134 lines
4.4 KiB
Docker
134 lines
4.4 KiB
Docker
# Alpine-based MUSL static binary builder for Ginxsom
|
|
# Produces truly portable binaries with zero runtime dependencies
|
|
|
|
ARG DEBUG_BUILD=false
|
|
|
|
FROM alpine:3.19 AS builder
|
|
|
|
# Re-declare build argument in this stage
|
|
ARG DEBUG_BUILD=false
|
|
|
|
# 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 \
|
|
fcgi-dev \
|
|
fcgi \
|
|
linux-headers \
|
|
wget \
|
|
bash \
|
|
nghttp2-dev \
|
|
nghttp2-static \
|
|
c-ares-dev \
|
|
c-ares-static \
|
|
libidn2-dev \
|
|
libidn2-static \
|
|
libunistring-dev \
|
|
libunistring-static \
|
|
libpsl-dev \
|
|
libpsl-static \
|
|
brotli-dev \
|
|
brotli-static
|
|
|
|
# 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
|
|
|
|
# Copy only submodule configuration and git directory
|
|
COPY .gitmodules /build/.gitmodules
|
|
COPY .git /build/.git
|
|
|
|
# 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), 042(Auth), 044(Encryption), 059(Gift Wrap)
|
|
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,42,44,59
|
|
|
|
# Copy web interface files for embedding
|
|
# Note: Changes to api/ files will trigger rebuild from this point
|
|
COPY api/ /build/api/
|
|
COPY scripts/embed_web_files.sh /build/scripts/
|
|
|
|
# Create src directory and embed web files into C headers
|
|
RUN mkdir -p src && \
|
|
chmod +x scripts/embed_web_files.sh && \
|
|
./scripts/embed_web_files.sh
|
|
|
|
# Copy Ginxsom source files LAST (only this layer rebuilds on source changes)
|
|
# Note: The embedded header from previous step will be overwritten by this COPY
|
|
# So we need to ensure src/admin_interface_embedded.h is NOT in src/ directory
|
|
COPY src/ /build/src/
|
|
COPY include/ /build/include/
|
|
|
|
# Build Ginxsom with full static linking (only rebuilds when src/ changes)
|
|
# Disable fortification to avoid __*_chk symbols that don't exist in MUSL
|
|
# Use conditional compilation flags based on DEBUG_BUILD argument
|
|
RUN if [ "$DEBUG_BUILD" = "true" ]; then \
|
|
CFLAGS="-g -O0 -DDEBUG"; \
|
|
STRIP_CMD=""; \
|
|
echo "Building with DEBUG symbols enabled"; \
|
|
else \
|
|
CFLAGS="-O2"; \
|
|
STRIP_CMD="strip /build/ginxsom-fcgi_static"; \
|
|
echo "Building optimized production binary"; \
|
|
fi && \
|
|
gcc -static $CFLAGS -Wall -Wextra -std=gnu99 \
|
|
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 \
|
|
-I. -Iinclude -Inostr_core_lib -Inostr_core_lib/nostr_core \
|
|
-Inostr_core_lib/cjson -Inostr_core_lib/nostr_websocket \
|
|
src/main.c src/admin_api.c src/admin_auth.c src/admin_event.c \
|
|
src/admin_handlers.c src/admin_interface.c src/admin_commands.c \
|
|
src/bud04.c src/bud06.c src/bud08.c src/bud09.c \
|
|
src/request_validator.c src/relay_client.c \
|
|
nostr_core_lib/nostr_core/core_relay_pool.c \
|
|
-o /build/ginxsom-fcgi_static \
|
|
nostr_core_lib/libnostr_core_x64.a \
|
|
-lfcgi -lsqlite3 -lsecp256k1 -lssl -lcrypto -lcurl \
|
|
-lnghttp2 -lcares -lidn2 -lunistring -lpsl -lbrotlidec -lbrotlicommon \
|
|
-lz -lpthread -lm -ldl && \
|
|
eval "$STRIP_CMD"
|
|
|
|
# Verify it's truly static
|
|
RUN echo "=== Binary Information ===" && \
|
|
file /build/ginxsom-fcgi_static && \
|
|
ls -lh /build/ginxsom-fcgi_static && \
|
|
echo "=== Checking for dynamic dependencies ===" && \
|
|
(ldd /build/ginxsom-fcgi_static 2>&1 || echo "Binary is static") && \
|
|
echo "=== Build complete ==="
|
|
|
|
# Output stage - just the binary
|
|
FROM scratch AS output
|
|
COPY --from=builder /build/ginxsom-fcgi_static /ginxsom-fcgi_static |