mirror of
https://github.com/dani-garcia/vaultwarden
synced 2024-11-14 05:52:51 +01:00
ca9234ed86
There was a PR (#4370) to add i686/i386 support for Vaultwarden. That specific PR was not a viable way of adding this. This PR adds extra architectures for Debian based containers which we will not support by default. Those images will not be build and pushed to our container registries. Added the following architectures: - linux/386 - linux/ppc64le - linux/s390x Again, there will be no major support for these architectures, but it will allow people who use these architectures to build a Debian based binary more easily
248 lines
10 KiB
Django/Jinja
248 lines
10 KiB
Django/Jinja
# syntax=docker/dockerfile:1
|
|
|
|
# This file was generated using a Jinja2 template.
|
|
# Please make your changes in `DockerSettings.yaml` or `Dockerfile.j2` and then `make`
|
|
# This will generate two Dockerfile's `Dockerfile.debian` and `Dockerfile.alpine`
|
|
|
|
# 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 docker.io/vaultwarden/web-vault:{{ vault_version }}
|
|
# $ docker image inspect --format "{{ '{{' }}.RepoDigests}}" docker.io/vaultwarden/web-vault:{{ vault_version }}
|
|
# [docker.io/vaultwarden/web-vault@{{ vault_image_digest }}]
|
|
#
|
|
# - Conversely, to get the tag name from the digest:
|
|
# $ docker image inspect --format "{{ '{{' }}.RepoTags}}" docker.io/vaultwarden/web-vault@{{ vault_image_digest }}
|
|
# [docker.io/vaultwarden/web-vault:{{ vault_version }}]
|
|
#
|
|
FROM --platform=linux/amd64 docker.io/vaultwarden/web-vault@{{ vault_image_digest }} as vault
|
|
|
|
{% if base == "debian" %}
|
|
########################## Cross Compile Docker Helper Scripts ##########################
|
|
## We use the linux/amd64 no matter which Build Platform, since these are all bash scripts
|
|
## And these bash scripts do not have any significant difference if at all
|
|
FROM --platform=linux/amd64 docker.io/tonistiigi/xx@{{ xx_image_digest }} AS xx
|
|
{% elif base == "alpine" %}
|
|
########################## ALPINE BUILD IMAGES ##########################
|
|
## NOTE: The Alpine Base Images do not support other platforms then linux/amd64
|
|
## And for Alpine we define all build images here, they will only be loaded when actually used
|
|
{% for arch in build_stage_image[base].arch_image %}
|
|
FROM --platform={{ build_stage_image[base].platform }} {{ build_stage_image[base].arch_image[arch] }} as build_{{ arch }}
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
########################## BUILD IMAGE ##########################
|
|
# hadolint ignore=DL3006
|
|
FROM --platform={{ build_stage_image[base].platform }} {{ build_stage_image[base].image }} as build
|
|
{% if base == "debian" %}
|
|
COPY --from=xx / /
|
|
{% endif %}
|
|
ARG TARGETARCH
|
|
ARG TARGETVARIANT
|
|
ARG TARGETPLATFORM
|
|
|
|
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
|
|
|
# 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"
|
|
{%- if base == "alpine" %} \
|
|
# Use PostgreSQL v15 during Alpine/MUSL builds instead of the default v11
|
|
# Debian Bookworm already contains libpq v15
|
|
PQ_LIB_DIR="/usr/local/musl/pq15/lib"
|
|
{% endif %}
|
|
|
|
{% if base == "debian" %}
|
|
|
|
# Install clang to get `xx-cargo` working
|
|
# Install pkg-config to allow amd64 builds to find all libraries
|
|
# Install git so build.rs can determine the correct version
|
|
# Install the libc cross packages based upon the debian-arch
|
|
RUN apt-get update && \
|
|
apt-get install -y \
|
|
--no-install-recommends \
|
|
clang \
|
|
pkg-config \
|
|
git \
|
|
"libc6-$(xx-info debian-arch)-cross" \
|
|
"libc6-dev-$(xx-info debian-arch)-cross" \
|
|
"linux-libc-dev-$(xx-info debian-arch)-cross" && \
|
|
# Run xx-cargo early, since it sometimes seems to break when run at a later stage
|
|
echo "export CARGO_TARGET=$(xx-cargo --print-target-triple)" >> /env-cargo
|
|
|
|
RUN xx-apt-get install -y \
|
|
--no-install-recommends \
|
|
gcc \
|
|
libmariadb3 \
|
|
libpq-dev \
|
|
libpq5 \
|
|
libssl-dev \
|
|
zlib1g-dev && \
|
|
# Force install arch dependend mariadb dev packages
|
|
# Installing them the normal way breaks several other packages (again)
|
|
apt-get download "libmariadb-dev-compat:$(xx-info debian-arch)" "libmariadb-dev:$(xx-info debian-arch)" && \
|
|
dpkg --force-all -i ./libmariadb-dev*.deb
|
|
{% endif %}
|
|
|
|
# Create CARGO_HOME folder and don't download rust docs
|
|
RUN mkdir -pv "${CARGO_HOME}" \
|
|
&& rustup set profile minimal
|
|
|
|
# Creates a dummy project used to grab dependencies
|
|
RUN USER=root cargo new --bin /app
|
|
WORKDIR /app
|
|
|
|
{% if base == "debian" %}
|
|
# Environment variables for Cargo on Debian based builds
|
|
ARG ARCH_OPENSSL_LIB_DIR \
|
|
ARCH_OPENSSL_INCLUDE_DIR
|
|
|
|
RUN source /env-cargo && \
|
|
if xx-info is-cross ; then \
|
|
# Some special variables if needed to override some build paths
|
|
if [[ -n "${ARCH_OPENSSL_LIB_DIR}" && -n "${ARCH_OPENSSL_INCLUDE_DIR}" ]]; then \
|
|
echo "export $(echo "${CARGO_TARGET}" | tr '[:lower:]' '[:upper:]' | tr - _)_OPENSSL_LIB_DIR=${ARCH_OPENSSL_LIB_DIR}" >> /env-cargo && \
|
|
echo "export $(echo "${CARGO_TARGET}" | tr '[:lower:]' '[:upper:]' | tr - _)_OPENSSL_INCLUDE_DIR=${ARCH_OPENSSL_INCLUDE_DIR}" >> /env-cargo ; \
|
|
fi && \
|
|
# We can't use xx-cargo since that uses clang, which doesn't work for our libraries.
|
|
# Because of this we generate the needed environment variables here which we can load in the needed steps.
|
|
echo "export CC_$(echo "${CARGO_TARGET}" | tr '[:upper:]' '[:lower:]' | tr - _)=/usr/bin/$(xx-info)-gcc" >> /env-cargo && \
|
|
echo "export CARGO_TARGET_$(echo "${CARGO_TARGET}" | tr '[:lower:]' '[:upper:]' | tr - _)_LINKER=/usr/bin/$(xx-info)-gcc" >> /env-cargo && \
|
|
echo "export PKG_CONFIG=/usr/bin/$(xx-info)-pkg-config" >> /env-cargo && \
|
|
echo "export CROSS_COMPILE=1" >> /env-cargo && \
|
|
echo "export OPENSSL_INCLUDE_DIR=/usr/include/$(xx-info)" >> /env-cargo && \
|
|
echo "export OPENSSL_LIB_DIR=/usr/lib/$(xx-info)" >> /env-cargo ; \
|
|
fi && \
|
|
# Output the current contents of the file
|
|
cat /env-cargo
|
|
|
|
# Configure the DB ARG as late as possible to not invalidate the cached layers above
|
|
ARG DB=sqlite,mysql,postgresql
|
|
{% elif base == "alpine" %}
|
|
# Environment variables for Cargo on Alpine based builds
|
|
RUN echo "export CARGO_TARGET=${RUST_MUSL_CROSS_TARGET}" >> /env-cargo && \
|
|
# To be able to build the armv6 image with mimalloc we need to tell the linker to also look for libatomic
|
|
if [[ "${TARGETARCH}${TARGETVARIANT}" == "armv6" ]] ; then echo "export RUSTFLAGS='-Clink-arg=-latomic'" >> /env-cargo ; fi && \
|
|
# Output the current contents of the file
|
|
cat /env-cargo
|
|
|
|
# Configure the DB ARG as late as possible to not invalidate the cached layers above
|
|
# Enable MiMalloc to improve performance on Alpine builds
|
|
ARG DB=sqlite,mysql,postgresql,enable_mimalloc
|
|
{% endif %}
|
|
|
|
RUN source /env-cargo && \
|
|
rustup target add "${CARGO_TARGET}"
|
|
|
|
ARG CARGO_PROFILE=release
|
|
ARG VW_VERSION
|
|
|
|
# Copies over *only* your manifests and build files
|
|
COPY ./Cargo.* ./
|
|
COPY ./rust-toolchain.toml ./rust-toolchain.toml
|
|
COPY ./build.rs ./build.rs
|
|
|
|
# Builds your dependencies and removes the
|
|
# dummy project, except the target folder
|
|
# This folder contains the compiled dependencies
|
|
RUN source /env-cargo && \
|
|
cargo build --features ${DB} --profile "${CARGO_PROFILE}" --target="${CARGO_TARGET}" && \
|
|
find . -not -path "./target*" -delete
|
|
|
|
# Copies the complete project
|
|
# To avoid copying unneeded files, use .dockerignore
|
|
COPY . .
|
|
|
|
# Builds again, this time it will be the actual source files being build
|
|
RUN source /env-cargo && \
|
|
# Make sure that we actually build the project by updating the src/main.rs timestamp
|
|
# Also do this for build.rs to ensure the version is rechecked
|
|
touch build.rs src/main.rs && \
|
|
# Create a symlink to the binary target folder to easy copy the binary in the final stage
|
|
cargo build --features ${DB} --profile "${CARGO_PROFILE}" --target="${CARGO_TARGET}" && \
|
|
if [[ "${CARGO_PROFILE}" == "dev" ]] ; then \
|
|
ln -vfsr "/app/target/${CARGO_TARGET}/debug" /app/target/final ; \
|
|
else \
|
|
ln -vfsr "/app/target/${CARGO_TARGET}/${CARGO_PROFILE}" /app/target/final ; \
|
|
fi
|
|
|
|
|
|
######################## RUNTIME IMAGE ########################
|
|
# Create a new stage with a minimal image
|
|
# because we already have a binary built
|
|
#
|
|
# To build these images you need to have qemu binfmt support.
|
|
# See the following pages to help install these tools locally
|
|
# Ubuntu/Debian: https://wiki.debian.org/QemuUserEmulation
|
|
# Arch Linux: https://wiki.archlinux.org/title/QEMU#Chrooting_into_arm/arm64_environment_from_x86_64
|
|
#
|
|
# Or use a Docker image which modifies your host system to support this.
|
|
# The GitHub Actions Workflow uses the same image as used below.
|
|
# See: https://github.com/tonistiigi/binfmt
|
|
# Usage: docker run --privileged --rm tonistiigi/binfmt --install arm64,arm
|
|
# To uninstall: docker run --privileged --rm tonistiigi/binfmt --uninstall 'qemu-*'
|
|
#
|
|
# We need to add `--platform` here, because of a podman bug: https://github.com/containers/buildah/issues/4742
|
|
FROM --platform=$TARGETPLATFORM {{ runtime_stage_image[base] }}
|
|
|
|
ENV ROCKET_PROFILE="release" \
|
|
ROCKET_ADDRESS=0.0.0.0 \
|
|
ROCKET_PORT=80
|
|
{%- if base == "debian" %} \
|
|
DEBIAN_FRONTEND=noninteractive
|
|
{% elif base == "alpine" %} \
|
|
SSL_CERT_DIR=/etc/ssl/certs
|
|
{% endif %}
|
|
|
|
# Create data folder and Install needed libraries
|
|
RUN mkdir /data && \
|
|
{% if base == "debian" %}
|
|
apt-get update && apt-get install -y \
|
|
--no-install-recommends \
|
|
ca-certificates \
|
|
curl \
|
|
libmariadb-dev-compat \
|
|
libpq5 \
|
|
openssl && \
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
{% elif base == "alpine" %}
|
|
apk --no-cache add \
|
|
ca-certificates \
|
|
curl \
|
|
openssl \
|
|
tzdata
|
|
{% endif %}
|
|
|
|
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 docker/healthcheck.sh /healthcheck.sh
|
|
COPY docker/start.sh /start.sh
|
|
|
|
COPY --from=vault /web-vault ./web-vault
|
|
COPY --from=build /app/target/final/vaultwarden .
|
|
|
|
HEALTHCHECK --interval=60s --timeout=10s CMD ["/healthcheck.sh"]
|
|
|
|
CMD ["/start.sh"]
|