Skip to content

Commit f0fc487

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 f0fc487

File tree

8 files changed

+102
-47
lines changed

8 files changed

+102
-47
lines changed

.dockerignore

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.git
2+
.direnv
3+
.vscode
4+
Dockerfile
5+
js
6+
test
7+
tmp
8+
bin
9+
release
10+
docs
11+
input
12+
node_modules
13+
development
14+
!development/nix

.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

+41-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,45 @@
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 tee -a /etc/nix/nix.conf <<EOF
5+
experimental-features = nix-command flakes
6+
filter-syscalls = false
7+
EOF
8+
9+
WORKDIR /app
10+
11+
COPY flake.nix flake.lock ./
12+
COPY development ./development
13+
14+
# Setup the nix environment in an early layer
15+
RUN nix develop --command "true"
16+
17+
# Create a custom shell script that activates nix develop for any RUN command
18+
RUN echo '#!/usr/bin/env bash' > /bin/nix-env-shell \
19+
&& echo 'exec nix develop --command bash -c "$@"' >> /bin/nix-env-shell \
20+
&& chmod +x /bin/nix-env-shell
21+
22+
SHELL ["/bin/nix-env-shell"]
23+
24+
# copy the go modules and download em
25+
COPY go.mod go.sum ./
26+
RUN go mod download
27+
28+
# copy everything else and build the project
29+
COPY . ./
30+
RUN make release/server_linux_$TARGETARCH
31+
32+
FROM buildpack-deps:bullseye AS build-release-stage
33+
ARG TARGETARCH
34+
35+
RUN apt-get update && \
36+
apt-get install -y curl findutils gzip net-tools less postgresql procps tar time && \
37+
rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
538

639
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 \
40+
&& 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} \
841
&& chmod +x /bin/grpc_health_probe
942

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-
1543
RUN useradd -ms /bin/bash main
1644
USER main
1745
WORKDIR /home/main
@@ -20,8 +48,11 @@ RUN mkdir -p /home/main/secrets
2048
VOLUME /home/main/secrets/tls
2149
VOLUME /home/main/secrets/paseto
2250

23-
COPY release/server_linux_amd64 server
51+
COPY --from=build-stage /app/release/server_linux_${TARGETARCH} server
2452
COPY migrations migrations
2553
COPY entrypoint.sh entrypoint.sh
2654

55+
# smoke test -- ensure the server command can run
56+
RUN ./server --help
57+
2758
ENTRYPOINT ["./entrypoint.sh"]

Makefile

+15-19
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,22 +188,23 @@ 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
200-
docker build -t gcr.io/gadget-core-production/dateilager:$(version) -t gcr.io/gadget-core-production/dateilager:latest .
195+
docker build --platform linux/amd64 -t gcr.io/gadget-core-production/dateilager:$(version) -t gcr.io/gadget-core-production/dateilager:latest .
201196
docker push gcr.io/gadget-core-production/dateilager:$(version)
202197
docker push gcr.io/gadget-core-production/dateilager:latest
203198
endif
204199

205-
upload-prerelease-container-image: release
206-
docker build -t gcr.io/gadget-core-production/dateilager:$(GIT_COMMIT) .
207-
docker push gcr.io/gadget-core-production/dateilager:$(GIT_COMMIT)
200+
upload-prerelease-container-image:
201+
docker build --platform linux/arm64,linux/amd64 --push -t us-central1-docker.pkg.dev/gadget-core-production/core-production/dateilager:pre-$(GIT_COMMIT) .
202+
203+
build-local-container:
204+
docker build --load -t dl-local:dev .
208205

209-
run-container: release
210-
docker build -t dl-local:latest .
211-
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
206+
run-container: release build-local-container
207+
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:dev $(GRPC_PORT) "postgres://$(DB_USER):$(DB_PASS)@host.docker.internal:5432" dl
212208

213209
gen-docs:
214210
go run cmd/gen-docs/main.go

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)