chore: switch to multiarch Docker image
							parent
							
								
									1cca0d46de
								
							
						
					
					
						commit
						5b6782df13
					
				
							
								
								
									
										85
									
								
								Dockerfile
								
								
								
								
							
							
						
						
									
										85
									
								
								Dockerfile
								
								
								
								
							|  | @ -1,31 +1,88 @@ | |||
| FROM rust:1.83-alpine3.21 AS builder | ||||
| # This Dockerfile supports building multi-platform Rust applications for | ||||
| # linux/amd64 and linux/arm64. It was largely inspired by the article linked | ||||
| # below, with the difference being that it more closely follows Docker's | ||||
| # caching system. In theory, it can support any architecture that Docker and | ||||
| # Rust both support. | ||||
| # | ||||
| # All RUN directives that require the specific target platform modify the | ||||
| # TARGETPLATFORM argument using a sed command. This is required because Rust | ||||
| # and Docker use different names for referring to the same architecture.  | ||||
| #  | ||||
| # https://dev.to/vladkens/fast-multi-arch-docker-build-for-rust-projects-an1 | ||||
| 
 | ||||
| ARG DI_VER=1.2.5 | ||||
| # We first create a base image that installs Zig (for zig cc) and Cargo Chef | ||||
| # (for better dependency caching). This image is shared between all | ||||
| # architectures. | ||||
| FROM --platform=$BUILDPLATFORM rust:1.88-alpine3.21 AS chef | ||||
| 
 | ||||
| WORKDIR /app | ||||
| 
 | ||||
| RUN apk update && apk add --no-cache build-base | ||||
| RUN apk update && \ | ||||
|     apk add --no-cache build-base musl-dev openssl-dev zig && \ | ||||
|     cargo install --locked cargo-zigbuild cargo-chef | ||||
| 
 | ||||
| # Build dumb-init | ||||
| RUN wget -O - "https://github.com/Yelp/dumb-init/archive/refs/tags/v${DI_VER}.tar.gz" | tar -xzf - && \ | ||||
| 
 | ||||
| # The planner generates the Chef recipe.json file that allows the builder steps | ||||
| # to efficiently cache dependency builds, greatly speeding up builds if | ||||
| # dependencies haven't changed. This image is also shared between all | ||||
| # dependencies. | ||||
| FROM chef AS planner | ||||
| 
 | ||||
| COPY . . | ||||
| 
 | ||||
| RUN cargo chef prepare --recipe-path recipe.json | ||||
| 
 | ||||
| 
 | ||||
| # The builder container is responsible for performing the actual build. It | ||||
| # installs its respective Rust toolchain and builds dumb-init for the target | ||||
| # platform. Then it uses the generated Chef recipe file to build the | ||||
| # dependencies, before using zigbuild to build the actual final binary. | ||||
| FROM chef AS builder | ||||
| 
 | ||||
| ARG DI_VER=1.2.5 | ||||
| ARG TARGETPLATFORM | ||||
| 
 | ||||
| RUN export ARCH="$(echo "${TARGETPLATFORM}" | sed 's:linux/amd64:x86_64:;s:linux/arm64:aarch64:')" && \ | ||||
|     rustup target add "$ARCH-unknown-linux-musl" && \ | ||||
|     wget -O - "https://github.com/Yelp/dumb-init/archive/refs/tags/v${DI_VER}.tar.gz" | tar -xzf - && \ | ||||
|     cd "dumb-init-${DI_VER}" && \ | ||||
|     make SHELL=/bin/sh && \ | ||||
|     mv dumb-init .. && \ | ||||
|     make CC="zig cc -target $ARCH-linux-musl" SHELL=/bin/sh && \ | ||||
|     mkdir -p "/app/${TARGETPLATFORM}" && \ | ||||
|     mv dumb-init "/app/${TARGETPLATFORM}/dumb-init" && \ | ||||
|     cd .. | ||||
| 
 | ||||
| COPY Cargo.toml Cargo.lock ./ | ||||
| # Using Chef, we can build the dependencies separately from the application | ||||
| # itself. This allows dependency builds to be cached, greatly speeding up | ||||
| # builds when dependencies haven't changed. Zigbuild is used to support | ||||
| # building C-based dependencies, such as libsqlite3. | ||||
| COPY --from=planner /app/recipe.json recipe.json | ||||
| 
 | ||||
| RUN cargo fetch --locked | ||||
| RUN export ARCH="$(echo "${TARGETPLATFORM}" | sed 's:linux/amd64:x86_64:;s:linux/arm64:aarch64:')" && \ | ||||
|     cargo chef cook \ | ||||
|     --recipe-path recipe.json \ | ||||
|     --release --zigbuild \ | ||||
|     --target "$ARCH-unknown-linux-musl" | ||||
| 
 | ||||
| COPY . ./ | ||||
| # Finally we copy the application source code and build the application binary, | ||||
| # using the cached dependency build. | ||||
| COPY . . | ||||
| 
 | ||||
| RUN cargo build --release --frozen | ||||
| RUN export ARCH="$(echo "${TARGETPLATFORM}" | sed 's:linux/amd64:x86_64:;s:linux/arm64:aarch64:')" && \ | ||||
|     cargo zigbuild \ | ||||
|         --release \ | ||||
|         --target "$ARCH-unknown-linux-musl" && \ | ||||
|     cp target/"$ARCH-unknown-linux-musl"/release/site "/app/${TARGETPLATFORM}/site" | ||||
| 
 | ||||
| 
 | ||||
| # We generate the final Alpine-based image by copying the built binaries from | ||||
| # the respective target platform's builder container. This is the only part of | ||||
| # the build that runs inside an emulator. | ||||
| FROM alpine:3.21 | ||||
| 
 | ||||
| COPY --from=builder /app/target/release/site /bin/site | ||||
| COPY --from=builder /app/dumb-init /bin/dumb-init | ||||
| ARG TARGETPLATFORM | ||||
| 
 | ||||
| COPY --from=builder /app/${TARGETPLATFORM}/dumb-init /bin/dumb-init | ||||
| COPY --from=builder /app/${TARGETPLATFORM}/site /bin/site | ||||
| 
 | ||||
| # Create a non-root user & make sure it can write to the data directory | ||||
| RUN set -x && \ | ||||
|  | @ -41,5 +98,3 @@ USER www-data:www-data | |||
| 
 | ||||
| ENTRYPOINT [ "/bin/dumb-init", "--" ] | ||||
| CMD [ "/bin/site" ] | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue