# MUSL-based fully static C-Relay builder # Produces portable binaries with zero runtime dependencies FROM alpine:latest AS builder # Add alternative mirrors and install build dependencies with retry RUN echo "http://dl-cdn.alpinelinux.org/alpine/v3.22/main" > /etc/apk/repositories && \ echo "http://dl-cdn.alpinelinux.org/alpine/v3.22/community" >> /etc/apk/repositories && \ echo "http://mirror.leaseweb.com/alpine/v3.22/main" >> /etc/apk/repositories && \ echo "http://mirror.leaseweb.com/alpine/v3.22/community" >> /etc/apk/repositories && \ apk update --no-cache || (sleep 5 && apk update --no-cache) || (sleep 10 && apk update --no-cache) # Install build dependencies with retry logic RUN apk add --no-cache \ build-base \ musl-dev \ git \ cmake \ pkgconfig \ autoconf \ automake \ libtool \ openssl-dev \ openssl-libs-static \ zlib-dev \ zlib-static \ curl-dev \ curl-static \ sqlite-dev \ sqlite-static \ linux-headers || \ (sleep 10 && apk add --no-cache \ build-base \ musl-dev \ git \ cmake \ pkgconfig \ autoconf \ automake \ libtool \ openssl-dev \ openssl-libs-static \ zlib-dev \ zlib-static \ curl-dev \ curl-static \ sqlite-dev \ sqlite-static \ linux-headers) # Set working directory WORKDIR /build # Build zlib static (if needed) RUN if [ ! -f /usr/lib/libz.a ]; then \ cd /tmp && \ wget https://zlib.net/zlib-1.3.1.tar.gz && \ tar xzf zlib-1.3.1.tar.gz && \ cd zlib-1.3.1 && \ ./configure --static --prefix=/usr && \ make && make install; \ fi # Build OpenSSL static RUN cd /tmp && \ wget https://www.openssl.org/source/openssl-3.0.13.tar.gz && \ tar xzf openssl-3.0.13.tar.gz && \ cd openssl-3.0.13 && \ ./Configure linux-x86_64 no-shared --prefix=/usr && \ make && make install_sw # Build libsecp256k1 static RUN cd /tmp && \ git clone https://github.com/bitcoin-core/secp256k1.git && \ cd secp256k1 && \ ./autogen.sh && \ ./configure --enable-static --disable-shared --prefix=/usr && \ make && make install # Build libwebsockets static with OpenSSL RUN cd /tmp && \ git clone https://github.com/warmcat/libwebsockets.git && \ cd libwebsockets && \ mkdir build && cd build && \ cmake .. \ -DLWS_WITH_STATIC=ON \ -DLWS_WITH_SHARED=OFF \ -DLWS_WITH_SSL=ON \ -DLWS_OPENSSL_LIBRARIES="/usr/lib/libssl.a;/usr/lib/libcrypto.a" \ -DLWS_OPENSSL_INCLUDE_DIRS="/usr/include" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr && \ make && make install # Build curl static (minimal features) RUN cd /tmp && \ wget https://curl.se/download/curl-8.6.0.tar.gz && \ tar xzf curl-8.6.0.tar.gz && \ cd curl-8.6.0 && \ ./configure \ --disable-shared \ --enable-static \ --disable-ldap \ --without-libidn2 \ --without-brotli \ --without-zstd \ --without-rtmp \ --without-libpsl \ --without-krb5 \ --with-openssl \ --prefix=/usr && \ make && make install # Copy c-relay source COPY . /build/ # Initialize submodules RUN git submodule update --init --recursive # Build nostr_core_lib RUN cd nostr_core_lib && ./build.sh # Build c-relay static RUN make clean && \ CC="musl-gcc -static" \ CFLAGS="-O2 -Wall -Wextra -std=c99 -g" \ LDFLAGS="-static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive" \ LIBS="-lsqlite3 -lwebsockets -lz -ldl -lpthread -lm -lsecp256k1 -lssl -lcrypto -lcurl" \ make # Strip binary for size RUN strip build/c_relay_x86 # Multi-stage build to produce minimal output FROM scratch AS output COPY --from=builder /build/build/c_relay_x86 /c_relay_static_musl_x86_64