Skip to content

Remove openssl and pq #154

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 3 additions & 54 deletions Dockerfile.arm64
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ LABEL maintainer="Eirik Albrigtsen <[email protected]>"
# Required packages:
# - musl-dev, musl-tools - the musl toolchain
# - curl, g++, make, pkgconf, cmake - for fetching and building third party libs
# - ca-certificates - openssl + curl + peer verification of downloads
# - xutils-dev - for openssl makedepend
# - libssl-dev and libpq-dev - for dynamic linking during diesel_codegen build process
# - ca-certificates - peer verification of downloads
# - git - cargo builds in user projects
# - linux-headers-amd64 - needed for building openssl 1.1 (stretch only)
# - file - needed by rustup.sh install
# - automake autoconf libtool - support crates building C deps as part cargo build
# NB: does not include cmake atm
Expand All @@ -25,9 +22,6 @@ RUN apt-get update && apt-get install -y \
curl \
pkgconf \
ca-certificates \
xutils-dev \
libssl-dev \
libpq-dev \
automake \
autoconf \
libtool \
Expand All @@ -53,9 +47,7 @@ RUN chmod a+X /root

# Convenience list of versions and variables for compilation later on
# This helps continuing manually if anything breaks.
ENV SSL_VER="1.1.1w" \
ZLIB_VER="1.3.1" \
PQ_VER="11.12" \
ENV ZLIB_VER="1.3.1" \
SQLITE_VER="3490100" \
PROTOBUF_VER="29.2" \
SCCACHE_VER="0.9.1" \
Expand All @@ -78,43 +70,13 @@ RUN curl -sSL https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VE
chmod +x /usr/local/bin/sccache && \
rm -rf sccache-v${SCCACHE_VER}-*-unknown-linux-musl

# Set up a prefix for musl build libraries, make the linker's job of finding them easier
# Primarily for the benefit of postgres.
# Lastly, link some linux-headers for openssl 1.1 (not used herein)
RUN mkdir $PREFIX && \
echo "$PREFIX/lib" >> /etc/ld-musl-aarch64.path && \
ln -s /usr/include/aarch64-linux-gnu/asm /usr/include/aarch64-linux-musl/asm && \
ln -s /usr/include/asm-generic /usr/include/aarch64-linux-musl/asm-generic && \
ln -s /usr/include/linux /usr/include/aarch64-linux-musl/linux

# Build zlib (used in openssl and pq)
# Build zlib (used in pq)
RUN curl -sSL https://zlib.net/zlib-$ZLIB_VER.tar.gz | tar xz && \
cd zlib-$ZLIB_VER && \
CC="musl-gcc -fPIC -pie" LDFLAGS="-L$PREFIX/lib" CFLAGS="-I$PREFIX/include" ./configure --static --prefix=$PREFIX && \
make -j$(nproc) && make install && \
cd .. && rm -rf zlib-$ZLIB_VER

# Build openssl (used in pq)
# Would like to use zlib here, but can't seem to get it to work properly
# TODO: fix so that it works
RUN curl -sSL https://www.openssl.org/source/openssl-$SSL_VER.tar.gz | tar xz && \
cd openssl-$SSL_VER && \
CFLAGS="-mno-outline-atomics" ./Configure no-zlib no-shared -fPIC --prefix=$PREFIX --openssldir=$PREFIX/ssl linux-aarch64 && \
env C_INCLUDE_PATH=$PREFIX/include make depend 2> /dev/null && \
make -j$(nproc) && make all install_sw && \
cd .. && rm -rf openssl-$SSL_VER

# Build libpq
RUN curl -sSL https://ftp.postgresql.org/pub/source/v$PQ_VER/postgresql-$PQ_VER.tar.gz | tar xz && \
cd postgresql-$PQ_VER && \
CC="musl-gcc -fPIE -pie" LDFLAGS="-L$PREFIX/lib" CFLAGS="-I$PREFIX/include" ./configure \
--without-readline \
--with-openssl \
--prefix=$PREFIX --host=x86_64-unknown-linux-musl && \
cd src/interfaces/libpq make -s -j$(nproc) all-static-lib && make -s install install-lib-static && \
cd ../../bin/pg_config && make -j $(nproc) && make install && \
cd .. && rm -rf postgresql-$PQ_VER

