diff options
author | BlackDex <[email protected]> | 2021-09-13 12:00:52 +0200 |
---|---|---|
committer | BlackDex <[email protected]> | 2021-09-13 14:42:15 +0200 |
commit | ca0fd7a31b724d06ba4eca203bfeda9e38c5e767 (patch) | |
tree | 8ec5302c6714fec7d5341554f3dcd25260e185fe /docker | |
parent | 9e1550af8e2fb247fa397b9af1d21f8a79f81c06 (diff) | |
download | vaultwarden-ca0fd7a31b724d06ba4eca203bfeda9e38c5e767.tar.gz vaultwarden-ca0fd7a31b724d06ba4eca203bfeda9e38c5e767.zip |
Optimize release workflow.
- Split Debian and Alpine into different build matrix
This starts building both Debian and Alpine based images at the same time
- Make use of Docker BuildKit, which improves speed also.
- Use BuildKit caching for Rust Cargo across docker images.
This prevents downloading the same crates multiple times.
- Use Github Actions Services to start a docker registry, starting it
via the build script sometimes caused issues.
- Updated the Build workflow to use Ubuntu 20.04 which is more close to
the Bullseye Debian release regarding package versions.
Diffstat (limited to 'docker')
-rw-r--r-- | docker/Dockerfile.j2 | 109 | ||||
-rw-r--r-- | docker/Makefile | 6 | ||||
-rw-r--r-- | docker/amd64/Dockerfile | 26 | ||||
-rw-r--r-- | docker/amd64/Dockerfile.alpine | 16 | ||||
-rw-r--r-- | docker/amd64/Dockerfile.buildx | 126 | ||||
-rw-r--r-- | docker/amd64/Dockerfile.buildx.alpine | 118 | ||||
-rw-r--r-- | docker/arm64/Dockerfile | 75 | ||||
-rw-r--r-- | docker/arm64/Dockerfile.buildx | 169 | ||||
-rw-r--r-- | docker/armv6/Dockerfile | 75 | ||||
-rw-r--r-- | docker/armv6/Dockerfile.buildx | 169 | ||||
-rw-r--r-- | docker/armv7/Dockerfile | 75 | ||||
-rw-r--r-- | docker/armv7/Dockerfile.alpine | 16 | ||||
-rw-r--r-- | docker/armv7/Dockerfile.buildx | 169 | ||||
-rw-r--r-- | docker/armv7/Dockerfile.buildx.alpine | 125 |
14 files changed, 1125 insertions, 149 deletions
diff --git a/docker/Dockerfile.j2 b/docker/Dockerfile.j2 index 1fc83996..2a849a5b 100644 --- a/docker/Dockerfile.j2 +++ b/docker/Dockerfile.j2 @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -40,6 +42,11 @@ {% else %} {% set package_arch_target_param = "" %} {% endif %} +{% if "buildx" in target_file %} +{% set mount_rust_cache = "--mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry " %} +{% else %} +{% set mount_rust_cache = "" %} +{% endif %} # Using multistage build: # https://docs.docker.com/develop/develop-images/multistage-build/ # https://whitfin.io/speeding-up-rust-docker-builds/ @@ -86,22 +93,39 @@ ARG DB=sqlite,mysql,postgresql {% endif %} # 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 +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" -# Don't download rust docs -RUN rustup set profile minimal +{# {% if "alpine" not in target_file and "buildx" in target_file %} +# Debian based Buildx builds can use some special apt caching to speedup building. +# By default Debian based images have some rules to keep docker builds clean, we need to remove this. +# See: https://hub.docker.com/r/docker/dockerfile +RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache +{% endif %} #} + +# Create CARGO_HOME folder and don't download rust docs +RUN {{ mount_rust_cache -}} mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal {% if "alpine" in target_file %} -ENV USER "root" ENV RUSTFLAGS='-C link-arg=-s' {% if "armv7" in target_file %} ENV CFLAGS_armv7_unknown_linux_musleabihf="-mfpu=vfpv3-d16" {% endif %} {% elif "arm" in target_file %} +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the {{ package_arch_prefix }} version. +# What we can do is a force install, because nothing important is overlapping each other. +# # Install required build libs for {{ package_arch_name }} architecture. # To compile both mysql and postgresql we need some extra packages for both host arch and target arch -RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ - /etc/apt/sources.list.d/deb-src.list \ +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ && dpkg --add-architecture {{ package_arch_name }} \ && apt-get update \ && apt-get install -y \ @@ -110,24 +134,43 @@ RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ libc6-dev{{ package_arch_prefix }} \ libpq5{{ package_arch_prefix }} \ libpq-dev \ + libmariadb3:amd64 \ libmariadb-dev{{ package_arch_prefix }} \ libmariadb-dev-compat{{ package_arch_prefix }} \ gcc-{{ package_cross_compiler }} \ - && mkdir -p ~/.cargo \ - && echo '[target.{{ package_arch_target }}]' >> ~/.cargo/config \ - && echo 'linker = "{{ package_cross_compiler }}-gcc"' >> ~/.cargo/config \ - && echo 'rustflags = ["-L/usr/lib/{{ package_cross_compiler }}"]' >> ~/.cargo/config + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) + && apt-get download libmariadb-dev-compat:amd64 \ + && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ + && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # + # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. + # The libpq5{{ package_arch_prefix }} package seems to not provide a symlink to libpq.so.5 with the name libpq.so. + # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. + # Without this specific file the ld command will fail and compilation fails with it. + && ln -sfnr /usr/lib/{{ package_cross_compiler }}/libpq.so.5 /usr/lib/{{ package_cross_compiler }}/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.{{ package_arch_target }}]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "{{ package_cross_compiler }}-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/{{ package_cross_compiler }}"]' >> "${CARGO_HOME}/config" -ENV CARGO_HOME "/root/.cargo" -ENV USER "root" -{% endif -%} +# Set arm specific environment values +ENV CC_{{ package_arch_target | replace("-", "_") }}="/usr/bin/{{ package_cross_compiler }}-gcc" +ENV CROSS_COMPILE="1" +ENV OPENSSL_INCLUDE_DIR="/usr/include/{{ package_cross_compiler }}" +ENV OPENSSL_LIB_DIR="/usr/lib/{{ package_cross_compiler }}" -{% if "amd64" in target_file and "alpine" not in target_file %} +{% elif "amd64" in target_file %} # Install DB packages -RUN apt-get update && apt-get install -y \ - --no-install-recommends \ - libmariadb-dev{{ package_arch_prefix }} \ - libpq-dev{{ package_arch_prefix }} \ +RUN apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libmariadb-dev{{ package_arch_prefix }} \ + libpq-dev{{ package_arch_prefix }} \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* {% endif %} @@ -140,37 +183,14 @@ COPY ./Cargo.* ./ COPY ./rust-toolchain ./rust-toolchain COPY ./build.rs ./build.rs -{% if "alpine" not in target_file %} -{% if "arm" in target_file %} -# NOTE: This should be the last apt-get/dpkg for this stage, since after this it will fail because of broken dependencies. -# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. -# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) -# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the {{ package_arch_prefix }} version. -# What we can do is a force install, because nothing important is overlapping each other. -RUN apt-get install -y --no-install-recommends libmariadb3:amd64 \ - && apt-get download libmariadb-dev-compat:amd64 \ - && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ - && rm -rvf ./libmariadb-dev-compat*.deb \ - # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. - # The libpq5{{ package_arch_prefix }} package seems to not provide a symlink to libpq.so.5 with the name libpq.so. - # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. - # Without this specific file the ld command will fail and compilation fails with it. - && ln -sfnr /usr/lib/{{ package_cross_compiler }}/libpq.so.5 /usr/lib/{{ package_cross_compiler }}/libpq.so - -ENV CC_{{ package_arch_target | replace("-", "_") }}="/usr/bin/{{ package_cross_compiler }}-gcc" -ENV CROSS_COMPILE="1" -ENV OPENSSL_INCLUDE_DIR="/usr/include/{{ package_cross_compiler }}" -ENV OPENSSL_LIB_DIR="/usr/lib/{{ package_cross_compiler }}" -{% endif -%} -{% endif %} {% if package_arch_target is defined %} -RUN rustup target add {{ package_arch_target }} +RUN {{ mount_rust_cache -}} rustup target add {{ package_arch_target }} {% endif %} # Builds your dependencies and removes the # dummy project, except the target folder # This folder contains the compiled dependencies -RUN cargo build --features ${DB} --release{{ package_arch_target_param }} \ +RUN {{ mount_rust_cache -}} cargo build --features ${DB} --release{{ package_arch_target_param }} \ && find . -not -path "./target*" -delete # Copies the complete project @@ -182,7 +202,7 @@ 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{{ package_arch_target_param }} +RUN {{ mount_rust_cache -}} cargo build --features ${DB} --release{{ package_arch_target_param }} {% if "alpine" in target_file %} {% if "armv7" in target_file %} # hadolint ignore=DL3059 @@ -231,6 +251,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* {% endif %} diff --git a/docker/Makefile b/docker/Makefile index 86b3b64c..8c939cba 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -7,3 +7,9 @@ all: $(OBJECTS) %/Dockerfile.alpine: Dockerfile.j2 render_template ./render_template "$<" "{\"target_file\":\"$@\"}" > "$@" + +%/Dockerfile.buildx: Dockerfile.j2 render_template + ./render_template "$<" "{\"target_file\":\"$@\"}" > "$@" + +%/Dockerfile.buildx.alpine: Dockerfile.j2 render_template + ./render_template "$<" "{\"target_file\":\"$@\"}" > "$@" diff --git a/docker/amd64/Dockerfile b/docker/amd64/Dockerfile index 8f448ccc..6769ef4f 100644 --- a/docker/amd64/Dockerfile +++ b/docker/amd64/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,16 +33,25 @@ FROM rust:1.54-bullseye as build ARG DB=sqlite,mysql,postgresql # 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 +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal # Install DB packages -RUN apt-get update && apt-get install -y \ - --no-install-recommends \ - libmariadb-dev \ - libpq-dev \ +RUN apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libmariadb-dev \ + libpq-dev \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Creates a dummy project used to grab dependencies @@ -90,6 +101,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/docker/amd64/Dockerfile.alpine b/docker/amd64/Dockerfile.alpine index 64963b99..9ac4dc38 100644 --- a/docker/amd64/Dockerfile.alpine +++ b/docker/amd64/Dockerfile.alpine @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,12 +33,18 @@ FROM clux/muslrust:nightly-2021-08-22 as build ARG DB=sqlite,postgresql # 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 +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal -ENV USER "root" ENV RUSTFLAGS='-C link-arg=-s' # Creates a dummy project used to grab dependencies diff --git a/docker/amd64/Dockerfile.buildx b/docker/amd64/Dockerfile.buildx new file mode 100644 index 00000000..a4aa826a --- /dev/null +++ b/docker/amd64/Dockerfile.buildx @@ -0,0 +1,126 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM rust:1.54-bullseye as build + +# Debian-based builds support multidb +ARG DB=sqlite,mysql,postgresql + +# 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 \ + CARGO_HOME="/root/.cargo" \ + USER="root" + + +# Create CARGO_HOME folder and don't download rust docs +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal + +# Install DB packages +RUN apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libmariadb-dev \ + libpq-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# 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 + + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release \ + && 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM debian:bullseye-slim + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 + + +# Create data folder and Install needed libraries +RUN mkdir /data \ + && apt-get update && apt-get install -y \ + --no-install-recommends \ + openssl \ + ca-certificates \ + curl \ + dumb-init \ + libmariadb-dev-compat \ + libpq5 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + + +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 +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/amd64/Dockerfile.buildx.alpine b/docker/amd64/Dockerfile.buildx.alpine new file mode 100644 index 00000000..ca666c1a --- /dev/null +++ b/docker/amd64/Dockerfile.buildx.alpine @@ -0,0 +1,118 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM clux/muslrust:nightly-2021-08-22 as build + +# Alpine-based AMD64 (musl) does not support mysql/mariadb during compile time. +ARG DB=sqlite,postgresql + +# 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 \ + CARGO_HOME="/root/.cargo" \ + USER="root" + + +# Create CARGO_HOME folder and don't download rust docs +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal + +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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry rustup target add x86_64-unknown-linux-musl + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=x86_64-unknown-linux-musl \ + && 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=x86_64-unknown-linux-musl + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM alpine:3.14 + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 +ENV SSL_CERT_DIR=/etc/ssl/certs + + +# Create data folder and Install needed libraries +RUN mkdir /data \ + && apk add --no-cache \ + openssl \ + tzdata \ + curl \ + dumb-init \ + postgresql-libs \ + ca-certificates + + +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 +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/x86_64-unknown-linux-musl/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/arm64/Dockerfile b/docker/arm64/Dockerfile index ddda4f98..3e019ba6 100644 --- a/docker/arm64/Dockerfile +++ b/docker/arm64/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,15 +33,27 @@ FROM rust:1.54-bullseye as build ARG DB=sqlite,mysql,postgresql # 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 +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :arm64 version. +# What we can do is a force install, because nothing important is overlapping each other. +# # Install required build libs for arm64 architecture. # To compile both mysql and postgresql we need some extra packages for both host arch and target arch -RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ - /etc/apt/sources.list.d/deb-src.list \ +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ && dpkg --add-architecture arm64 \ && apt-get update \ && apt-get install -y \ @@ -48,45 +62,45 @@ RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ libc6-dev:arm64 \ libpq5:arm64 \ libpq-dev \ + libmariadb3:amd64 \ libmariadb-dev:arm64 \ libmariadb-dev-compat:arm64 \ gcc-aarch64-linux-gnu \ - && mkdir -p ~/.cargo \ - && echo '[target.aarch64-unknown-linux-gnu]' >> ~/.cargo/config \ - && echo 'linker = "aarch64-linux-gnu-gcc"' >> ~/.cargo/config \ - && echo 'rustflags = ["-L/usr/lib/aarch64-linux-gnu"]' >> ~/.cargo/config - -ENV CARGO_HOME "/root/.cargo" -ENV USER "root" - -# 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 - -# NOTE: This should be the last apt-get/dpkg for this stage, since after this it will fail because of broken dependencies. -# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. -# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) -# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :arm64 version. -# What we can do is a force install, because nothing important is overlapping each other. -RUN apt-get install -y --no-install-recommends libmariadb3:amd64 \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) && apt-get download libmariadb-dev-compat:amd64 \ && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. # The libpq5:arm64 package seems to not provide a symlink to libpq.so.5 with the name libpq.so. # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. # Without this specific file the ld command will fail and compilation fails with it. - && ln -sfnr /usr/lib/aarch64-linux-gnu/libpq.so.5 /usr/lib/aarch64-linux-gnu/libpq.so - + && ln -sfnr /usr/lib/aarch64-linux-gnu/libpq.so.5 /usr/lib/aarch64-linux-gnu/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.aarch64-unknown-linux-gnu]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "aarch64-linux-gnu-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/aarch64-linux-gnu"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values 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" + + +# 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 aarch64-unknown-linux-gnu # Builds your dependencies and removes the @@ -128,6 +142,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* # hadolint ignore=DL3059 diff --git a/docker/arm64/Dockerfile.buildx b/docker/arm64/Dockerfile.buildx new file mode 100644 index 00000000..afbdd46d --- /dev/null +++ b/docker/arm64/Dockerfile.buildx @@ -0,0 +1,169 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM rust:1.54-bullseye as build + +# Debian-based builds support multidb +ARG DB=sqlite,mysql,postgresql + +# 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 \ + CARGO_HOME="/root/.cargo" \ + USER="root" + + +# Create CARGO_HOME folder and don't download rust docs +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal + +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :arm64 version. +# What we can do is a force install, because nothing important is overlapping each other. +# +# Install required build libs for arm64 architecture. +# To compile both mysql and postgresql we need some extra packages for both host arch and target arch +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ + && dpkg --add-architecture arm64 \ + && apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libssl-dev:arm64 \ + libc6-dev:arm64 \ + libpq5:arm64 \ + libpq-dev \ + libmariadb3:amd64 \ + libmariadb-dev:arm64 \ + libmariadb-dev-compat:arm64 \ + gcc-aarch64-linux-gnu \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) + && apt-get download libmariadb-dev-compat:amd64 \ + && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ + && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # + # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. + # The libpq5:arm64 package seems to not provide a symlink to libpq.so.5 with the name libpq.so. + # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. + # Without this specific file the ld command will fail and compilation fails with it. + && ln -sfnr /usr/lib/aarch64-linux-gnu/libpq.so.5 /usr/lib/aarch64-linux-gnu/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.aarch64-unknown-linux-gnu]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "aarch64-linux-gnu-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/aarch64-linux-gnu"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values +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" + + +# 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry rustup target add aarch64-unknown-linux-gnu + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=aarch64-unknown-linux-gnu \ + && 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=aarch64-unknown-linux-gnu + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM balenalib/aarch64-debian:bullseye + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 + +# hadolint ignore=DL3059 +RUN [ "cross-build-start" ] + +# Create data folder and Install needed libraries +RUN mkdir /data \ + && apt-get update && apt-get install -y \ + --no-install-recommends \ + openssl \ + ca-certificates \ + curl \ + dumb-init \ + libmariadb-dev-compat \ + libpq5 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# hadolint ignore=DL3059 +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 +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/aarch64-unknown-linux-gnu/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/armv6/Dockerfile b/docker/armv6/Dockerfile index 1935517f..a5d1693b 100644 --- a/docker/armv6/Dockerfile +++ b/docker/armv6/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,15 +33,27 @@ FROM rust:1.54-bullseye as build ARG DB=sqlite,mysql,postgresql # 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 +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armel version. +# What we can do is a force install, because nothing important is overlapping each other. +# # Install required build libs for armel architecture. # To compile both mysql and postgresql we need some extra packages for both host arch and target arch -RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ - /etc/apt/sources.list.d/deb-src.list \ +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ && dpkg --add-architecture armel \ && apt-get update \ && apt-get install -y \ @@ -48,45 +62,45 @@ RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ libc6-dev:armel \ libpq5:armel \ libpq-dev \ + libmariadb3:amd64 \ libmariadb-dev:armel \ libmariadb-dev-compat:armel \ gcc-arm-linux-gnueabi \ - && mkdir -p ~/.cargo \ - && echo '[target.arm-unknown-linux-gnueabi]' >> ~/.cargo/config \ - && echo 'linker = "arm-linux-gnueabi-gcc"' >> ~/.cargo/config \ - && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabi"]' >> ~/.cargo/config - -ENV CARGO_HOME "/root/.cargo" -ENV USER "root" - -# 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 - -# NOTE: This should be the last apt-get/dpkg for this stage, since after this it will fail because of broken dependencies. -# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. -# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) -# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armel version. -# What we can do is a force install, because nothing important is overlapping each other. -RUN apt-get install -y --no-install-recommends libmariadb3:amd64 \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) && apt-get download libmariadb-dev-compat:amd64 \ && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. # The libpq5:armel package seems to not provide a symlink to libpq.so.5 with the name libpq.so. # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. # Without this specific file the ld command will fail and compilation fails with it. - && ln -sfnr /usr/lib/arm-linux-gnueabi/libpq.so.5 /usr/lib/arm-linux-gnueabi/libpq.so - + && ln -sfnr /usr/lib/arm-linux-gnueabi/libpq.so.5 /usr/lib/arm-linux-gnueabi/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.arm-unknown-linux-gnueabi]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "arm-linux-gnueabi-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabi"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values 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" + + +# 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 arm-unknown-linux-gnueabi # Builds your dependencies and removes the @@ -128,6 +142,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* # hadolint ignore=DL3059 diff --git a/docker/armv6/Dockerfile.buildx b/docker/armv6/Dockerfile.buildx new file mode 100644 index 00000000..5d7dc057 --- /dev/null +++ b/docker/armv6/Dockerfile.buildx @@ -0,0 +1,169 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM rust:1.54-bullseye as build + +# Debian-based builds support multidb +ARG DB=sqlite,mysql,postgresql + +# 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 \ + CARGO_HOME="/root/.cargo" \ + USER="root" + + +# Create CARGO_HOME folder and don't download rust docs +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal + +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armel version. +# What we can do is a force install, because nothing important is overlapping each other. +# +# Install required build libs for armel architecture. +# To compile both mysql and postgresql we need some extra packages for both host arch and target arch +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ + && dpkg --add-architecture armel \ + && apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libssl-dev:armel \ + libc6-dev:armel \ + libpq5:armel \ + libpq-dev \ + libmariadb3:amd64 \ + libmariadb-dev:armel \ + libmariadb-dev-compat:armel \ + gcc-arm-linux-gnueabi \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) + && apt-get download libmariadb-dev-compat:amd64 \ + && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ + && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # + # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. + # The libpq5:armel package seems to not provide a symlink to libpq.so.5 with the name libpq.so. + # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. + # Without this specific file the ld command will fail and compilation fails with it. + && ln -sfnr /usr/lib/arm-linux-gnueabi/libpq.so.5 /usr/lib/arm-linux-gnueabi/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.arm-unknown-linux-gnueabi]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "arm-linux-gnueabi-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabi"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values +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" + + +# 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry rustup target add arm-unknown-linux-gnueabi + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=arm-unknown-linux-gnueabi \ + && 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=arm-unknown-linux-gnueabi + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM balenalib/rpi-debian:bullseye + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 + +# hadolint ignore=DL3059 +RUN [ "cross-build-start" ] + +# Create data folder and Install needed libraries +RUN mkdir /data \ + && apt-get update && apt-get install -y \ + --no-install-recommends \ + openssl \ + ca-certificates \ + curl \ + dumb-init \ + libmariadb-dev-compat \ + libpq5 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# hadolint ignore=DL3059 +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 +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/arm-unknown-linux-gnueabi/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/armv7/Dockerfile b/docker/armv7/Dockerfile index 9172b90e..9a168f65 100644 --- a/docker/armv7/Dockerfile +++ b/docker/armv7/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -31,15 +33,27 @@ FROM rust:1.54-bullseye as build ARG DB=sqlite,mysql,postgresql # 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 +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armhf version. +# What we can do is a force install, because nothing important is overlapping each other. +# # Install required build libs for armhf architecture. # To compile both mysql and postgresql we need some extra packages for both host arch and target arch -RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ - /etc/apt/sources.list.d/deb-src.list \ +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ && dpkg --add-architecture armhf \ && apt-get update \ && apt-get install -y \ @@ -48,45 +62,45 @@ RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ libc6-dev:armhf \ libpq5:armhf \ libpq-dev \ + libmariadb3:amd64 \ libmariadb-dev:armhf \ libmariadb-dev-compat:armhf \ gcc-arm-linux-gnueabihf \ - && mkdir -p ~/.cargo \ - && echo '[target.armv7-unknown-linux-gnueabihf]' >> ~/.cargo/config \ - && echo 'linker = "arm-linux-gnueabihf-gcc"' >> ~/.cargo/config \ - && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabihf"]' >> ~/.cargo/config - -ENV CARGO_HOME "/root/.cargo" -ENV USER "root" - -# 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 - -# NOTE: This should be the last apt-get/dpkg for this stage, since after this it will fail because of broken dependencies. -# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. -# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) -# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armhf version. -# What we can do is a force install, because nothing important is overlapping each other. -RUN apt-get install -y --no-install-recommends libmariadb3:amd64 \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) && apt-get download libmariadb-dev-compat:amd64 \ && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. # The libpq5:armhf package seems to not provide a symlink to libpq.so.5 with the name libpq.so. # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. # Without this specific file the ld command will fail and compilation fails with it. - && ln -sfnr /usr/lib/arm-linux-gnueabihf/libpq.so.5 /usr/lib/arm-linux-gnueabihf/libpq.so - + && ln -sfnr /usr/lib/arm-linux-gnueabihf/libpq.so.5 /usr/lib/arm-linux-gnueabihf/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.armv7-unknown-linux-gnueabihf]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "arm-linux-gnueabihf-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabihf"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values 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" + + +# 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-gnueabihf # Builds your dependencies and removes the @@ -128,6 +142,7 @@ RUN mkdir /data \ dumb-init \ libmariadb-dev-compat \ libpq5 \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* # hadolint ignore=DL3059 diff --git a/docker/armv7/Dockerfile.alpine b/docker/armv7/Dockerfile.alpine index a6ca1582..f78168cf 100644 --- a/docker/armv7/Dockerfile.alpine +++ b/docker/armv7/Dockerfile.alpine @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + # This file was generated using a Jinja2 template. # Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. @@ -32,12 +34,18 @@ FROM messense/rust-musl-cross:armv7-musleabihf as build ARG DB=sqlite,vendored_openssl # 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 +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + TZ=UTC \ + TERM=xterm-256color \ + CARGO_HOME="/root/.cargo" \ + USER="root" + -# Don't download rust docs -RUN rustup set profile minimal +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal -ENV USER "root" ENV RUSTFLAGS='-C link-arg=-s' ENV CFLAGS_armv7_unknown_linux_musleabihf="-mfpu=vfpv3-d16" diff --git a/docker/armv7/Dockerfile.buildx b/docker/armv7/Dockerfile.buildx new file mode 100644 index 00000000..938abd58 --- /dev/null +++ b/docker/armv7/Dockerfile.buildx @@ -0,0 +1,169 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM rust:1.54-bullseye as build + +# Debian-based builds support multidb +ARG DB=sqlite,mysql,postgresql + +# 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 \ + CARGO_HOME="/root/.cargo" \ + USER="root" + + +# Create CARGO_HOME folder and don't download rust docs +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal + +# NOTE: Any apt-get/dpkg after this stage will fail because of broken dependencies. +# For Diesel-RS migrations_macros to compile with MySQL/MariaDB we need to do some magic. +# We at least need libmariadb3:amd64 installed for the x86_64 version of libmariadb.so (client) +# We also need the libmariadb-dev-compat:amd64 but it can not be installed together with the :armhf version. +# What we can do is a force install, because nothing important is overlapping each other. +# +# Install required build libs for armhf architecture. +# To compile both mysql and postgresql we need some extra packages for both host arch and target arch +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list \ + && dpkg --add-architecture armhf \ + && apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + libssl-dev:armhf \ + libc6-dev:armhf \ + libpq5:armhf \ + libpq-dev \ + libmariadb3:amd64 \ + libmariadb-dev:armhf \ + libmariadb-dev-compat:armhf \ + gcc-arm-linux-gnueabihf \ + # + # Manual install libmariadb-dev-compat:amd64 ( After this broken dependencies will break apt ) + && apt-get download libmariadb-dev-compat:amd64 \ + && dpkg --force-all -i ./libmariadb-dev-compat*.deb \ + && rm -rvf ./libmariadb-dev-compat*.deb \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + # + # For Diesel-RS migrations_macros to compile with PostgreSQL we need to do some magic. + # The libpq5:armhf package seems to not provide a symlink to libpq.so.5 with the name libpq.so. + # This is only provided by the libpq-dev package which can't be installed for both arch at the same time. + # Without this specific file the ld command will fail and compilation fails with it. + && ln -sfnr /usr/lib/arm-linux-gnueabihf/libpq.so.5 /usr/lib/arm-linux-gnueabihf/libpq.so \ + # + # Make sure cargo has the right target config + && echo '[target.armv7-unknown-linux-gnueabihf]' >> "${CARGO_HOME}/config" \ + && echo 'linker = "arm-linux-gnueabihf-gcc"' >> "${CARGO_HOME}/config" \ + && echo 'rustflags = ["-L/usr/lib/arm-linux-gnueabihf"]' >> "${CARGO_HOME}/config" + +# Set arm specific environment values +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" + + +# 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry rustup target add armv7-unknown-linux-gnueabihf + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=armv7-unknown-linux-gnueabihf \ + && 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=armv7-unknown-linux-gnueabihf + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM balenalib/armv7hf-debian:bullseye + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 + +# hadolint ignore=DL3059 +RUN [ "cross-build-start" ] + +# Create data folder and Install needed libraries +RUN mkdir /data \ + && apt-get update && apt-get install -y \ + --no-install-recommends \ + openssl \ + ca-certificates \ + curl \ + dumb-init \ + libmariadb-dev-compat \ + libpq5 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# hadolint ignore=DL3059 +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 +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/armv7-unknown-linux-gnueabihf/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] diff --git a/docker/armv7/Dockerfile.buildx.alpine b/docker/armv7/Dockerfile.buildx.alpine new file mode 100644 index 00000000..8b72d1d3 --- /dev/null +++ b/docker/armv7/Dockerfile.buildx.alpine @@ -0,0 +1,125 @@ +# syntax=docker/dockerfile:1 + +# This file was generated using a Jinja2 template. +# Please make your changes in `Dockerfile.j2` and then `make` the individual Dockerfiles. + +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +# The web-vault digest specifies a particular web-vault build on Docker Hub. +# Using the digest instead of the tag name provides better security, +# as the digest of an image is immutable, whereas a tag name can later +# be changed to point to a malicious image. +# +# To verify the current digest for a given tag name: +# - From https://hub.docker.com/r/vaultwarden/web-vault/tags, +# click the tag name to view the digest of the image it currently points to. +# - From the command line: +# $ docker pull vaultwarden/web-vault:v2.21.1 +# $ docker image inspect --format "{{.RepoDigests}}" vaultwarden/web-vault:v2.21.1 +# [vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5] +# +# - Conversely, to get the tag name from the digest: +# $ docker image inspect --format "{{.RepoTags}}" vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 +# [vaultwarden/web-vault:v2.21.1] +# +FROM vaultwarden/web-vault@sha256:29a4fa7bf3790fff9d908b02ac5a154913491f4bf30c95b87b06d8cf1c5516b5 as vault + +########################## BUILD IMAGE ########################## +FROM messense/rust-musl-cross:armv7-musleabihf as build + +# Alpine-based ARM (musl) only supports sqlite during compile time. +# We now also need to add vendored_openssl, because the current base image we use to build has OpenSSL removed. +ARG DB=sqlite,vendored_openssl + +# 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 \ + CARGO_HOME="/root/.cargo" \ + USER="root" + + +# Create CARGO_HOME folder and don't download rust docs +RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry mkdir -pv "${CARGO_HOME}" \ + && rustup set profile minimal + +ENV RUSTFLAGS='-C link-arg=-s' +ENV CFLAGS_armv7_unknown_linux_musleabihf="-mfpu=vfpv3-d16" + +# 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=armv7-unknown-linux-musleabihf \ + && 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 --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=armv7-unknown-linux-musleabihf +# hadolint ignore=DL3059 +RUN musl-strip target/armv7-unknown-linux-musleabihf/release/vaultwarden + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM balenalib/armv7hf-alpine:3.14 + +ENV ROCKET_ENV "staging" +ENV ROCKET_PORT=80 +ENV ROCKET_WORKERS=10 +ENV SSL_CERT_DIR=/etc/ssl/certs + +# hadolint ignore=DL3059 +RUN [ "cross-build-start" ] + +# Create data folder and Install needed libraries +RUN mkdir /data \ + && apk add --no-cache \ + openssl \ + tzdata \ + curl \ + dumb-init \ + ca-certificates + +# hadolint ignore=DL3059 +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 +WORKDIR / +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /app/target/armv7-unknown-linux-musleabihf/release/vaultwarden . + +COPY docker/healthcheck.sh /healthcheck.sh +COPY docker/start.sh /start.sh + +HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"] + +# Configures the startup! +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["/start.sh"] |