From e50cbda16910bf90c1d00b1d4b0306992f9ab1cf Mon Sep 17 00:00:00 2001 From: Eric Kidd Date: Sat, 27 Apr 2019 08:51:12 -0400 Subject: [PATCH] Allow building with OpenSSL 1.0 or 1.1 It turns out that some popular libaries still have problems with OpenSSL 1.1, particularly `postgres` 0.15. So we'll build two sets of images now. We also explain the new image tagging scheme, and fix a bug wher the test script didn't test the newly built image. --- Dockerfile | 5 ++++- README.md | 23 ++++++++++++++++++++ examples/using-diesel/Dockerfile | 6 +++++- hooks/build | 36 ++++++++++++++++++++++++++------ hooks/test | 5 ++++- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 59912d3..a3accb9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,10 @@ FROM ubuntu:18.04 # The Rust toolchain to use when building our image. Set by `hooks/build`. ARG TOOLCHAIN=stable +# The OpenSSL version to use. We parameterize this because many Rust +# projects will fail to build with 1.1. +ARG OPENSSL_VERSION=1.0.2r + # Make sure we have basic dev tools for building C libraries. Our goal # here is to support the musl-libc builds and Cargo builds needed for a # large selection of the most popular crates. @@ -73,7 +77,6 @@ RUN git config --global credential.https://github.com.helper ghtoken # needed by the popular Rust `hyper` crate. RUN echo "Building OpenSSL" && \ cd /tmp && \ - OPENSSL_VERSION=1.1.1b && \ curl -LO "https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz" && \ tar xvzf "openssl-$OPENSSL_VERSION.tar.gz" && cd "openssl-$OPENSSL_VERSION" && \ env CC=musl-gcc ./Configure no-shared no-zlib no-async no-engine -fPIC --prefix=/usr/local/musl -DOPENSSL_NO_SECURE_MEMORY linux-x86_64 && \ diff --git a/README.md b/README.md index d95d0df..5135e9a 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,29 @@ Binaries will be written to `target/$TARGET_ARCHITECTURE/release`. By default it With a bit of luck, you should be able to just copy your application binary from `target/x86_64-unknown-linux-musl/release`, and install it directly on any reasonably modern x86_64 Linux machine. In particular, you should be able make static release binaries using TravisCI and GitHub, or you can copy your Rust application into an [Alpine Linux container][]. See below for details! +## Available tags + +In general, we provide the following tagged Docker images: + +- `latest`, `stable`: Current stable Rust, with OpenSSL 1.0 (for now). We + try to update this fairly rapidly after every new stable release, and + after most point releases. +- `beta`: This usually gets updated every six weeks alongside the stable + release. It will usually not be updated for beta bugfix releases. +- `nightly-YYYY-MM-DD`: Specific nightly releases. These should almost + always support `clippy`, `rls` and `rustfmt`, as verified using + [rustup components history][comp]. If you need a specific date for + compatibility with `tokio` or another popular library using unstable + Rust, please file an issue. +- `stable-openssl11`: Current stable Rust, with OpenSSL 1.1. +- `nightly-YYYY-MM-DD-openssl11`: Specific nightly releases with OpenSSL + 1.1. + +At a minimum, each of these images should be able to +compile [examples/using-diesel](./examples/using-diesel). + +[comp]: https://rust-lang.github.io/rustup-components-history/index.html + ## Caching builds You may be able to speed up build performance by adding the following `-v` commands to the `rust-musl-builder` alias: diff --git a/examples/using-diesel/Dockerfile b/examples/using-diesel/Dockerfile index dc3406a..634a521 100644 --- a/examples/using-diesel/Dockerfile +++ b/examples/using-diesel/Dockerfile @@ -3,8 +3,12 @@ # An example Dockerfile showing how to build a Rust executable using this # image, and deploy it with a tiny Alpine Linux container. +# You can override this `--build-arg BASE_IMAGE=...` to use different +# version of Rust or OpenSSL. +ARG BASE_IMAGE=ekidd/rust-musl-builder:latest + # Our first FROM statement declares the build environment. -FROM ekidd/rust-musl-builder AS builder +FROM ${BASE_IMAGE} AS builder # Add our source code. ADD . ./ diff --git a/hooks/build b/hooks/build index 25810b6..8aa6213 100755 --- a/hooks/build +++ b/hooks/build @@ -1,23 +1,47 @@ #!/bin/bash +# +# This script is responsible for calling `docker build` on behalf of GitHub. But +# what it _really_ does is translate `DOCKER_TAG` into the builds args `TARGET` +# and `OPENSSL_VERSION`. # Abort if anything goes wrong. set -euo pipefail -# Decide what Rust toolchain to use. +# Default to using OpenSSL 1.0 for a while longer, because 1.1 is +# incompatible with the crates postgres 0.15 and openssl 0.9, which +# are still widely used. +OPENSSL_VERSION=1.0.2r + +# Pick an appropriate Docker tag case "$DOCKER_TAG" in + *-openssl11) + DOCKER_TAG_WITHOUT_OPENSSL="${DOCKER_TAG/-openssl11/}" + OPENSSL_VERSION=1.1.1b + ;; + *) + DOCKER_TAG_WITHOUT_OPENSSL="$DOCKER_TAG" + ;; +esac + +# Decide what Rust toolchain to use. +case "$DOCKER_TAG_WITHOUT_OPENSSL" in # Always map the Docker tags `latest` and `experimental` to stable Rust. - latest|experimental) + latest) TOOLCHAIN=stable ;; # Strip `experimental-` from other `experimental-*` tags. experimental-*) - TOOLCHAIN="${DOCKER_TAG/experimental-/}" + TOOLCHAIN="${DOCKER_TAG_WITHOUT_OPENSSL/experimental-/}" ;; - # Pass all our tags + # Pass all other tags through. *) - TOOLCHAIN="$DOCKER_TAG" + TOOLCHAIN="$DOCKER_TAG_WITHOUT_OPENSSL" ;; esac # Run the build. -docker build --build-arg TOOLCHAIN="$TOOLCHAIN" -t "$IMAGE_NAME" . +docker build \ + --build-arg TOOLCHAIN="$TOOLCHAIN" \ + --build-arg OPENSSL_VERSION="$OPENSSL_VERSION" \ + -t "$IMAGE_NAME" \ + . diff --git a/hooks/test b/hooks/test index ca536cc..72d6362 100755 --- a/hooks/test +++ b/hooks/test @@ -5,5 +5,8 @@ set -euo pipefail # Make sure we can build some of our more important test images. for EXAMPLE in using-diesel; do - docker build -t rust-musl-builder-"$EXAMPLE" examples/"$EXAMPLE" + docker build \ + --build-arg BASE_IMAGE="$IMAGE_NAME" \ + -t rust-musl-builder-"$EXAMPLE" \ + examples/"$EXAMPLE" done