# Build libsqlite3 using same configuration as the alpine linux main/sqlite package
RUN curl -sSL https://www.sqlite.org/2025/sqlite-autoconf-$SQLITE_VER.tar.gz | tar xz && \
cd sqlite-autoconf-$SQLITE_VER && \
Expand All @@ -124,27 +86,14 @@ RUN curl -sSL https://www.sqlite.org/2025/sqlite-autoconf-$SQLITE_VER.tar.gz | t
make && make install && \
cd .. && rm -rf sqlite-autoconf-$SQLITE_VER

# SSL cert directories get overridden by --prefix and --openssldir
# and they do not match the typical host configurations.
# The SSL_CERT_* vars fix this, but only when inside this container
# musl-compiled binary must point SSL at the correct certs (muslrust/issues/5) elsewhere
# Postgres bindings need vars so that diesel_codegen.so uses the GNU deps at build time
# but finally links with the static libpq.a at the end.
# It needs the non-musl pg_config to set this up with libpq-dev (depending on libssl-dev)
# See https://github.com/sgrif/pq-sys/pull/18
ENV PATH=/root/.cargo/bin:$PREFIX/bin:$PATH \
RUSTUP_HOME=/root/.rustup \
CARGO_BUILD_TARGET=aarch64-unknown-linux-musl \
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-Clink-self-contained=yes -Clinker=rust-lld -Ctarget-feature=+crt-static" \
PKG_CONFIG_ALLOW_CROSS=true \
PKG_CONFIG_ALL_STATIC=true \
PQ_LIB_STATIC_AARCH64_UNKNOWN_LINUX_MUSL=true \
PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig \
PG_CONFIG_AARCH64_UNKNOWN_LINUX_GNU=/usr/bin/pg_config \
OPENSSL_STATIC=true \
OPENSSL_DIR=$PREFIX \
SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \
SSL_CERT_DIR=/etc/ssl/certs \
LIBZ_SYS_STATIC=1 \
DEBIAN_FRONTEND=noninteractive \
TZ=Etc/UTC
Expand Down
56 changes: 3 additions & 53 deletions Dockerfile.x86_64
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
# syntax=docker/dockerfile:1
FROM ubuntu:noble
LABEL maintainer="Eirik Albrigtsen <[email protected]>"

# Required packages:
# - musl-dev, musl-tools - the musl toolchain
# - curl, g++, make, pkgconf, cmake - for fetching and building third party libs
# - ca-certificates - openssl + curl + peer verification of downloads
# - xutils-dev - for openssl makedepend
# - libssl-dev and libpq-dev - for dynamic linking during diesel_codegen build process
# - git - cargo builds in user projects
# - linux-headers-amd64 - needed for building openssl 1.1 (stretch only)
# - file - needed by rustup.sh install
# - automake autoconf libtool - support crates building C deps as part cargo build
# NB: does not include cmake atm
Expand All @@ -24,9 +22,6 @@ RUN apt-get update && apt-get install -y \
curl \
pkgconf \
ca-certificates \
xutils-dev \
libssl-dev \
libpq-dev \
automake \
autoconf \
libtool \
Expand All @@ -52,9 +47,7 @@ RUN chmod a+X /root

# Convenience list of versions and variables for compilation later on
# This helps continuing manually if anything breaks.
ENV SSL_VER="1.1.1w" \
ZLIB_VER="1.3.1" \
PQ_VER="11.12" \
ENV ZLIB_VER="1.3.1" \
SQLITE_VER="3490100" \
PROTOBUF_VER="29.2" \
SCCACHE_VER="0.9.1" \
Expand All @@ -77,43 +70,13 @@ RUN curl -sSL https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VE
chmod +x /usr/local/bin/sccache && \
rm -rf sccache-v${SCCACHE_VER}-*-unknown-linux-musl

