Add Alpine Linux build system

Add Dockerfiles for building curl-impersonate on Alpine Linux.

The Dockerfile template file was modified to support Alpine Linux,
mainly by changing the dependency installation from 'apt' to 'apk'.
The resulting alpine images are small (~11mb) and will be uploaded to
Docker hub.
This commit is contained in:
lwthiker 2022-03-10 11:57:53 +02:00
parent 91c906febd
commit eaeb619fa7
6 changed files with 345 additions and 18 deletions

View File

@ -5,36 +5,65 @@
# PLEASE DO NOT EDIT IT DIRECTLY.
#
{{#debian}}
# Python is needed for building libnss.
# Use it as a common base.
FROM python:3.10.1-slim-buster
{{/debian}}
{{#alpine}}
FROM alpine:3.15.0 as builder
{{/alpine}}
WORKDIR /build
# Common dependencies
{{#debian}}
RUN apt-get update && \
apt-get install -y git ninja-build cmake curl zlib1g-dev
{{/debian}}
{{#alpine}}
RUN apk add git build-base make cmake ninja curl zlib-dev patch linux-headers python3 python3-dev
{{/alpine}}
# The following are needed because we are going to change some autoconf scripts,
# both for libnghttp2 and curl.
{{#debian}}
RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool
{{/debian}}
{{#alpine}}
RUN apk add autoconf automake pkgconfig libtool
{{/alpine}}
{{#firefox}}
# Dependencies for building libnss
# See https://firefox-source-docs.mozilla.org/security/nss/build.html#mozilla-projects-nss-building
{{#debian}}
RUN apt-get install -y mercurial python3-pip
{{/debian}}
{{#alpine}}
RUN apk add mercurial py3-pip clang-analyzer
{{/alpine}}
# curl tries to load the CA certificates for libnss.
# It loads them from /usr/lib/x86_64-linux-gnu/nss/libnssckbi.so,
# which is supplied by libnss3 on Debian/Ubuntu
{{#debian}}
RUN apt-get install -y libnss3
{{/debian}}
{{#alpine}}
RUN apk add nss
{{/alpine}}
{{/firefox}}
{{#chrome}}
# Dependencies for downloading and building BoringSSL
{{#debian}}
RUN apt-get install -y g++ golang-go unzip
{{/debian}}
{{#alpine}}
RUN apk add g++ go unzip
{{/alpine}}
{{/chrome}}
# The following are needed because we are going to change some autoconf scripts,
# both for libnghttp2 and curl.
RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool
# Download and compile libbrotli
ARG BROTLI_VERSION=1.0.9
RUN curl -L https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz -o brotli-${BROTLI_VERSION}.tar.gz && \
@ -56,9 +85,12 @@ ARG NSS_URL=https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_74_RTM/src/n
RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL}
RUN tar xf ${NSS_VERSION}.tar.gz && \
cd ${NSS_VERSION}/nss && \
{{#alpine}}
# Hack to make nss compile on alpine with python3
ln -sf python3 /usr/bin/python && \
{{/alpine}}
./build.sh -o --disable-tests --static
{{/firefox}}
{{#chrome}}
# BoringSSL doesn't have versions. Choose a commit that is used in a stable
# Chromium version.
@ -168,4 +200,22 @@ COPY curl_ff* out/
{{#chrome}}
COPY curl_chrome* curl_edge* curl_safari* out/
{{/chrome}}
{{#alpine}}
# Replace /bin/bash with /bin/ash
RUN sed -i 's@/bin/bash@/bin/ash@' out/curl_*
{{/alpine}}
RUN chmod +x out/curl_*
{{#alpine}}
# When using alpine, create a final, minimal image with the compiled binaries
# only.
FROM alpine:3.15.0
# Copy curl-impersonate from the builder image
COPY --from=builder /build/out/curl-impersonate /usr/local/bin/
# Wrapper scripts
COPY --from=builder /build/out/curl_* /usr/local/bin/
# Copy libcurl-impersonate from the builder image
COPY --from=builder /build/out/libcurl-impersonate.so /usr/local/lib/
{{/alpine}}

View File

@ -15,14 +15,13 @@ WORKDIR /build
RUN apt-get update && \
apt-get install -y git ninja-build cmake curl zlib1g-dev
# Dependencies for downloading and building BoringSSL
RUN apt-get install -y g++ golang-go unzip
# The following are needed because we are going to change some autoconf scripts,
# both for libnghttp2 and curl.
RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool
# Dependencies for downloading and building BoringSSL
RUN apt-get install -y g++ golang-go unzip
# Download and compile libbrotli
ARG BROTLI_VERSION=1.0.9
RUN curl -L https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz -o brotli-${BROTLI_VERSION}.tar.gz && \
@ -32,7 +31,6 @@ RUN cd brotli-${BROTLI_VERSION} && \
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./installed .. && \
cmake --build . --config Release --target install
# BoringSSL doesn't have versions. Choose a commit that is used in a stable
# Chromium version.
ARG BORING_SSL_COMMIT=3a667d10e94186fd503966f5638e134fe9fb4080
@ -50,7 +48,7 @@ RUN cd boringssl && \
ninja
# Fix the directory structure so that curl can compile against it.
# See https://everything.curl.dev/source/build/tls/boringssl
# See https://everything.curl.dev/source/build/tls/boringssl
RUN mkdir boringssl/build/lib && \
ln -s ../crypto/libcrypto.a boringssl/build/lib/libcrypto.a && \
ln -s ../ssl/libssl.a boringssl/build/lib/libssl.a && \

135
chrome/Dockerfile.alpine Normal file
View File

@ -0,0 +1,135 @@
#
# NOTE: THIS DOCKERFILE IS GENERATED FROM "Dockerfile.template" VIA
# "generate-dockerfiles.sh".
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM alpine:3.15.0 as builder
WORKDIR /build
# Common dependencies
RUN apk add git build-base make cmake ninja curl zlib-dev patch linux-headers python3 python3-dev
# The following are needed because we are going to change some autoconf scripts,
# both for libnghttp2 and curl.
RUN apk add autoconf automake pkgconfig libtool
# Dependencies for downloading and building BoringSSL
RUN apk add g++ go unzip
# Download and compile libbrotli
ARG BROTLI_VERSION=1.0.9
RUN curl -L https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz -o brotli-${BROTLI_VERSION}.tar.gz && \
tar xf brotli-${BROTLI_VERSION}.tar.gz
RUN cd brotli-${BROTLI_VERSION} && \
mkdir build && cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./installed .. && \
cmake --build . --config Release --target install
# BoringSSL doesn't have versions. Choose a commit that is used in a stable
# Chromium version.
ARG BORING_SSL_COMMIT=3a667d10e94186fd503966f5638e134fe9fb4080
RUN curl -L https://github.com/google/boringssl/archive/${BORING_SSL_COMMIT}.zip -o boringssl.zip && \
unzip boringssl && \
mv boringssl-${BORING_SSL_COMMIT} boringssl
# Compile BoringSSL.
# See https://boringssl.googlesource.com/boringssl/+/HEAD/BUILDING.md
COPY patches/boringssl-*.patch boringssl/
RUN cd boringssl && \
for p in $(ls boringssl-*.patch); do patch -p1 < $p; done && \
mkdir build && cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=on -GNinja .. && \
ninja
# Fix the directory structure so that curl can compile against it.
# See https://everything.curl.dev/source/build/tls/boringssl
RUN mkdir boringssl/build/lib && \
ln -s ../crypto/libcrypto.a boringssl/build/lib/libcrypto.a && \
ln -s ../ssl/libssl.a boringssl/build/lib/libssl.a && \
cp -R boringssl/include boringssl/build
ARG NGHTTP2_VERSION=nghttp2-1.46.0
ARG NGHTTP2_URL=https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2
# Download nghttp2 for HTTP/2.0 support.
RUN curl -o ${NGHTTP2_VERSION}.tar.bz2 -L ${NGHTTP2_URL}
RUN tar xf ${NGHTTP2_VERSION}.tar.bz2
# Patch nghttp2 pkg config file to support static builds.
COPY patches/libnghttp2-*.patch ${NGHTTP2_VERSION}/
RUN cd ${NGHTTP2_VERSION} && \
for p in $(ls libnghttp2-*.patch); do patch -p1 < $p; done && \
autoreconf -i && automake && autoconf
# Compile nghttp2
RUN cd ${NGHTTP2_VERSION} && \
./configure --with-pic && \
make && make install
# Download curl.
ARG CURL_VERSION=curl-7.81.0
RUN curl -o ${CURL_VERSION}.tar.xz https://curl.se/download/${CURL_VERSION}.tar.xz
RUN tar xf ${CURL_VERSION}.tar.xz
# Patch curl and re-generate the configure script
COPY patches/curl-*.patch ${CURL_VERSION}/
RUN cd ${CURL_VERSION} && \
for p in $(ls curl-*.patch); do patch -p1 < $p; done && \
autoreconf -fi
# Compile curl with nghttp2, libbrotli and nss (firefox) or boringssl (chrome).
# Enable keylogfile for debugging of TLS traffic.
RUN cd ${CURL_VERSION} && \
./configure --enable-static \
--disable-shared \
--with-nghttp2=/usr/local \
--with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \
--with-openssl=/build/boringssl/build \
LIBS="-pthread" \
CFLAGS="-I/build/boringssl/build" \
USE_CURL_SSLKEYLOGFILE=true && \
make
RUN mkdir out && \
cp ${CURL_VERSION}/src/curl out/curl-impersonate && \
strip out/curl-impersonate
# Re-compile libcurl dynamically
RUN cd ${CURL_VERSION} && \
./configure --with-nghttp2=/usr/local \
--with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \
--with-openssl=/build/boringssl/build \
LIBS="-pthread" \
CFLAGS="-I/build/boringssl/build" \
USE_CURL_SSLKEYLOGFILE=true && \
make clean && make
# Rename to 'libcurl-impersonate' to avoid confusion, and recreate the
# symbolic links.
RUN ver=$(readlink -f curl-7.81.0/lib/.libs/libcurl.so | sed 's/.*so\.//') && \
major=$(echo -n $ver | cut -d'.' -f1) && \
cp "${CURL_VERSION}/lib/.libs/libcurl.so.$ver" "out/libcurl-impersonate.so.$ver" && \
ln -s "libcurl-impersonate.so.$ver" "out/libcurl-impersonate.so.$major" && \
ln -s "libcurl-impersonate.so.$ver" "out/libcurl-impersonate.so" && \
strip "out/libcurl-impersonate.so.$ver"
# Wrapper scripts
COPY curl_chrome* curl_edge* curl_safari* out/
# Replace /bin/bash with /bin/ash
RUN sed -i 's@/bin/bash@/bin/ash@' out/curl_*
RUN chmod +x out/curl_*
# When using alpine, create a final, minimal image with the compiled binaries
# only.
FROM alpine:3.15.0
# Copy curl-impersonate from the builder image
COPY --from=builder /build/out/curl-impersonate /usr/local/bin/
# Wrapper scripts
COPY --from=builder /build/out/curl_* /usr/local/bin/
# Copy libcurl-impersonate from the builder image
COPY --from=builder /build/out/libcurl-impersonate.so /usr/local/lib/

View File

@ -15,6 +15,10 @@ WORKDIR /build
RUN apt-get update && \
apt-get install -y git ninja-build cmake curl zlib1g-dev
# The following are needed because we are going to change some autoconf scripts,
# both for libnghttp2 and curl.
RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool
# Dependencies for building libnss
# See https://firefox-source-docs.mozilla.org/security/nss/build.html#mozilla-projects-nss-building
RUN apt-get install -y mercurial python3-pip
@ -24,11 +28,6 @@ RUN apt-get install -y mercurial python3-pip
# which is supplied by libnss3 on Debian/Ubuntu
RUN apt-get install -y libnss3
# The following are needed because we are going to change some autoconf scripts,
# both for libnghttp2 and curl.
RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool
# Download and compile libbrotli
ARG BROTLI_VERSION=1.0.9
RUN curl -L https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz -o brotli-${BROTLI_VERSION}.tar.gz && \
@ -51,7 +50,6 @@ RUN tar xf ${NSS_VERSION}.tar.gz && \
cd ${NSS_VERSION}/nss && \
./build.sh -o --disable-tests --static
ARG NGHTTP2_VERSION=nghttp2-1.46.0
ARG NGHTTP2_URL=https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2

131
firefox/Dockerfile.alpine Normal file
View File

@ -0,0 +1,131 @@
#
# NOTE: THIS DOCKERFILE IS GENERATED FROM "Dockerfile.template" VIA
# "generate-dockerfiles.sh".
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM alpine:3.15.0 as builder
WORKDIR /build
# Common dependencies
RUN apk add git build-base make cmake ninja curl zlib-dev patch linux-headers python3 python3-dev
# The following are needed because we are going to change some autoconf scripts,
# both for libnghttp2 and curl.
RUN apk add autoconf automake pkgconfig libtool
# Dependencies for building libnss
# See https://firefox-source-docs.mozilla.org/security/nss/build.html#mozilla-projects-nss-building
RUN apk add mercurial py3-pip clang-analyzer
# curl tries to load the CA certificates for libnss.
# It loads them from /usr/lib/x86_64-linux-gnu/nss/libnssckbi.so,
# which is supplied by libnss3 on Debian/Ubuntu
RUN apk add nss
# Download and compile libbrotli
ARG BROTLI_VERSION=1.0.9
RUN curl -L https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz -o brotli-${BROTLI_VERSION}.tar.gz && \
tar xf brotli-${BROTLI_VERSION}.tar.gz
RUN cd brotli-${BROTLI_VERSION} && \
mkdir build && cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./installed .. && \
cmake --build . --config Release --target install
# Needed for building libnss
RUN pip install gyp-next
ARG NSS_VERSION=nss-3.74
# This tarball is already bundled with nspr, a dependency of libnss.
ARG NSS_URL=https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_74_RTM/src/nss-3.74-with-nspr-4.32.tar.gz
# Download and compile nss.
RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL}
RUN tar xf ${NSS_VERSION}.tar.gz && \
cd ${NSS_VERSION}/nss && \
# Hack to make nss compile on alpine with python3
ln -sf python3 /usr/bin/python && \
./build.sh -o --disable-tests --static
ARG NGHTTP2_VERSION=nghttp2-1.46.0
ARG NGHTTP2_URL=https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2
# Download nghttp2 for HTTP/2.0 support.
RUN curl -o ${NGHTTP2_VERSION}.tar.bz2 -L ${NGHTTP2_URL}
RUN tar xf ${NGHTTP2_VERSION}.tar.bz2
# Patch nghttp2 pkg config file to support static builds.
COPY patches/libnghttp2-*.patch ${NGHTTP2_VERSION}/
RUN cd ${NGHTTP2_VERSION} && \
for p in $(ls libnghttp2-*.patch); do patch -p1 < $p; done && \
autoreconf -i && automake && autoconf
# Compile nghttp2
RUN cd ${NGHTTP2_VERSION} && \
./configure --with-pic && \
make && make install
# Download curl.
ARG CURL_VERSION=curl-7.81.0
RUN curl -o ${CURL_VERSION}.tar.xz https://curl.se/download/${CURL_VERSION}.tar.xz
RUN tar xf ${CURL_VERSION}.tar.xz
# Patch curl and re-generate the configure script
COPY patches/curl-*.patch ${CURL_VERSION}/
RUN cd ${CURL_VERSION} && \
for p in $(ls curl-*.patch); do patch -p1 < $p; done && \
autoreconf -fi
# Compile curl with nghttp2, libbrotli and nss (firefox) or boringssl (chrome).
# Enable keylogfile for debugging of TLS traffic.
RUN cd ${CURL_VERSION} && \
./configure --enable-static \
--disable-shared \
--with-nghttp2=/usr/local \
--with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \
--with-nss=/build/${NSS_VERSION}/dist/Release \
CFLAGS="-I/build/${NSS_VERSION}/dist/public/nss -I/build/${NSS_VERSION}/dist/Release/include/nspr" \
USE_CURL_SSLKEYLOGFILE=true && \
make
RUN mkdir out && \
cp ${CURL_VERSION}/src/curl out/curl-impersonate && \
strip out/curl-impersonate
# Re-compile libcurl dynamically
RUN cd ${CURL_VERSION} && \
./configure --with-nghttp2=/usr/local \
--with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \
--with-nss=/build/${NSS_VERSION}/dist/Release \
CFLAGS="-I/build/${NSS_VERSION}/dist/public/nss -I/build/${NSS_VERSION}/dist/Release/include/nspr" \
USE_CURL_SSLKEYLOGFILE=true && \
make clean && make
# Rename to 'libcurl-impersonate' to avoid confusion, and recreate the
# symbolic links.
RUN ver=$(readlink -f curl-7.81.0/lib/.libs/libcurl.so | sed 's/.*so\.//') && \
major=$(echo -n $ver | cut -d'.' -f1) && \
cp "${CURL_VERSION}/lib/.libs/libcurl.so.$ver" "out/libcurl-impersonate.so.$ver" && \
ln -s "libcurl-impersonate.so.$ver" "out/libcurl-impersonate.so.$major" && \
ln -s "libcurl-impersonate.so.$ver" "out/libcurl-impersonate.so" && \
strip "out/libcurl-impersonate.so.$ver"
# Wrapper scripts
COPY curl_ff* out/
# Replace /bin/bash with /bin/ash
RUN sed -i 's@/bin/bash@/bin/ash@' out/curl_*
RUN chmod +x out/curl_*
# When using alpine, create a final, minimal image with the compiled binaries
# only.
FROM alpine:3.15.0
# Copy curl-impersonate from the builder image
COPY --from=builder /build/out/curl-impersonate /usr/local/bin/
# Wrapper scripts
COPY --from=builder /build/out/curl_* /usr/local/bin/
# Copy libcurl-impersonate from the builder image
COPY --from=builder /build/out/libcurl-impersonate.so /usr/local/lib/

View File

@ -3,11 +3,26 @@
cat <<EOF | mustache - Dockerfile.template > chrome/Dockerfile
---
chrome: true
debian: true
---
EOF
cat <<EOF | mustache - Dockerfile.template > chrome/Dockerfile.alpine
---
chrome: true
alpine: true
---
EOF
cat <<EOF | mustache - Dockerfile.template > firefox/Dockerfile
---
firefox: true
debian: true
---
EOF
cat <<EOF | mustache - Dockerfile.template > firefox/Dockerfile.alpine
---
firefox: true
alpine: true
---
EOF