Skip to content

Commit 42a6646

Browse files
committed
Build dateilager within the dockerfile using the nix environment
This switches the build process to: - build DL within the dockerfile for repeatable builds, instead of copying in from outside - use the nix environment to setup the env for the build, so it's the same go version / protoc version etc etc in and outside of docker - use a multistage docker build so we have slim containers with just the binary at the end I did all this because I was fighting to get a docker image built for linux_arm64, which is what orbstack needs to run the image locally in a k8s setup! It was annoying. This also adds linux_arm64 as a build target to the makefile, and teaches the dockerfile how to build the binary for the target architecture that the dockerfile is building for. Yeesh.
1 parent cc8f6bb commit 42a6646

File tree

8 files changed

+77
-41
lines changed

8 files changed

+77
-41
lines changed

.dockerignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.git
2+
.direnv
3+
Dockerfile
4+
js
5+
test
6+
tmp
7+
bin
8+
input
9+
node_modules

.github/actions/setup-env/action.yml

+1-5
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,4 @@ runs:
4646

4747
- name: Add Go binaries to PATH
4848
run: echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
49-
shell: bash -l {0}
50-
51-
- name: Install Go binaries
52-
run: make install
53-
shell: bash -l {0}
49+
shell: bash -l {0}

Dockerfile

+26-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,30 @@
1-
FROM --platform=linux/amd64 registry.fedoraproject.org/fedora-minimal:40
1+
FROM nixos/nix:2.22.0 AS build-stage
2+
ARG TARGETARCH
23

3-
RUN microdnf install -y curl findutils gzip iputils less postgresql procps shadow-utils tar time which \
4-
&& microdnf clean all
4+
RUN echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf
5+
WORKDIR /app
6+
7+
COPY flake.nix flake.lock ./
8+
COPY development ./development
9+
10+
# build the nix environment once as an early docker layer
11+
RUN nix develop -c true
12+
13+
# copy the go modules and download em
14+
COPY go.mod go.sum ./
15+
RUN nix develop -c go mod download
16+
17+
# copy everything else and build the project
18+
COPY . ./
19+
RUN nix develop -c make release/server_linux_$TARGETARCH
20+
21+
FROM buildpack-deps:bullseye AS build-release-stage
22+
ARG TARGETARCH
523

624
RUN GRPC_HEALTH_PROBE_VERSION=v0.4.23 \
7-
&& curl -Lfso /bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 \
25+
&& curl -Lfso /bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-${TARGETARCH} \
826
&& chmod +x /bin/grpc_health_probe
927

10-
RUN GO_MIGRATE_VERSION=v4.16.2 \
11-
&& curl -Lfso /tmp/migrate.tar.gz https://github.com/golang-migrate/migrate/releases/download/${GO_MIGRATE_VERSION}/migrate.linux-amd64.tar.gz \
12-
&& tar -xzf /tmp/migrate.tar.gz -C /bin \
13-
&& chmod +x /bin/migrate
14-
1528
RUN useradd -ms /bin/bash main
1629
USER main
1730
WORKDIR /home/main
@@ -20,8 +33,11 @@ RUN mkdir -p /home/main/secrets
2033
VOLUME /home/main/secrets/tls
2134
VOLUME /home/main/secrets/paseto
2235

23-
COPY release/server_linux_amd64 server
36+
COPY --from=build-stage /app/release/server_linux_${TARGETARCH} server
2437
COPY migrations migrations
2538
COPY entrypoint.sh entrypoint.sh
2639

40+
# smoke test -- ensure the server command can run
41+
RUN ./server --help
42+
2743
ENTRYPOINT ["./entrypoint.sh"]

Makefile

+10-13
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,14 @@ PROTO_FILES := $(shell find internal/pb/ -type f -name '*.proto')
2121
MIGRATE_DIR := ./migrations
2222
SERVICE := $(PROJECT).server
2323

24-
.PHONY: install migrate migrate-create clean build lint release
24+
.PHONY: migrate migrate-create clean build lint release
2525
.PHONY: test test-one test-fuzz test-js lint-js build-js
2626
.PHONY: reset-db setup-local server server-profile install-js
2727
.PHONY: client-update client-large-update client-get client-rebuild client-rebuild-with-cache
2828
.PHONY: client-getcache client-gc-contents client-gc-project client-gc-random-projects
2929
.PHONY: health upload-container-image run-container gen-docs
3030
.PHONY: load-test-new load-test-get load-test-update
3131

32-
install:
33-
go install google.golang.org/protobuf/cmd/[email protected]
34-
go install google.golang.org/grpc/cmd/[email protected]
35-
go install github.com/grpc-ecosystem/[email protected]
36-
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/[email protected]
37-
go install github.com/bojand/ghz/cmd/[email protected]
38-
go install github.com/gadget-inc/fsdiff/cmd/[email protected]
39-
go install github.com/stamblerre/gocode@latest
40-
go install golang.org/x/tools/cmd/goimports@latest
41-
4232
migrate:
4333
migrate -database $(DB_URI)?sslmode=disable -path $(MIGRATE_DIR) up
4434