# Set up a prefix for musl build libraries, make the linker's job of finding them easier
# Primarily for the benefit of postgres.
# Lastly, link some linux-headers for openssl 1.1 (not used herein)
RUN mkdir $PREFIX && \
echo "$PREFIX/lib" >> /etc/ld-musl-x86_64.path && \
ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/x86_64-linux-musl/asm && \
ln -s /usr/include/asm-generic /usr/include/x86_64-linux-musl/asm-generic && \
ln -s /usr/include/linux /usr/include/x86_64-linux-musl/linux

# Build zlib (used in openssl and pq)
# Build zlib (used in pq)
RUN curl -sSL https://zlib.net/zlib-$ZLIB_VER.tar.gz | tar xz && \
cd zlib-$ZLIB_VER && \
CC="musl-gcc -fPIC -pie" LDFLAGS="-L$PREFIX/lib" CFLAGS="-I$PREFIX/include" ./configure --static --prefix=$PREFIX && \
make -j$(nproc) && make install && \
cd .. && rm -rf zlib-$ZLIB_VER

# Build openssl (used in pq)
# Would like to use zlib here, but can't seem to get it to work properly
# TODO: fix so that it works
RUN curl -sSL https://www.openssl.org/source/openssl-$SSL_VER.tar.gz | tar xz && \
cd openssl-$SSL_VER && \
./Configure no-zlib no-shared -fPIC --prefix=$PREFIX --openssldir=$PREFIX/ssl linux-x86_64 && \
env C_INCLUDE_PATH=$PREFIX/include make depend 2> /dev/null && \
make -j$(nproc) && make all install_sw && \
cd .. && rm -rf openssl-$SSL_VER

# Build libpq
RUN curl -sSL https://ftp.postgresql.org/pub/source/v$PQ_VER/postgresql-$PQ_VER.tar.gz | tar xz && \
cd postgresql-$PQ_VER && \
CC="musl-gcc -fPIE -pie" LDFLAGS="-L$PREFIX/lib" CFLAGS="-I$PREFIX/include" ./configure \
--without-readline \
--with-openssl \
--prefix=$PREFIX --host=x86_64-unknown-linux-musl && \
cd src/interfaces/libpq make -s -j$(nproc) all-static-lib && make -s install install-lib-static && \
cd ../../bin/pg_config && make -j $(nproc) && make install && \
cd .. && rm -rf postgresql-$PQ_VER

# Build libsqlite3 using same configuration as the alpine linux main/sqlite package
RUN curl -sSL https://www.sqlite.org/2025/sqlite-autoconf-$SQLITE_VER.tar.gz | tar xz && \
cd sqlite-autoconf-$SQLITE_VER && \
Expand All @@ -123,26 +86,13 @@ RUN curl -sSL https://www.sqlite.org/2025/sqlite-autoconf-$SQLITE_VER.tar.gz | t
make && make install && \
cd .. && rm -rf sqlite-autoconf-$SQLITE_VER

