- Restructure Dockerfile.alpine-musl for better layer caching * Build dependencies (secp256k1, libwebsockets) in separate cached layers * Copy submodules before source files to maximize cache hits * Reduce rebuild time from ~2-3 minutes to ~10-15 seconds for source changes - Remove 'musl' from binary names (c_relay_static_x86_64 instead of c_relay_static_musl_x86_64) - Enforce static binary usage in make_and_restart_relay.sh * Remove all fallbacks to regular make builds * Exit with clear error if static binary not found * Ensures JSON1 extension is always available - Fix build_static.sh hanging on ldd check with timeout - Remove sudo usage from build_static.sh (assumes docker group membership) These changes ensure consistent builds with JSON1 support and dramatically improve development iteration speed through intelligent Docker layer caching.
119 lines
4.0 KiB
Docker
119 lines
4.0 KiB
Docker
# Alpine-based MUSL static binary builder for C-Relay
|
|
# Produces truly portable binaries with zero runtime dependencies
|
|
|
|
FROM alpine:3.19 AS builder
|
|
|
|
# Install build dependencies
|
|
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 \
|
|
wget \
|
|
bash
|
|
|
|
# Set working directory
|
|
WORKDIR /build
|
|
|
|
# Build libsecp256k1 static (cached layer - only rebuilds if Alpine version changes)
|
|
RUN cd /tmp && \
|
|
git clone https://github.com/bitcoin-core/secp256k1.git && \
|
|
cd secp256k1 && \
|
|
./autogen.sh && \
|
|
./configure --enable-static --disable-shared --prefix=/usr \
|
|
CFLAGS="-fPIC" && \
|
|
make -j$(nproc) && \
|
|
make install && \
|
|
rm -rf /tmp/secp256k1
|
|
|
|
# Build libwebsockets static with minimal features (cached layer)
|
|
RUN cd /tmp && \
|
|
git clone --depth 1 --branch v4.3.3 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_WITHOUT_TESTAPPS=ON \
|
|
-DLWS_WITHOUT_TEST_SERVER=ON \
|
|
-DLWS_WITHOUT_TEST_CLIENT=ON \
|
|
-DLWS_WITHOUT_TEST_PING=ON \
|
|
-DLWS_WITH_HTTP2=OFF \
|
|
-DLWS_WITH_LIBUV=OFF \
|
|
-DLWS_WITH_LIBEVENT=OFF \
|
|
-DLWS_IPV6=ON \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_INSTALL_PREFIX=/usr \
|
|
-DCMAKE_C_FLAGS="-fPIC" && \
|
|
make -j$(nproc) && \
|
|
make install && \
|
|
rm -rf /tmp/libwebsockets
|
|
|
|
# Copy only submodule configuration and git directory
|
|
COPY .gitmodules /build/.gitmodules
|
|
COPY .git /build/.git
|
|
|
|
# Clean up any stale submodule references (nips directory is not a submodule)
|
|
RUN git rm --cached nips 2>/dev/null || true
|
|
|
|
# Initialize submodules (cached unless .gitmodules changes)
|
|
RUN git submodule update --init --recursive
|
|
|
|
# Copy nostr_core_lib source files (cached unless nostr_core_lib changes)
|
|
COPY nostr_core_lib /build/nostr_core_lib/
|
|
|
|
# Build nostr_core_lib with required NIPs (cached unless nostr_core_lib changes)
|
|
# Disable fortification in build.sh to prevent __*_chk symbol issues
|
|
# NIPs: 001(Basic), 006(Keys), 013(PoW), 017(DMs), 019(Bech32), 044(Encryption), 059(Gift Wrap - required by NIP-17)
|
|
RUN cd nostr_core_lib && \
|
|
chmod +x build.sh && \
|
|
sed -i 's/CFLAGS="-Wall -Wextra -std=c99 -fPIC -O2"/CFLAGS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -Wall -Wextra -std=c99 -fPIC -O2"/' build.sh && \
|
|
rm -f *.o *.a 2>/dev/null || true && \
|
|
./build.sh --nips=1,6,13,17,19,44,59
|
|
|
|
# Copy c-relay source files LAST (only this layer rebuilds on source changes)
|
|
COPY src/ /build/src/
|
|
COPY Makefile /build/Makefile
|
|
|
|
# Build c-relay with full static linking (only rebuilds when src/ changes)
|
|
# Disable fortification to avoid __*_chk symbols that don't exist in MUSL
|
|
RUN gcc -static -O2 -Wall -Wextra -std=c99 \
|
|
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 \
|
|
-I. -Inostr_core_lib -Inostr_core_lib/nostr_core \
|
|
-Inostr_core_lib/cjson -Inostr_core_lib/nostr_websocket \
|
|
src/main.c src/config.c src/dm_admin.c src/request_validator.c \
|
|
src/nip009.c src/nip011.c src/nip013.c src/nip040.c src/nip042.c \
|
|
src/websockets.c src/subscriptions.c src/api.c src/embedded_web_content.c \
|
|
-o /build/c_relay_static \
|
|
nostr_core_lib/libnostr_core_x64.a \
|
|
-lwebsockets -lssl -lcrypto -lsqlite3 -lsecp256k1 \
|
|
-lcurl -lz -lpthread -lm -ldl
|
|
|
|
# Strip binary to reduce size
|
|
RUN strip /build/c_relay_static
|
|
|
|
# Verify it's truly static
|
|
RUN echo "=== Binary Information ===" && \
|
|
file /build/c_relay_static && \
|
|
ls -lh /build/c_relay_static && \
|
|
echo "=== Checking for dynamic dependencies ===" && \
|
|
(ldd /build/c_relay_static 2>&1 || echo "Binary is static") && \
|
|
echo "=== Build complete ==="
|
|
|
|
# Output stage - just the binary
|
|
FROM scratch AS output
|
|
COPY --from=builder /build/c_relay_static /c_relay_static |