diff --git a/Dockerfile b/Dockerfile index 868d0b9..ff1a6e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ -# Use Ubuntu 18.04 LTS as our base image. -FROM ubuntu:18.04 +# syntax=docker/dockerfile:1 + +# Use Ubuntu 20.04 LTS as our base image. +FROM ubuntu:20.04 # The Rust toolchain to use when building our image. Set by `hooks/build`. ARG TOOLCHAIN=stable @@ -10,6 +12,10 @@ ARG TOOLCHAIN=stable # # ALSO UPDATE hooks/build! ARG OPENSSL_VERSION=1.1.1m +# Needs evaluation; +# fails for libpq with: +# "configure: error: library 'crypto' is required for OpenSSL" +# ARG OPENSSL_VERSION=3.0.0 # Versions for other dependencies. Here are the places to check for new # releases: @@ -38,8 +44,8 @@ ARG POSTGRESQL_VERSION=11.14 # # We also set up a `rust` user by default. This user has sudo privileges if you # need to install any more software. -RUN apt-get update && \ - export DEBIAN_FRONTEND=noninteractive && \ +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ apt-get install -yq \ build-essential \ cmake \ @@ -61,32 +67,6 @@ RUN apt-get update && \ apt-get clean && rm -rf /var/lib/apt/lists/* && \ useradd rust --user-group --create-home --shell /bin/bash --groups sudo -# - `mdbook` is the standard Rust tool for making searchable HTML manuals. -# - `mdbook-graphviz` allows using inline GraphViz drawing commands to add illustrations. -# - `cargo-about` generates a giant license file for all dependencies. -# - `cargo-audit` checks for security vulnerabilities. We include it for backwards compat. -# - `cargo-deny` does everything `cargo-audit` does, plus check licenses & many other things. -RUN curl -fLO https://github.com/rust-lang-nursery/mdBook/releases/download/v$MDBOOK_VERSION/mdbook-v$MDBOOK_VERSION-x86_64-unknown-linux-gnu.tar.gz && \ - tar xf mdbook-v$MDBOOK_VERSION-x86_64-unknown-linux-gnu.tar.gz && \ - mv mdbook /usr/local/bin/ && \ - rm -f mdbook-v$MDBOOK_VERSION-x86_64-unknown-linux-gnu.tar.gz && \ - curl -fLO https://github.com/dylanowen/mdbook-graphviz/releases/download/v$MDBOOK_GRAPHVIZ_VERSION/mdbook-graphviz_v${MDBOOK_GRAPHVIZ_VERSION}_x86_64-unknown-linux-musl.zip && \ - unzip mdbook-graphviz_v${MDBOOK_GRAPHVIZ_VERSION}_x86_64-unknown-linux-musl.zip && \ - mv mdbook-graphviz /usr/local/bin/ && \ - rm -f mdbook-graphviz_v${MDBOOK_GRAPHVIZ_VERSION}_x86_64-unknown-linux-musl.zip && \ - curl -fLO https://github.com/EmbarkStudios/cargo-about/releases/download/$CARGO_ABOUT_VERSION/cargo-about-$CARGO_ABOUT_VERSION-x86_64-unknown-linux-musl.tar.gz && \ - tar xf cargo-about-$CARGO_ABOUT_VERSION-x86_64-unknown-linux-musl.tar.gz && \ - mv cargo-about-$CARGO_ABOUT_VERSION-x86_64-unknown-linux-musl/cargo-about /usr/local/bin/ && \ - rm -rf cargo-about-$CARGO_ABOUT_VERSION-x86_64-unknown-linux-musl.tar.gz cargo-about-$CARGO_ABOUT_VERSION-x86_64-unknown-linux-musl && \ - curl -fLO https://github.com/rustsec/rustsec/releases/download/cargo-audit%2Fv${CARGO_AUDIT_VERSION}/cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION}.tgz && \ - tar xf cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION}.tgz && \ - cp cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION}/cargo-audit /usr/local/bin/ && \ - rm -rf cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION}.tgz cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION} && \ - curl -fLO https://github.com/EmbarkStudios/cargo-deny/releases/download/$CARGO_DENY_VERSION/cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl.tar.gz && \ - tar xf cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl.tar.gz && \ - mv cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl/cargo-deny /usr/local/bin/ && \ - rm -rf cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl.tar.gz - # Static linking for C++ code RUN ln -s "/usr/bin/g++" "/usr/bin/musl-g++" @@ -97,17 +77,17 @@ RUN ln -s "/usr/bin/g++" "/usr/bin/musl-g++" # necessarily the right ones) in an effort to compile OpenSSL 1.1's "engine" # component. It's possible that this will cause bizarre and terrible things to # happen. There may be "sanitized" header -RUN echo "Building OpenSSL" && \ +RUN echo "Building OpenSSL ${OPENSSL_VERSION}" && \ ls /usr/include/linux && \ mkdir -p /usr/local/musl/include && \ ln -s /usr/include/linux /usr/local/musl/include/linux && \ ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/musl/include/asm && \ ln -s /usr/include/asm-generic /usr/local/musl/include/asm-generic && \ cd /tmp && \ - short_version="$(echo "$OPENSSL_VERSION" | sed s'/[a-z]$//' )" && \ - curl -fLO "https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz" || \ + short_version="$(echo "${OPENSSL_VERSION}" | sed s'/[a-z]$//' )" && \ + curl -fLO "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz" || \ curl -fLO "https://www.openssl.org/source/old/$short_version/openssl-$OPENSSL_VERSION.tar.gz" && \ - tar xvzf "openssl-$OPENSSL_VERSION.tar.gz" && cd "openssl-$OPENSSL_VERSION" && \ + tar xvzf "openssl-${OPENSSL_VERSION}.tar.gz" && cd "openssl-${OPENSSL_VERSION}" && \ env CC=musl-gcc ./Configure no-shared no-zlib -fPIC --prefix=/usr/local/musl -DOPENSSL_NO_SECURE_MEMORY linux-x86_64 && \ env C_INCLUDE_PATH=/usr/local/musl/include/ make depend && \ env C_INCLUDE_PATH=/usr/local/musl/include/ make && \ @@ -115,18 +95,18 @@ RUN echo "Building OpenSSL" && \ rm /usr/local/musl/include/linux /usr/local/musl/include/asm /usr/local/musl/include/asm-generic && \ rm -r /tmp/* -RUN echo "Building zlib" && \ +RUN echo "Building zlib ${ZLIB_VERSION}" && \ cd /tmp && \ - curl -fLO "http://zlib.net/zlib-$ZLIB_VERSION.tar.gz" && \ - tar xzf "zlib-$ZLIB_VERSION.tar.gz" && cd "zlib-$ZLIB_VERSION" && \ + curl -fLO "http://zlib.net/zlib-${ZLIB_VERSION}.tar.gz" && \ + tar xzf "zlib-${ZLIB_VERSION}.tar.gz" && cd "zlib-${ZLIB_VERSION}" && \ CC=musl-gcc ./configure --static --prefix=/usr/local/musl && \ make && make install && \ rm -r /tmp/* -RUN echo "Building libpq" && \ +RUN echo "Building libpq ${POSTGRESQL_VERSION}" && \ cd /tmp && \ - curl -fLO "https://ftp.postgresql.org/pub/source/v$POSTGRESQL_VERSION/postgresql-$POSTGRESQL_VERSION.tar.gz" && \ - tar xzf "postgresql-$POSTGRESQL_VERSION.tar.gz" && cd "postgresql-$POSTGRESQL_VERSION" && \ + curl -fLO "https://ftp.postgresql.org/pub/source/v${POSTGRESQL_VERSION}/postgresql-${POSTGRESQL_VERSION}.tar.gz" && \ + tar xzf "postgresql-${POSTGRESQL_VERSION}.tar.gz" && cd "postgresql-${POSTGRESQL_VERSION}" && \ CC=musl-gcc CPPFLAGS=-I/usr/local/musl/include LDFLAGS=-L/usr/local/musl/lib ./configure --with-openssl --without-readline --prefix=/usr/local/musl && \ cd src/interfaces/libpq && make all-static-lib && make install-lib-static && \ cd ../../bin/pg_config && make && make install && \ @@ -139,7 +119,7 @@ RUN echo "Building libpq" && \ # Install a `git credentials` helper for using GH_USER and GH_TOKEN to access # private repositories if desired. We make sure this is configured for root, # here, and for the `rust` user below. -ADD git-credential-ghtoken /usr/local/bin/ghtoken +COPY git-credential-ghtoken /usr/local/bin/ghtoken RUN git config --global credential.https://github.com.helper ghtoken # Set up our path with all our binary directories, including those for the @@ -155,16 +135,23 @@ ENV RUSTUP_HOME=/opt/rust/rustup \ # interact with the user or fool around with TTYs. We also set the default # `--target` to musl so that our users don't need to keep overriding it # manually. -RUN curl https://sh.rustup.rs -sSf | \ +RUN echo "Installing Rust (${TOOLCHAIN} toolchain)" && \ + curl https://sh.rustup.rs -sSf | \ env CARGO_HOME=/opt/rust/cargo \ - sh -s -- -y --default-toolchain $TOOLCHAIN --profile minimal --no-modify-path && \ + sh -s -- -y --default-toolchain ${TOOLCHAIN} --profile minimal --no-modify-path && \ env CARGO_HOME=/opt/rust/cargo \ rustup component add rustfmt && \ env CARGO_HOME=/opt/rust/cargo \ rustup component add clippy && \ env CARGO_HOME=/opt/rust/cargo \ rustup target add x86_64-unknown-linux-musl -ADD cargo-config.toml /opt/rust/cargo/config + # if we also install other target's build dependencies (like tools, libs, and linkers) + # rustup target add x86_64-unknown-linux-musl \ + # rustup target add aarch64-unknown-linux-musl \ + # rustup target add armv7-unknown-linux-musleabihf \ + # rustup target add armv7-unknown-linux-musleabi + +COPY cargo-config.toml /opt/rust/cargo/config # Set up our environment variables so that we cross-compile using musl-libc by # default. @@ -181,12 +168,38 @@ ENV X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_DIR=/usr/local/musl/ \ # slow down image builds). This will use the static linking toolchain, but that # should be OK. # -# - `cargo-deb` builds Debian packages. -RUN env CARGO_HOME=/opt/rust/cargo cargo install -f cargo-deb && \ - rm -rf /opt/rust/cargo/registry/ +# - `cargo-deb` is a helper command which automatically creates binary Debian packages (.deb) from Cargo projects. +# - `mdbook` is the standard Rust tool for making searchable HTML manuals. +# - `mdbook-graphviz` allows using inline GraphViz drawing commands to add illustrations. +# - `cargo-about` generates a giant license file for all dependencies. +# - `cargo-audit` checks for security vulnerabilities. We include it for backwards compat. +# - `cargo-deny` does everything `cargo-audit` does, plus check licenses & many other things. +RUN echo "Installing cargo tools" && \ + env CARGO_HOME=/opt/rust/cargo cargo install -f cargo-deb && \ + rm -rf /opt/rust/cargo/registry/ && \ + curl -fLO https://github.com/rust-lang-nursery/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz && \ + tar xf mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz && \ + mv mdbook /usr/local/bin/ && \ + rm -f mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz && \ + curl -fLO https://github.com/dylanowen/mdbook-graphviz/releases/download/v${MDBOOK_GRAPHVIZ_VERSION}/mdbook-graphviz_v${MDBOOK_GRAPHVIZ_VERSION}_x86_64-unknown-linux-musl.zip && \ + unzip mdbook-graphviz_v${MDBOOK_GRAPHVIZ_VERSION}_x86_64-unknown-linux-musl.zip && \ + mv mdbook-graphviz /usr/local/bin/ && \ + rm -f mdbook-graphviz_v${MDBOOK_GRAPHVIZ_VERSION}_x86_64-unknown-linux-musl.zip && \ + curl -fLO https://github.com/EmbarkStudios/cargo-about/releases/download/${CARGO_ABOUT_VERSION}/cargo-about-${CARGO_ABOUT_VERSION}-x86_64-unknown-linux-musl.tar.gz && \ + tar xf cargo-about-${CARGO_ABOUT_VERSION}-x86_64-unknown-linux-musl.tar.gz && \ + mv cargo-about-${CARGO_ABOUT_VERSION}-x86_64-unknown-linux-musl/cargo-about /usr/local/bin/ && \ + rm -rf cargo-about-${CARGO_ABOUT_VERSION}-x86_64-unknown-linux-musl.tar.gz cargo-about-${CARGO_ABOUT_VERSION}-x86_64-unknown-linux-musl && \ + curl -fLO https://github.com/rustsec/rustsec/releases/download/cargo-audit%2Fv${CARGO_AUDIT_VERSION}/cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION}.tgz && \ + tar xf cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION}.tgz && \ + cp cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION}/cargo-audit /usr/local/bin/ && \ + rm -rf cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION}.tgz cargo-audit-x86_64-unknown-linux-gnu-v${CARGO_AUDIT_VERSION} && \ + curl -fLO https://github.com/EmbarkStudios/cargo-deny/releases/download/${CARGO_DENY_VERSION}/cargo-deny-${CARGO_DENY_VERSION}-x86_64-unknown-linux-musl.tar.gz && \ + tar xf cargo-deny-${CARGO_DENY_VERSION}-x86_64-unknown-linux-musl.tar.gz && \ + mv cargo-deny-${CARGO_DENY_VERSION}-x86_64-unknown-linux-musl/cargo-deny /usr/local/bin/ && \ + rm -rf cargo-deny-${CARGO_DENY_VERSION}-x86_64-unknown-linux-musl cargo-deny-${CARGO_DENY_VERSION}-x86_64-unknown-linux-musl.tar.gz # Allow sudo without a password. -ADD sudoers /etc/sudoers.d/nopasswd +COPY sudoers /etc/sudoers.d/nopasswd # Run all further code as user `rust`, create our working directories, install # our config file, and set up our credential helper. diff --git a/examples/linking-with-git2/Dockerfile b/examples/linking-with-git2/Dockerfile index d0e89fb..99d5308 100644 --- a/examples/linking-with-git2/Dockerfile +++ b/examples/linking-with-git2/Dockerfile @@ -11,3 +11,11 @@ ADD --chown=rust:rust . ./ # Build our application. RUN cargo build + +# Now, we need to build our _real_ Docker container, copying in `linking-with-git2`. +FROM debian:stretch-slim +RUN apt-get update && apt-get install -y ca-certificates +COPY --from=builder \ + /home/rust/src/target/x86_64-unknown-linux-musl/debug/linking-with-git2 \ + /usr/local/bin/ +CMD /usr/local/bin/linking-with-git2 diff --git a/examples/using-sqlx/Dockerfile b/examples/using-sqlx/Dockerfile index f25aad1..a16ef47 100644 --- a/examples/using-sqlx/Dockerfile +++ b/examples/using-sqlx/Dockerfile @@ -17,8 +17,8 @@ ADD --chown=rust:rust . ./ RUN cargo build --release # Now, we need to build our _real_ Docker container, copying in `using-sqlx`. -FROM alpine:latest -RUN apk --no-cache add ca-certificates +FROM debian:stretch-slim +RUN apt-get update && apt-get install -y ca-certificates COPY --from=builder \ /home/rust/src/target/x86_64-unknown-linux-musl/release/using-sqlx \ /usr/local/bin/ diff --git a/test-image b/test-image index f29ef40..e4356e0 100755 --- a/test-image +++ b/test-image @@ -17,12 +17,14 @@ echo "==== Verifying static linking" # Make sure we can build a static executable using `sqlx`. docker build -t rust-musl-builder-using-sqlx examples/using-sqlx -docker run --rm rust-musl-builder-using-sqlx sh -c " +docker run --rm rust-musl-builder-using-sqlx bash -c " set -euo pipefail echo -e '--- Test case for sqlx:' echo 'ldd says:' -if ldd /usr/local/bin/using-sqlx; then +lddresult=\$(ldd /usr/local/bin/using-sqlx) +echo \$lddresult +if [[ "\$lddresult" != *statically\ linked* ]]; then echo '[FAIL] Executable is not static!' 1>&2 exit 1 fi @@ -33,14 +35,16 @@ echo -e '[PASS] using-sqlx binary is statically linked.\n' docker build -t rust-musl-builder-linking-with-git2 examples/linking-with-git2 docker run --rm rust-musl-builder-linking-with-git2 bash -c " set -euo pipefail -cd /home/rust/src echo -e '--- Test case for libgit2:' echo 'ldd says:' -if ldd target/x86_64-unknown-linux-musl/debug/linking-with-git2; then +lddresult=\$(ldd /usr/local/bin/linking-with-git2) +echo \$lddresult +if [[ "\$lddresult" != *statically\ linked* ]]; then echo '[FAIL] Executable is not static!' 1>&2 exit 1 fi + echo -e '[PASS] libgit2 binary is statically linked.\n' "