# SSL cert directories get overridden by --prefix and --openssldir
# and they do not match the typical host configurations.
# The SSL_CERT_* vars fix this, but only when inside this container
# musl-compiled binary must point SSL at the correct certs (muslrust/issues/5) elsewhere
# Postgres bindings need vars so that diesel_codegen.so uses the GNU deps at build time
# but finally links with the static libpq.a at the end.
# It needs the non-musl pg_config to set this up with libpq-dev (depending on libssl-dev)
# See https://github.com/sgrif/pq-sys/pull/18
ENV PATH=/root/.cargo/bin:$PREFIX/bin:$PATH \
RUSTUP_HOME=/root/.rustup \
CARGO_BUILD_TARGET=x86_64-unknown-linux-musl \
PKG_CONFIG_ALLOW_CROSS=true \
PKG_CONFIG_ALL_STATIC=true \
PQ_LIB_STATIC_X86_64_UNKNOWN_LINUX_MUSL=true \
PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig \
PG_CONFIG_X86_64_UNKNOWN_LINUX_GNU=/usr/bin/pg_config \
OPENSSL_STATIC=true \
OPENSSL_DIR=$PREFIX \
SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \
SSL_CERT_DIR=/etc/ssl/certs \
LIBZ_SYS_STATIC=1 \
DEBIAN_FRONTEND=noninteractive \
TZ=Etc/UTC
Expand Down
55 changes: 17 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
[![stable](https://github.com/clux/muslrust/actions/workflows/stable.yml/badge.svg)](https://github.com/clux/muslrust/actions/workflows/stable.yml)
[![docker pulls](https://img.shields.io/docker/pulls/clux/muslrust.svg)](https://hub.docker.com/r/clux/muslrust/tags)

A docker environment for building **static** rust binaries for `x86_64` and `arm64` **linux** environments using **[musl](https://musl.libc.org/)**. Built daily via [github actions](https://github.com/clux/muslrust/actions).
A docker environment for building **static** rust binaries for `x86_64` and `arm64` environments using **[musl](https://musl.libc.org/)**. Built daily via [github actions](https://github.com/clux/muslrust/actions).

Binaries compiled with `muslrust` are **light-weight**, call straight into the kernel without other dynamic system library dependencies, can be shipped to most linux distributions without compatibility issues, and can be inserted as-is into lightweight docker images such as [static distroless](https://github.com/GoogleContainerTools/distroless/blob/main/base/README.md), [scratch](https://hub.docker.com/_/scratch), or [alpine](https://hub.docker.com/_/alpine).
Binaries compiled with `muslrust` are **light-weight**, call straight into the kernel without other dynamic system library dependencies, can be shipped to most distributions without compatibility issues, and can be inserted as-is into lightweight docker images such as [static distroless](https://github.com/GoogleContainerTools/distroless/blob/main/base/README.md), [scratch](https://hub.docker.com/_/scratch), or [alpine](https://hub.docker.com/_/alpine).

The goal is to **simplify** the creation of small and **efficient cloud containers**, or **stand-alone linux binary releases**.

This image includes popular [C libraries](#c-libraries) compiled with `musl-gcc`, enabling static builds even when these libraries are used.
This image includes some hard-to-avoid [C libraries](#c-libraries) compiled with `musl-gcc`, enabling static builds even when these libraries are used.

## Usage

Expand Down Expand Up @@ -50,14 +50,20 @@ For pinned, or historical builds, see the [available tags on dockerhub](https://

The following system libraries are compiled against `musl-gcc`:

- [x] openssl ([openssl crate](https://github.com/sfackler/rust-openssl))
- [x] pq ([pq-sys crate](https://github.com/sgrif/pq-sys) used by [diesel](https://github.com/diesel-rs/diesel))
- [x] sqlite3 ([libsqlite3-sys crate](https://github.com/jgallagher/rusqlite/tree/master/libsqlite3-sys) used by [diesel](https://github.com/diesel-rs/diesel))
- [x] zlib (used by pq and openssl)
- sqlite3 ([libsqlite3-sys crate](https://github.com/jgallagher/rusqlite/tree/master/libsqlite3-sys) used by [diesel](https://github.com/diesel-rs/diesel))
- zlib

We **[try](https://github.com/clux/muslrust/blob/main/update_libs.py)** to keep these up to date.
Note that these libraries **may be removed** if sensible and popular Rust crates can replace them in the future.

NB: C library for `curl` has been removed in newer tags from 2025. See [#96](https://github.com/clux/muslrust/issues/96).
In the mean time, we **[try](https://github.com/clux/muslrust/blob/main/update_libs.py)** to keep these up to date.

Removed Libraries;

- `openssl` has been removed in 2025. See [#153](https://github.com/clux/muslrust/issues/153).
- `curl` has been removed in 2025. See [#96](https://github.com/clux/muslrust/issues/96).
- `pq` has been removed in 2025. See [#81](https://github.com/clux/muslrust/issues/81)

Consider [blackdex/rust-musl](https://github.com/BlackDex/rust-musl) for `openssl`, `curl` and `pq`.

## Developing

Expand All @@ -74,10 +80,9 @@ just test
Before we push a new version of muslrust we [test](https://github.com/clux/muslrust/blob/main/test.sh#L4-L17) to ensure that we can use and statically link:

- [x] [serde](https://crates.io/crates/serde)
- [x] [diesel](https://crates.io/crates/diesel)
- [x] [hyper](https://crates.io/crates/hyper)
- [x] [diesel](https://crates.io/crates/diesel) (using sqlite)
- [x] [rustls](https://crates.io/crates/rustls)
- [x] [openssl](https://crates.io/crates/openssl)
- [x] [hyper](https://crates.io/crates/hyper) (using hyper-rustls and rustls's default crypto backend)
- [x] [flate2](https://crates.io/crates/flate2)
- [x] [rand](https://crates.io/crates/rand)

Expand Down Expand Up @@ -139,32 +144,6 @@ static GLOBAL: Jemalloc = Jemalloc;

## Troubleshooting

### SSL Verification

You might need to point `openssl` at the location of your certificates **explicitly** to avoid certificate errors on https requests.

```sh
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
export SSL_CERT_DIR=/etc/ssl/certs
```

These can be [hardcoded in your Dockerfile](https://docs.docker.com/engine/reference/builder/#env), or you can rely on the [openssl-probe crate](https://crates.io/crates/openssl-probe) to detect the cert location. You should not have to do this if you are using the static variants of `distroless` or `chainguard`.

### Diesel and PQ builds

Works with the older version of libpq we bundle (see [#81](https://github.com/clux/muslrust/issues/81)). See the [test/dieselpgcrate](./test/dieselpgcrate) for specifics.

For stuff like `infer_schema!` to work you need to explicitly pass on `-e DATABASE_URL=$DATABASE_URL` to the `docker run`. It's probably easier to just make `diesel print-schema > src/schema.rs` part of your migration setup though.

Note that diesel compiles with `openssl` statically since `1.34.0`, so you need to include the `openssl` crate **before** `diesel` due to [pq-sys#25](https://github.com/sgrif/pq-sys/issues/25):

```rs
extern crate openssl;
#[macro_use] extern crate diesel;
```

This is true even if you connect without `sslmode=require`.

### Filesystem permissions on local builds

When building locally, the permissions of the musl parts of the `./target` artifacts dir will be owned by `root` and requires `sudo rm -rf target/` to clear. This is an [intended](https://github.com/clux/muslrust/issues/65) complexity tradeoff with user builds.
Expand Down
6 changes: 3 additions & 3 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ _ti crate:
just _t_{{ os() }}_{{ arch() }} {{crate}}

# when running locally we can use one of these instead of _t
_t_linux_amd64 crate:
_t_linux_x86_64 crate:
#!/bin/bash
export PLATFORM="linux/amd64"
export TARGET_DIR="x86_64-unknown-linux-musl"
Expand All @@ -46,9 +46,9 @@ _t_macos_aarch64 crate:
./test.sh {{crate}}

# Test all crates against built container locally
test: (_ti "plain") (_ti "ssl") (_ti "rustls") (_ti "pq") (_ti "serde") (_ti "zlib") (_ti "hyper") (_ti "dieselpg") (_ti "dieselsqlite")
test: (_ti "plain") (_ti "serde") (_ti "zlib") (_ti "hypertls") (_ti "dieselsqlite")
# Test all crates against built container in ci (inheriting set PLATFORM/TARGET_DIR/AR vars)
test-ci: (_t "plain") (_t "ssl") (_t "rustls") (_t "pq") (_t "serde") (_t "zlib") (_t "hyper") (_t "dieselpg") (_t "dieselsqlite")
test-ci: (_t "plain") (_t "serde") (_t "zlib") (_t "hypertls") (_t "dieselsqlite")

# Cleanup everything
clean: clean-docker clean-tests
Expand Down
8 changes: 0 additions & 8 deletions test/dieselpgcrate/Cargo.toml

This file was deleted.

52 changes: 0 additions & 52 deletions test/dieselpgcrate/src/main.rs

This file was deleted.

2 changes: 1 addition & 1 deletion test/dieselsqlitecrate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ name = "dieselsqlitecrate"
version = "0.1.0"

[dependencies]
diesel = { version = "2.1.*", features = ["sqlite"] }
diesel = { version = "2.2.*", features = ["sqlite"] }
Loading
Loading