@@ -78,9 +68,14 @@ build: internal/pb/fs.pb.go internal/pb/fs_grpc.pb.go bin/server bin/client deve
7868
lint:
7969
golangci-lint run
8070

71+
72+
8173
release/%_linux_amd64: cmd/%/main.go $(PKG_GO_FILES) $(INTERNAL_GO_FILES) go.sum
8274
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build $(BUILD_FLAGS) -o $@ $<
8375

76+
release/%_linux_arm64: cmd/%/main.go $(PKG_GO_FILES) $(INTERNAL_GO_FILES) go.sum
77+
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build $(BUILD_FLAGS) -o $@ $<
78+
8479
release/%_macos_amd64: cmd/%/main.go $(PKG_GO_FILES) $(INTERNAL_GO_FILES) go.sum
8580
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build $(BUILD_FLAGS) -o $@ $<
8681

@@ -193,7 +188,7 @@ health:
193188
grpc-health-probe -addr $(GRPC_SERVER)
194189
grpc-health-probe -addr $(GRPC_SERVER) -service $(SERVICE)
195190

196-
upload-container-image: release
191+
upload-container-image:
197192
ifndef version
198193
$(error version variable must be set)
199194
else
@@ -206,8 +201,10 @@ upload-prerelease-container-image: release
206201
docker build -t gcr.io/gadget-core-production/dateilager:$(GIT_COMMIT) .
207202
docker push gcr.io/gadget-core-production/dateilager:$(GIT_COMMIT)
208203

209-
run-container: release
204+
build-local-container:
210205
docker build -t dl-local:latest .
206+
207+
run-container: release build-local-container
211208
docker run --rm -it -p 127.0.0.1:$(GRPC_PORT):$(GRPC_PORT)/tcp -v ./development:/home/main/secrets/tls -v ./development:/home/main/secrets/paseto dl-local:latest $(GRPC_PORT) "postgres://$(DB_USER):$(DB_PASS)@host.docker.internal:5432" dl
212209

213210
gen-docs:

Readme.md

+5-9
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
Dateilager is a content-addressed, networked filesystem for keeping large, similar directories among a wide variety of hosts. It has a few key properties:
44

5-
- file contents and versions are stored in by a central server, with readers and writers as clients
6-
- files and trees of files are stored only once in a content-addressed store by the server for efficiency, but are still served securely to only clients with access
7-
- readers and writers keep a copy of the filesystem synced locally for very fast local access (and trade off consistency or atomicity)
8-
- incremental updates by readers are O(changes) and optimized to be very fast
9-
- one Dateilager server supports storing many different independent filesystems with secured access to each (multi-tenancy)
5+
- file contents and versions are stored in by a central server, with readers and writers as clients
6+
- files and trees of files are stored only once in a content-addressed store by the server for efficiency, but are still served securely to only clients with access
7+
- readers and writers keep a copy of the filesystem synced locally for very fast local access (and trade off consistency or atomicity)
8+
- incremental updates by readers are O(changes) and optimized to be very fast
9+
- one Dateilager server supports storing many different independent filesystems with secured access to each (multi-tenancy)
1010

1111
Dateilager is used in production to power https://gadget.dev to sync the filesystems for all the apps on the Gadget platform. Dateilager shines at syncing the (often very large) `node_modules` folder shared between the many node.js applications, as well as the comparatively small `.js` files comprising the actual business logic of one particular app.
1212

@@ -37,10 +37,6 @@ Ensure that you have a working [Go development environment](https://golang.org/d
3737

3838
You will also require `npm`.
3939

40-
```bash
41-
$ make install
42-
```
43-
4440
### Setup VSCode (Optional)
4541

4642
We recommend using VSCode for development, and there's an example settings file at `.vscode/settings.example.json` to get started with:

flake.nix

+23-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"x86_64-linux"
1212
"x86_64-darwin"
1313
"aarch64-darwin"
14+
"aarch64-linux"
1415
]
1516
(system: nixpkgs.lib.fix (flake:
1617
let
@@ -36,7 +37,7 @@
3637
callPackage = pkgs.newScope (flake.packages // { inherit lib callPackage; });
3738
in
3839
{
39-
packages = {
40+
packages = {
4041
## DateiLager development scripts
4142

4243
clean = callPackage ./development/nix/scripts/clean.nix { };
@@ -63,6 +64,27 @@
6364
};
6465

6566
defaultPackage = flake.packages.dateilager;
67+
68+
devShell = pkgs.mkShell {
69+
buildInputs = with pkgs; [
70+
flake.packages.go
71+
flake.packages.nodejs
72+
flake.packages.postgresql
73+
flake.packages.dev
74+
flake.packages.clean
75+
git
76+
protobuf
77+
protoc-gen-go
78+
protoc-gen-go-grpc
79+
go-migrate
80+
mkcert
81+
];
82+
83+
shellHook = ''
84+
# prepend the built binaries to the $PATH
85+
export PATH="./bin":$PATH
86+
'';
87+
};
6688
}
6789
)));
6890
}

internal/pb/fs.pb.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/pb/fs_grpc.pb.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)