Files
sexy/Dockerfile
Sebastian Krüger f880aa5957 feat: externalize buttplug as separate nginx container
- Add Dockerfile.buttplug: builds Rust/WASM + TS, serves via nginx
- Add nginx.buttplug.conf: serves /dist and /wasm with correct MIME types
- Add .gitea/workflows/docker-build-buttplug.yml: path-filtered CI workflow
- Strip Rust toolchain and buttplug build from frontend Dockerfile
- Move buttplug to devDependencies (types only at build time)
- Remove vite-plugin-wasm from frontend (WASM now served by nginx)
- Add /buttplug proxy in vite.config (dev: localhost:8080)
- Add buttplug service to compose.yml
- Load buttplug dynamically in play page via runtime import
- Fix faq page: suppress no-unnecessary-state-wrap for reassigned SvelteSet

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 13:49:38 +01:00

99 lines
3.2 KiB
Docker

# syntax=docker/dockerfile:1
# ============================================================================
# Base stage - shared dependencies
# ============================================================================
FROM node:22.11.0-slim AS base
# Enable corepack for pnpm
RUN npm install -g corepack@latest && corepack enable
# Set working directory
WORKDIR /app
# Copy workspace configuration
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
# Create env file with placeholder values so SvelteKit knows variable names at build time
# Actual values are injected at runtime via process.env (adapter-node)
RUN mkdir -p ./packages/frontend && \
printf 'PUBLIC_API_URL=\nPUBLIC_URL=\nPUBLIC_UMAMI_ID=\nPUBLIC_UMAMI_SCRIPT=\n' > ./packages/frontend/.env
# ============================================================================
# Builder stage - compile frontend
# ============================================================================
FROM base AS builder
ARG CI=false
ENV CI=$CI
# Copy source files
COPY packages ./packages
# Install all dependencies
RUN pnpm install --frozen-lockfile
# Build frontend
RUN pnpm --filter @sexy.pivoine.art/frontend build
# Prune dev dependencies for production
RUN CI=true pnpm install -rP
# ============================================================================
# Runner stage - minimal production image
# ============================================================================
FROM node:22.11.0-slim AS runner
# Install dumb-init for proper signal handling
RUN apt-get update && apt-get install -y \
dumb-init \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN userdel -r node && \
groupadd -r -g 1000 node && \
useradd -r -u 1000 -g node -m -d /home/node -s /bin/bash node
# Set working directory
WORKDIR /home/node/app
# Copy production dependencies and built artifacts from builder
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
COPY --from=builder --chown=node:node /app/package.json ./package.json
COPY --from=builder --chown=node:node /app/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=builder --chown=node:node /app/pnpm-workspace.yaml ./pnpm-workspace.yaml
# Create package directory
RUN mkdir -p packages/frontend
# Copy frontend artifacts
COPY --from=builder --chown=node:node /app/packages/frontend/build ./packages/frontend/build
COPY --from=builder --chown=node:node /app/packages/frontend/node_modules ./packages/frontend/node_modules
COPY --from=builder --chown=node:node /app/packages/frontend/package.json ./packages/frontend/package.json
# Switch to non-root user
USER node
# Environment variables (with defaults, override at runtime)
ENV NODE_ENV=production \
PORT=3000 \
HOST=0.0.0.0
# Runtime environment variables (will be passed at container start)
ENV PUBLIC_API_URL="" \
PUBLIC_URL="" \
PUBLIC_UMAMI_ID="" \
PUBLIC_UMAMI_SCRIPT=""
# Expose application port
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
# Use dumb-init to handle signals properly
ENTRYPOINT ["dumb-init", "--"]
# Start the application
CMD ["node", "packages/frontend/build/index.js"]