|
| 1 | +FROM ubuntu:jammy |
| 2 | +LABEL maintainer="Eirik Albrigtsen <sszynrae@gmail.com>" |
| 3 | + |
| 4 | +# Required packages: |
| 5 | +# - musl-dev, musl-tools - the musl toolchain |
| 6 | +# - curl, g++, make, pkgconf, cmake - for fetching and building third party libs |
| 7 | +# - ca-certificates - openssl + curl + peer verification of downloads |
| 8 | +# - xutils-dev - for openssl makedepend |
| 9 | +# - libssl-dev and libpq-dev - for dynamic linking during diesel_codegen build process |
| 10 | +# - git - cargo builds in user projects |
| 11 | +# - linux-headers-amd64 - needed for building openssl 1.1 (stretch only) |
| 12 | +# - file - needed by rustup.sh install |
| 13 | +# - automake autoconf libtool - support crates building C deps as part cargo build |
| 14 | +# NB: does not include cmake atm |
| 15 | +RUN apt-get update && apt-get install -y \ |
| 16 | + musl-dev \ |
| 17 | + musl-tools \ |
| 18 | + file \ |
| 19 | + git \ |
| 20 | + openssh-client \ |
| 21 | + make \ |
| 22 | + cmake \ |
| 23 | + g++ \ |
| 24 | + curl \ |
| 25 | + pkgconf \ |
| 26 | + ca-certificates \ |
| 27 | + xutils-dev \ |
| 28 | + libssl-dev \ |
| 29 | + libpq-dev \ |
| 30 | + automake \ |
| 31 | + autoconf \ |
| 32 | + libtool \ |
| 33 | + libprotobuf-dev \ |
| 34 | + unzip \ |
| 35 | + --no-install-recommends && \ |
| 36 | + rm -rf /var/lib/apt/lists/* |
| 37 | + |
| 38 | +# Install rust using rustup |
| 39 | +ARG CHANNEL |
| 40 | +ENV RUSTUP_VER="1.26.0" \ |
| 41 | + RUST_ARCH="aarch64-unknown-linux-gnu" \ |
| 42 | + CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse |
| 43 | + |
| 44 | +RUN curl "https://static.rust-lang.org/rustup/archive/${RUSTUP_VER}/${RUST_ARCH}/rustup-init" -o rustup-init && \ |
| 45 | + chmod +x rustup-init && \ |
| 46 | + ./rustup-init -y --default-toolchain ${CHANNEL} --profile minimal --no-modify-path && \ |
| 47 | + rm rustup-init && \ |
| 48 | + ~/.cargo/bin/rustup target add aarch64-unknown-linux-musl |
| 49 | + |
| 50 | +# Allow non-root access to cargo |
| 51 | +RUN chmod a+X /root |
| 52 | + |
| 53 | +# Convenience list of versions and variables for compilation later on |
| 54 | +# This helps continuing manually if anything breaks. |
| 55 | +ENV SSL_VER="1.1.1w" \ |
| 56 | + CURL_VER="8.6.0" \ |
| 57 | + ZLIB_VER="1.3.1" \ |
| 58 | + PQ_VER="11.12" \ |
| 59 | + SQLITE_VER="3450100" \ |
| 60 | + PROTOBUF_VER="25.2" \ |
| 61 | + CC=musl-gcc \ |
| 62 | + PREFIX=/musl \ |
| 63 | + PATH=/usr/local/bin:/root/.cargo/bin:$PATH \ |
| 64 | + PKG_CONFIG_PATH=/usr/local/lib/pkgconfig \ |
| 65 | + LD_LIBRARY_PATH=$PREFIX |
| 66 | + |
| 67 | +# Install a more recent release of protoc (protobuf-compiler in jammy is 4 years old and misses some features) |
| 68 | +RUN cd /tmp && \ |
| 69 | + curl -sSL https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VER}/protoc-${PROTOBUF_VER}-linux-aarch_64.zip -o protoc.zip && \ |
| 70 | + unzip protoc.zip && \ |
| 71 | + cp bin/protoc /usr/bin/protoc && \ |
| 72 | + rm -rf * |
| 73 | + |
| 74 | +# Set up a prefix for musl build libraries, make the linker's job of finding them easier |
| 75 | +# Primarily for the benefit of postgres. |
| 76 | +# Lastly, link some linux-headers for openssl 1.1 (not used herein) |
| 77 | +RUN mkdir $PREFIX && \ |
| 78 | + echo "$PREFIX/lib" >> /etc/ld-musl-aarch64.path && \ |
| 79 | + ln -s /usr/include/aarch64-linux-gnu/asm /usr/include/aarch64-linux-musl/asm && \ |
| 80 | + ln -s /usr/include/asm-generic /usr/include/aarch64-linux-musl/asm-generic && \ |
| 81 | + ln -s /usr/include/linux /usr/include/aarch64-linux-musl/linux |
| 82 | + |
| 83 | +# Build zlib (used in openssl and pq) |
| 84 | +RUN curl -sSL https://zlib.net/zlib-$ZLIB_VER.tar.gz | tar xz && \ |
| 85 | + cd zlib-$ZLIB_VER && \ |
| 86 | + CC="musl-gcc -fPIC -pie" LDFLAGS="-L$PREFIX/lib" CFLAGS="-I$PREFIX/include" ./configure --static --prefix=$PREFIX && \ |
| 87 | + make -j$(nproc) && make install && \ |
| 88 | + cd .. && rm -rf zlib-$ZLIB_VER |
| 89 | + |
| 90 | +# Build openssl (used in curl and pq) |
| 91 | +# Would like to use zlib here, but can't seem to get it to work properly |
| 92 | +# TODO: fix so that it works |
| 93 | +RUN curl -sSL https://www.openssl.org/source/openssl-$SSL_VER.tar.gz | tar xz && \ |
| 94 | + cd openssl-$SSL_VER && \ |
| 95 | + CFLAGS="-mno-outline-atomics" ./Configure no-zlib no-shared -fPIC --prefix=$PREFIX --openssldir=$PREFIX/ssl linux-aarch64 && \ |
| 96 | + env C_INCLUDE_PATH=$PREFIX/include make depend 2> /dev/null && \ |
| 97 | + make -j$(nproc) && make all install_sw && \ |
| 98 | + cd .. && rm -rf openssl-$SSL_VER |
| 99 | + |
| 100 | +# Build curl (needs with-zlib and all this stuff to allow https) |
| 101 | +# curl_LDFLAGS needed on stretch to avoid fPIC errors - though not sure from what |
| 102 | +RUN curl -sSL https://curl.se/download/curl-$CURL_VER.tar.gz | tar xz && \ |
| 103 | + cd curl-$CURL_VER && \ |
| 104 | + CC="musl-gcc -fPIC -pie" LDFLAGS="-L$PREFIX/lib" CFLAGS="-I$PREFIX/include" ./configure \ |
| 105 | + --enable-shared=no --with-zlib --enable-static=ssl --enable-optimize --prefix=$PREFIX \ |
| 106 | + --with-ca-path=/etc/ssl/certs/ --with-ca-bundle=/etc/ssl/certs/ca-certificates.crt --without-ca-fallback \ |
| 107 | + --with-openssl --without-libpsl && \ |
| 108 | + make -j$(nproc) curl_LDFLAGS="-all-static" && make install && \ |
| 109 | + cd .. && rm -rf curl-$CURL_VER |
| 110 | + |
| 111 | +# Build libpq |
| 112 | +RUN curl -sSL https://ftp.postgresql.org/pub/source/v$PQ_VER/postgresql-$PQ_VER.tar.gz | tar xz && \ |
| 113 | + cd postgresql-$PQ_VER && \ |
| 114 | + CC="musl-gcc -fPIE -pie" LDFLAGS="-L$PREFIX/lib" CFLAGS="-I$PREFIX/include" ./configure \ |
| 115 | + --without-readline \ |
| 116 | + --with-openssl \ |
| 117 | + --prefix=$PREFIX --host=x86_64-unknown-linux-musl && \ |
| 118 | + cd src/interfaces/libpq make -s -j$(nproc) all-static-lib && make -s install install-lib-static && \ |
| 119 | + cd ../../bin/pg_config && make -j $(nproc) && make install && \ |
| 120 | + cd .. && rm -rf postgresql-$PQ_VER |
| 121 | + |
| 122 | +# Build libsqlite3 using same configuration as the alpine linux main/sqlite package |
| 123 | +RUN curl -sSL https://www.sqlite.org/2024/sqlite-autoconf-$SQLITE_VER.tar.gz | tar xz && \ |
| 124 | + cd sqlite-autoconf-$SQLITE_VER && \ |
| 125 | + CFLAGS="-DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_SECURE_DELETE -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_ENABLE_RTREE -DSQLITE_USE_URI -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1" \ |
| 126 | + CC="musl-gcc -fPIC -pie" \ |
| 127 | + ./configure --prefix=$PREFIX --host=x86_64-unknown-linux-musl --enable-threadsafe --enable-dynamic-extensions --disable-shared && \ |
| 128 | + make && make install && \ |
| 129 | + cd .. && rm -rf sqlite-autoconf-$SQLITE_VER |
| 130 | + |
| 131 | +# SSL cert directories get overridden by --prefix and --openssldir |
| 132 | +# and they do not match the typical host configurations. |
| 133 | +# The SSL_CERT_* vars fix this, but only when inside this container |
| 134 | +# musl-compiled binary must point SSL at the correct certs (muslrust/issues/5) elsewhere |
| 135 | +# Postgres bindings need vars so that diesel_codegen.so uses the GNU deps at build time |
| 136 | +# but finally links with the static libpq.a at the end. |
| 137 | +# It needs the non-musl pg_config to set this up with libpq-dev (depending on libssl-dev) |
| 138 | +# See https://github.com/sgrif/pq-sys/pull/18 |
| 139 | +ENV PATH=/root/.cargo/bin:$PREFIX/bin:$PATH \ |
| 140 | + RUSTUP_HOME=/root/.rustup \ |
| 141 | + CARGO_BUILD_TARGET=aarch64-unknown-linux-musl \ |
| 142 | + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-Clink-self-contained=yes -Clinker=rust-lld -Ctarget-feature=+crt-static" \ |
| 143 | + PKG_CONFIG_ALLOW_CROSS=true \ |
| 144 | + PKG_CONFIG_ALL_STATIC=true \ |
| 145 | + PQ_LIB_STATIC_AARCH64_UNKNOWN_LINUX_MUSL=true \ |
| 146 | + PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig \ |
| 147 | + PG_CONFIG_AARCH64_UNKNOWN_LINUX_GNU=/usr/bin/pg_config \ |
| 148 | + OPENSSL_STATIC=true \ |
| 149 | + OPENSSL_DIR=$PREFIX \ |
| 150 | + SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \ |
| 151 | + SSL_CERT_DIR=/etc/ssl/certs \ |
| 152 | + LIBZ_SYS_STATIC=1 \ |
| 153 | + DEBIAN_FRONTEND=noninteractive \ |
| 154 | + TZ=Etc/UTC |
| 155 | + |
| 156 | +# Allow ditching the -w /volume flag to docker run |
| 157 | +WORKDIR /volume |
0 commit comments