Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ARM64 Docker image support #3810

Merged
merged 16 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .woodpecker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ steps:
settings:
repo: dessalines/lemmy
dockerfile: docker/Dockerfile
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
build_args:
- RUST_RELEASE_MODE=release
auto_tag: true
Expand All @@ -252,7 +252,7 @@ steps:
settings:
repo: dessalines/lemmy
dockerfile: docker/Dockerfile
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
build_args:
- RUST_RELEASE_MODE=release
tag: dev
Expand Down
142 changes: 111 additions & 31 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,45 +1,125 @@
FROM clux/muslrust:1.70.0 as builder
WORKDIR /app
ARG CARGO_BUILD_TARGET=x86_64-unknown-linux-musl
#
# Docker multiarch image:
# We build the Lemmy binary for amd64 and arm64 in individual stages using the blackdex/rust-musl image (github.com/blackdex/rust-musl).
# This image uses musl-cross-make (github.com/richfelker/musl-cross-make) to build a musl cross compilation toolchain for the target
# architecture. It also includes pre-built static libraries such as libpq. These libraries can improve the compile time and eliminate
# the requirement for extra dependencies in the final image.
#
# During each build stage, we use the blackdex/rust-musl openssl 3 images and configure PQ_LIB_DIR=/usr/local/musl/pq15/lib to use
# libpq v15. We also ensure the installation of the Rust toolchain corresponding to the target architecture using:
# `rustup target add $TARGET-unknown-linux-musl`.
#

# comma-seperated list of features to enable
ARG RUST_VERSION=1.71.0
ARG ALPINE_VERSION=3.18
ARG CARGO_BUILD_FEATURES=default
ARG RUST_RELEASE_MODE=debug
ARG UID=911
ARG GID=911

TheSilkky marked this conversation as resolved.
Show resolved Hide resolved
# This can be set to release using --build-arg
ARG RUST_RELEASE_MODE="debug"
# AMD64 builder base
FROM --platform=${BUILDPLATFORM} blackdex/rust-musl:x86_64-musl-stable-${RUST_VERSION}-openssl3 AS base-amd64

COPY . .
ENV DEBIAN_FRONTEND=noninteractive
ENV CARGO_HOME=/root/.cargo
ENV PQ_LIB_DIR=/usr/local/musl/pq15/lib

# Build the project

# Debug mode build
RUN --mount=type=cache,target=/app/target \
if [ "$RUST_RELEASE_MODE" = "debug" ] ; then \
echo "pub const VERSION: &str = \"$(git describe --tag)\";" > "crates/utils/src/version.rs" \
&& cargo build --target ${CARGO_BUILD_TARGET} --features ${CARGO_BUILD_FEATURES} \
&& cp ./target/$CARGO_BUILD_TARGET/$RUST_RELEASE_MODE/lemmy_server /app/lemmy_server; \
RUN apt update && apt install -y \
--no-install-recommends \
git

RUN mkdir -pv "${CARGO_HOME}" && \
rustup set profile minimal && \
rustup target add x86_64-unknown-linux-musl

# ARM64 builder base
FROM --platform=${BUILDPLATFORM} blackdex/rust-musl:aarch64-musl-stable-${RUST_VERSION}-openssl3 AS base-arm64

ENV DEBIAN_FRONTEND=noninteractive
ENV CARGO_HOME=/root/.cargo
ENV PQ_LIB_DIR=/usr/local/musl/pq15/lib

RUN apt update && apt install -y \
--no-install-recommends \
git

RUN mkdir -pv "${CARGO_HOME}" && \
rustup set profile minimal && \
rustup target add aarch64-unknown-linux-musl

# AMD64 builder
FROM base-amd64 AS build-amd64

ARG CARGO_BUILD_FEATURES
ARG RUST_RELEASE_MODE

WORKDIR /lemmy

COPY . ./

# Debug build
RUN --mount=type=cache,target=/lemmy/target set -ex; \
if [ "${RUST_RELEASE_MODE}" = "debug" ]; then \
echo "pub const VERSION: &str = \"$(git describe --tag)\";" > crates/utils/src/version.rs; \
cargo build --target=x86_64-unknown-linux-musl --features "${CARGO_BUILD_FEATURES}"; \
mv target/x86_64-unknown-linux-musl/debug/lemmy_server ./lemmy; \
fi

# Release mode build
RUN \
if [ "$RUST_RELEASE_MODE" = "release" ] ; then \
echo "pub const VERSION: &str = \"$(git describe --tag)\";" > "crates/utils/src/version.rs" \
&& cargo build --target ${CARGO_BUILD_TARGET} --features ${CARGO_BUILD_FEATURES} --release \
&& cp ./target/$CARGO_BUILD_TARGET/$RUST_RELEASE_MODE/lemmy_server /app/lemmy_server; \
# Release build
RUN set -ex; \
if [ "${RUST_RELEASE_MODE}" = "release" ]; then \
echo "pub const VERSION: &str = \"$(git describe --tag)\";" > crates/utils/src/version.rs; \
cargo build --target=x86_64-unknown-linux-musl --features "${CARGO_BUILD_FEATURES}" --release; \
mv target/x86_64-unknown-linux-musl/release/lemmy_server ./lemmy; \
fi

# The alpine runner
FROM alpine:3 as lemmy
# ARM64 builder
FROM base-arm64 AS build-arm64

ARG CARGO_BUILD_FEATURES
ARG RUST_RELEASE_MODE

# Install libpq for postgres
RUN apk add --no-cache libpq
WORKDIR /lemmy

# Copy resources
COPY --from=builder /app/lemmy_server /app/lemmy
COPY . ./

# Debug build
RUN --mount=type=cache,target=/lemmy/target set -ex; \
if [ "${RUST_RELEASE_MODE}" = "debug" ]; then \
echo "pub const VERSION: &str = \"$(git describe --tag)\";" > crates/utils/src/version.rs; \
cargo build --target=aarch64-unknown-linux-musl --features "${CARGO_BUILD_FEATURES}"; \
mv target/aarch64-unknown-linux-musl/debug/lemmy_server ./lemmy; \
fi

# Release build
RUN set -ex; \
if [ "${RUST_RELEASE_MODE}" = "release" ]; then \
echo "pub const VERSION: &str = \"$(git describe --tag)\";" > crates/utils/src/version.rs; \
cargo build --target=aarch64-unknown-linux-musl --features "${CARGO_BUILD_FEATURES}" --release; \
mv target/aarch64-unknown-linux-musl/release/lemmy_server ./lemmy; \
fi

# Get target binary
FROM build-${TARGETARCH} AS build

## Final image
FROM alpine:${ALPINE_VERSION}

ARG UID
ARG GID

RUN apk add --no-cache \
ca-certificates

COPY --from=build --chmod=0755 /lemmy/lemmy /usr/local/bin

RUN addgroup -S -g ${GID} lemmy && \
adduser -S -H -D -G lemmy -u ${UID} -g "" -s /sbin/nologin lemmy

# Create non-privileged user
RUN adduser -h /app -s sh -S -u 1000 lemmy
RUN chown -R lemmy /app
USER lemmy

CMD ["/app/lemmy"]
CMD ["lemmy"]

EXPOSE 8536

STOPSIGNAL SIGTERM