diff --git a/docker/Dockerfile.j2 b/docker/Dockerfile.j2 index af222ad5..07415a05 100644 --- a/docker/Dockerfile.j2 +++ b/docker/Dockerfile.j2 @@ -3,9 +3,15 @@ {% set build_stage_base_image = "rust:1.45" %} {% if "alpine" in target_file %} -{% set build_stage_base_image = "clux/muslrust:nightly-2020-07-09" %} -{% set runtime_stage_base_image = "alpine:3.12" %} -{% set package_arch_name = "" %} +{% if "amd64" in target_file %} +{% set build_stage_base_image = "clux/muslrust:nightly-2020-07-09" %} +{% set runtime_stage_base_image = "alpine:3.12" %} +{% set package_arch_name = "" %} +{% elif "arm32v7" in target_file %} +{% set build_stage_base_image = "messense/rust-musl-cross:armv7-musleabihf" %} +{% set runtime_stage_base_image = "cmosh/alpine-arm:3.6" %} +{% set package_arch_name = "" %} +{% endif %} {% elif "amd64" in target_file %} {% set runtime_stage_base_image = "debian:buster-slim" %} {% set package_arch_name = "" %} @@ -101,7 +107,7 @@ RUN apt-get update \ ENV CARGO_HOME "/root/.cargo" ENV USER "root" -{% elif "arm32v7" in target_file %} +{% elif "arm32v7" in target_file and "alpine" not in target_file %} RUN apt-get update \ && apt-get install -y \ --no-install-recommends \ @@ -131,36 +137,41 @@ COPY ./Cargo.* ./ COPY ./rust-toolchain ./rust-toolchain COPY ./build.rs ./build.rs -{% if "arm64v8" in target_file %} +{% if "alpine" not in target_file %} +{% if "arm64v8" in target_file %} ENV CC_aarch64_unknown_linux_gnu="/usr/bin/aarch64-linux-gnu-gcc" ENV CROSS_COMPILE="1" ENV OPENSSL_INCLUDE_DIR="/usr/include/aarch64-linux-gnu" ENV OPENSSL_LIB_DIR="/usr/lib/aarch64-linux-gnu" -{% elif "arm32v6" in target_file %} +{% elif "arm32v6" in target_file %} ENV CC_arm_unknown_linux_gnueabi="/usr/bin/arm-linux-gnueabi-gcc" ENV CROSS_COMPILE="1" ENV OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabi" ENV OPENSSL_LIB_DIR="/usr/lib/arm-linux-gnueabi" -{% elif "arm32v7" in target_file %} +{% elif "arm32v7" in target_file %} ENV CC_armv7_unknown_linux_gnueabihf="/usr/bin/arm-linux-gnueabihf-gcc" ENV CROSS_COMPILE="1" ENV OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabihf" ENV OPENSSL_LIB_DIR="/usr/lib/arm-linux-gnueabihf" +{% endif -%} {% endif -%} {% if "alpine" in target_file %} +{% if "amd64" in target_file %} RUN rustup target add x86_64-unknown-linux-musl - -{% elif "arm64v8" in target_file %} +{% elif "arm32v7" in target_file %} +RUN rustup target add armv7-unknown-linux-musleabihf +{% endif %} +{% elif "alpine" not in target_file %} +{% if "arm64v8" in target_file %} RUN rustup target add aarch64-unknown-linux-gnu - -{% elif "arm32v6" in target_file %} +{% elif "arm32v6" in target_file %} RUN rustup target add arm-unknown-linux-gnueabi - -{% elif "arm32v7" in target_file %} +{% elif "arm32v7" in target_file %} RUN rustup target add armv7-unknown-linux-gnueabihf - +{% endif %} {% endif %} + # Builds your dependencies and removes the # dummy project, except the target folder # This folder contains the compiled dependencies @@ -176,14 +187,23 @@ RUN touch src/main.rs # Builds again, this time it'll just be # your actual source files being built -{% if "amd64" in target_file %} +{% if "alpine" in target_file %} +{% if "amd64" in target_file %} +RUN cargo build --features ${DB} --release --target=x86_64-unknown-linux-musl +{% elif "arm32v7" in target_file %} +RUN cargo build --features ${DB} --release --target=armv7-unknown-linux-musleabihf +RUN musl-strip target/armv7-unknown-linux-musleabihf/release/bitwarden_rs +{% endif %} +{% elif "alpine" not in target_file %} +{% if "amd64" in target_file %} RUN cargo build --features ${DB} --release -{% elif "arm64v8" in target_file %} +{% elif "arm64v8" in target_file %} RUN cargo build --features ${DB} --release --target=aarch64-unknown-linux-gnu -{% elif "arm32v6" in target_file %} +{% elif "arm32v6" in target_file %} RUN cargo build --features ${DB} --release --target=arm-unknown-linux-gnueabi -{% elif "arm32v7" in target_file %} +{% elif "arm32v7" in target_file %} RUN cargo build --features ${DB} --release --target=armv7-unknown-linux-gnueabihf +{% endif %} {% endif %} ######################## RUNTIME IMAGE ######################## @@ -228,6 +248,9 @@ RUN apt-get update && apt-get install -y \ {% endif %} && rm -rf /var/lib/apt/lists/* {% endif %} +{% if "alpine" in target_file and "arm32v7" in target_file %} +RUN apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing catatonit +{% endif %} RUN mkdir /data {% if "amd64" not in target_file %} @@ -244,15 +267,21 @@ EXPOSE 3012 COPY Rocket.toml . COPY --from=vault /web-vault ./web-vault {% if "alpine" in target_file %} +{% if "amd64" in target_file %} COPY --from=build /app/target/x86_64-unknown-linux-musl/release/bitwarden_rs . -{% elif "arm64v8" in target_file %} +{% elif "arm32v7" in target_file %} +COPY --from=build /app/target/armv7-unknown-linux-musleabihf/release/bitwarden_rs . +{% endif %} +{% elif "alpine" not in target_file %} +{% if "arm64v8" in target_file %} COPY --from=build /app/target/aarch64-unknown-linux-gnu/release/bitwarden_rs . -{% elif "arm32v6" in target_file %} +{% elif "arm32v6" in target_file %} COPY --from=build /app/target/arm-unknown-linux-gnueabi/release/bitwarden_rs . -{% elif "arm32v7" in target_file %} +{% elif "arm32v7" in target_file %} COPY --from=build /app/target/armv7-unknown-linux-gnueabihf/release/bitwarden_rs . -{% else %} +{% else %} COPY --from=build app/target/release/bitwarden_rs . +{% endif %} {% endif %} COPY docker/healthcheck.sh /healthcheck.sh @@ -262,4 +291,8 @@ HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] # Configures the startup! WORKDIR / +{% if "alpine" in target_file and "arm32v7" in target_file %} +CMD ["catatonit", "/start.sh"] +{% else %} CMD ["/start.sh"] +{% endif %} diff --git a/docker/arm32v7/Dockerfile.alpine b/docker/arm32v7/Dockerfile.alpine new file mode 100644 index 00000000..fa4f3ab5 --- /dev/null +++ b/docker/arm32v7/Dockerfile.alpine @@ -0,0 +1,106 @@ +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfile's. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### + +# This hash is extracted from the docker web-vault builds and it's prefered over a simple tag because it's immutable. +# It can be viewed in multiple ways: +# - From the https://hub.docker.com/repository/docker/bitwardenrs/web-vault/tags page, click the tag name and the digest should be there. +# - From the console, with the following commands: +# docker pull bitwardenrs/web-vault:v2.16.0b +# docker image inspect --format "{{.RepoDigests}}" bitwardenrs/web-vault:v2.16.0b +# +# - To do the opposite, and get the tag from the hash, you can do: +# docker image inspect --format "{{.RepoTags}}" bitwardenrs/web-vault@sha256:a6705a4d7776500a6544afd141de1786e6b87c386b068be996294960779cb5bf +FROM bitwardenrs/web-vault@sha256:a6705a4d7776500a6544afd141de1786e6b87c386b068be996294960779cb5bf as vault + +########################## BUILD IMAGE ########################## +FROM messense/rust-musl-cross:armv7-musleabihf as build + +# Alpine only works on SQlite +ARG DB=sqlite + +# Build time options to avoid dpkg warnings and help with reproducible builds. +ENV DEBIAN_FRONTEND=noninteractive LANG=C.UTF-8 TZ=UTC TERM=xterm-256color + +# Don't download rust docs +RUN rustup set profile minimal + +ENV USER "root" +ENV RUSTFLAGS='-C link-arg=-s' + + +# Creates a dummy project used to grab dependencies +RUN USER=root cargo new --bin /app +WORKDIR /app + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./ +COPY ./rust-toolchain ./rust-toolchain +COPY ./build.rs ./build.rs + +RUN rustup target add armv7-unknown-linux-musleabihf + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +RUN cargo build --features ${DB} --release +RUN find . -not -path "./target*" -delete + +# Copies the complete project +# To avoid copying unneeded files, use .dockerignore +COPY . . + +# Make sure that we actually build the project +RUN touch src/main.rs + +# Builds again, this time it'll just be +# your actual source files being built +RUN cargo build --features ${DB} --release --target=armv7-unknown-linux-musleabihf +RUN musl-strip target/armv7-unknown-linux-musleabihf/release/bitwarden_rs + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM cmosh/alpine-arm + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 +ENV SSL_CERT_DIR=/etc/ssl/certs + +RUN [ "cross-build-start" ] + +# Install needed libraries +RUN apk add --no-cache \ + openssl \ + curl \ + ca-certificates +RUN apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing catatonit + +RUN mkdir /data + +RUN [ "cross-build-end" ] + +VOLUME /data +EXPOSE 80 +EXPOSE 3012 + +# Copies the files from the context (Rocket.toml file and web-vault) +# and the binary from the "build" stage to the current stage +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/armv7-unknown-linux-musleabihf/release/bitwarden_rs . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +WORKDIR / +CMD ["catatonit", "/start.sh"] + diff --git a/hooks/arches.sh b/hooks/arches.sh index 14c53e23..7bd52c49 100644 --- a/hooks/arches.sh +++ b/hooks/arches.sh @@ -21,5 +21,8 @@ esac if [[ "${DOCKER_TAG}" == *alpine ]]; then # The Alpine build currently only works for amd64. os_suffix=.alpine - arches=(amd64) + arches=( + amd64 + arm32v7 + ) fi