Files
meshstream/Dockerfile
Daniel Pupius 501a7be689 Use setarch --addr-no-randomize to fix esbuild crash in Docker
esbuild's Go binary crashes with lfstack.push on kernels with 5-level
paging or high-entropy ASLR (memory mapped above 47-bit addresses).
Disabling ASLR via the personality syscall for the build process keeps
allocations at low addresses without requiring host changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 03:34:28 +00:00

131 lines
3.8 KiB
Docker

# Multi-stage build for Meshstream
###############################################################################
# Stage 1: Build the web application
###############################################################################
FROM node:20-bookworm-slim AS web-builder
WORKDIR /app/web
# Install pnpm globally
RUN npm install -g pnpm@latest
# Copy web app package files
COPY web/package.json web/pnpm-lock.yaml ./
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy the rest of the web app source
COPY web/ ./
# Build-time environment variables for web app
ARG MESHSTREAM_API_BASE_URL=""
ARG MESHSTREAM_APP_ENV="production"
ARG MESHSTREAM_SITE_TITLE
ARG MESHSTREAM_SITE_DESCRIPTION
# Convert MESHSTREAM_ prefixed args to VITE_ environment variables for the web build
ENV VITE_API_BASE_URL=${MESHSTREAM_API_BASE_URL} \
VITE_APP_ENV=${MESHSTREAM_APP_ENV} \
VITE_SITE_TITLE=${MESHSTREAM_SITE_TITLE} \
VITE_SITE_DESCRIPTION=${MESHSTREAM_SITE_DESCRIPTION}
# esbuild's bundled Go binary crashes on kernels with 5-level paging or
# high-entropy ASLR because Go's lfstack can't handle addresses above 47 bits.
# setarch --addr-no-randomize disables ASLR for the process via the personality
# syscall, keeping allocations at low addresses. util-linux provides setarch.
RUN apt-get update && apt-get install -y --no-install-recommends util-linux \
&& rm -rf /var/lib/apt/lists/*
# Build the web app
RUN setarch "$(uname -m)" --addr-no-randomize pnpm build
###############################################################################
# Stage 2: Build the Go server
###############################################################################
FROM golang:1.25.5-alpine AS go-builder
WORKDIR /app
# Install required system dependencies
RUN apk add --no-cache git protobuf make
# Cache Go modules
COPY go.mod go.sum ./
RUN go mod download
# Copy proto files (needed for any proto generation)
COPY proto/ ./proto/
# Copy web build from previous stage
COPY --from=web-builder /app/web/dist ./dist/static
# Copy the rest of the app code
COPY . .
# Generate protocol buffer code in case it's needed
RUN make gen-proto
# Build the Go application
RUN CGO_ENABLED=0 GOOS=linux go build -o /meshstream
###############################################################################
# Stage 3: Final lightweight runtime image
###############################################################################
FROM alpine:3.19
WORKDIR /app
# Add basic runtime dependencies
RUN apk add --no-cache ca-certificates tzdata
# Create a non-root user to run the app
RUN addgroup -S meshstream && adduser -S meshstream -G meshstream
# Copy the binary from the build stage
COPY --from=go-builder /meshstream /app/meshstream
# Copy the static files
COPY --from=go-builder /app/dist/static /app/static
# Set ownership to the non-root user
RUN chown -R meshstream:meshstream /app
# Switch to the non-root user
USER meshstream
# Expose the application port
EXPOSE 5446
# Server configuration
ENV MESHSTREAM_SERVER_HOST=0.0.0.0
ENV MESHSTREAM_SERVER_PORT=5446
ENV MESHSTREAM_STATIC_DIR=/app/static
# Reporting configuration
ENV MESHSTREAM_STATS_INTERVAL=30s
ENV MESHSTREAM_CACHE_SIZE=1000
ENV MESHSTREAM_VERBOSE_LOGGING=false
# MQTT configuration
ENV MESHSTREAM_MQTT_BROKER=mqtt.bayme.sh
ENV MESHSTREAM_MQTT_USERNAME=meshdev
ENV MESHSTREAM_MQTT_PASSWORD=large4cats
ENV MESHSTREAM_MQTT_TOPIC_PREFIX=msh/US/bayarea
ENV MESHSTREAM_MQTT_CLIENT_ID=meshstream
ENV MESHSTREAM_CHANNEL_KEYS=""
# MQTT connection tuning parameters
ENV MESHSTREAM_MQTT_KEEPALIVE=60
ENV MESHSTREAM_MQTT_CONNECT_TIMEOUT=30s
ENV MESHSTREAM_MQTT_PING_TIMEOUT=10s
ENV MESHSTREAM_MQTT_MAX_RECONNECT=5m
ENV MESHSTREAM_MQTT_USE_TLS=false
ENV MESHSTREAM_MQTT_TLS_PORT=8883
# Note: Web app configuration is set at build time
# and baked into the static files
# Run the application
ENTRYPOINT ["/app/meshstream"]