feat: docker
This commit is contained in:
135
Dockerfile
Normal file
135
Dockerfile
Normal file
@@ -0,0 +1,135 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# ============================================================================
|
||||
# Base stage - shared dependencies
|
||||
# ============================================================================
|
||||
FROM node:20.19.1-slim AS base
|
||||
|
||||
# Enable corepack for pnpm
|
||||
RUN corepack enable
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy workspace configuration
|
||||
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
|
||||
|
||||
# ============================================================================
|
||||
# Builder stage - compile application with Rust/WASM support
|
||||
# ============================================================================
|
||||
FROM base AS builder
|
||||
|
||||
# Install build dependencies for Rust and native modules
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
build-essential \
|
||||
pkg-config \
|
||||
libssl-dev \
|
||||
ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Rust toolchain
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
|
||||
--default-toolchain stable \
|
||||
--profile minimal \
|
||||
--target wasm32-unknown-unknown
|
||||
|
||||
# Add Rust to PATH
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
|
||||
# Install wasm-bindgen-cli
|
||||
RUN cargo install wasm-bindgen-cli
|
||||
|
||||
# Copy source files
|
||||
COPY packages ./packages
|
||||
|
||||
# Install all dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build packages in correct order with WASM support
|
||||
# 1. Build buttplug WASM
|
||||
RUN RUSTFLAGS='--cfg getrandom_backend="wasm_js" --cfg=web_sys_unstable_apis' \
|
||||
pnpm --filter @sexy.pivoine.art/buttplug build:wasm
|
||||
|
||||
# 2. Build buttplug TypeScript
|
||||
RUN pnpm --filter @sexy.pivoine.art/buttplug build
|
||||
|
||||
# 3. Build frontend
|
||||
RUN pnpm --filter @sexy.pivoine.art/frontend build
|
||||
|
||||
# 4. Build Directus bundle
|
||||
RUN pnpm --filter @sexy.pivoine.art/bundle build
|
||||
|
||||
# Prune dev dependencies for production
|
||||
RUN pnpm install --prod --frozen-lockfile
|
||||
|
||||
# ============================================================================
|
||||
# Runner stage - minimal production image
|
||||
# ============================================================================
|
||||
FROM node:20.19.1-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 directories
|
||||
RUN mkdir -p packages/frontend packages/bundle packages/buttplug
|
||||
|
||||
# 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
|
||||
|
||||
# Copy bundle artifacts
|
||||
COPY --from=builder --chown=node:node /app/packages/bundle/dist ./packages/bundle/dist
|
||||
COPY --from=builder --chown=node:node /app/packages/bundle/node_modules ./packages/bundle/node_modules
|
||||
COPY --from=builder --chown=node:node /app/packages/bundle/package.json ./packages/bundle/package.json
|
||||
|
||||
# Copy buttplug artifacts
|
||||
COPY --from=builder --chown=node:node /app/packages/buttplug/dist ./packages/buttplug/dist
|
||||
COPY --from=builder --chown=node:node /app/packages/buttplug/node_modules ./packages/buttplug/node_modules
|
||||
COPY --from=builder --chown=node:node /app/packages/buttplug/package.json ./packages/buttplug/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="" \
|
||||
LETTERSPACE_API_URL="" \
|
||||
LETTERSPACE_API_KEY="" \
|
||||
LETTERSPACE_LIST_ID=""
|
||||
|
||||
# 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"]
|
||||
Reference in New Issue
Block a user