diff --git a/.github/workflows/docker-build-server.yml b/.github/workflows/docker-build-server.yml index 796e20393..0b991493b 100644 --- a/.github/workflows/docker-build-server.yml +++ b/.github/workflows/docker-build-server.yml @@ -36,6 +36,9 @@ jobs: with: node-version: 22 + - name: Install bun + run: npm install -g bun@1.2.15 + - name: Get pnpm store directory shell: bash run: | @@ -44,9 +47,58 @@ jobs: - name: Mount pnpm store sticky disk uses: useblacksmith/stickydisk@v1 with: - key: ${{ github.repository }}-docker-pnpm-store + key: ${{ github.repository }}-pnpm-store path: ${{ env.STORE_PATH }} + - name: Mount Turbo cache sticky disk + uses: useblacksmith/stickydisk@v1 + with: + key: ${{ github.repository }}-turbo-cache + path: ./.turbo + + - name: Install dependencies + run: | + echo "๐Ÿ“ฆ Installing dependencies with pnpm..." + pnpm install --frozen-lockfile --prefer-offline + + - name: Build with Turbo + run: | + echo "๐Ÿ”จ Building server with Turbo (using sticky disk cache)..." + pnpm turbo run build --filter=@buster-app/server + echo "โœ… Build complete!" + env: + NODE_ENV: production + DOCKER_BUILD: true + CI: true + + - name: Build server bundle + run: | + echo "๐Ÿ“ฆ Creating server bundle with bun..." + cd apps/server + bun build src/index.ts --outdir ./dist --target bun --external pino-pretty + ls -la dist/ + cd ../.. + + - name: Prepare production dependencies + run: | + echo "๐Ÿงน Preparing production-only dependencies..." + # Create a temporary directory for production deps + mkdir -p /tmp/prod-deps + cp package.json pnpm-lock.yaml pnpm-workspace.yaml /tmp/prod-deps/ + cp -r packages /tmp/prod-deps/ + cp apps/server/package.json /tmp/prod-deps/apps/server/ + + # Install production dependencies only + cd /tmp/prod-deps + pnpm install --frozen-lockfile --prod --ignore-scripts --no-optional + + # Copy back to workspace + cd - + mkdir -p docker-context + cp -r /tmp/prod-deps/node_modules docker-context/ + cp -r apps/server/dist docker-context/ + cp apps/server/package.json docker-context/ + - name: Set up Docker Builder with Blacksmith cache uses: useblacksmith/setup-docker-builder@v1 @@ -77,8 +129,8 @@ jobs: - name: Build and push Docker image uses: useblacksmith/build-push-action@v2 with: - context: . - file: ./apps/server/Dockerfile + context: ./docker-context + file: ./apps/server/Dockerfile.prebuilt push: true tags: ${{ steps.meta.outputs.tags }} labels: | diff --git a/apps/server/Dockerfile.prebuilt b/apps/server/Dockerfile.prebuilt new file mode 100644 index 000000000..6c17913f5 --- /dev/null +++ b/apps/server/Dockerfile.prebuilt @@ -0,0 +1,46 @@ +# ================================================================ +# Optimized Dockerfile for pre-built artifacts +# This expects the app to be already built by GitHub Actions +# ================================================================ + +FROM oven/bun:1.2.15-alpine AS runtime + +WORKDIR /app + +# Set production environment +ENV NODE_ENV=production + +# Add build metadata as labels +ARG COMMIT_SHA +ARG BUILD_DATE +LABEL org.opencontainers.image.revision="${COMMIT_SHA}" +LABEL org.opencontainers.image.created="${BUILD_DATE}" + +# Create non-root user +RUN addgroup --system --gid 1001 bunuser && \ + adduser --system --uid 1001 bunuser + +# Copy pre-built application files +# These are prepared by GitHub Actions: +# - dist/ contains the built server bundle +# - node_modules/ contains production dependencies only +# - package.json for runtime metadata +COPY --chown=bunuser:bunuser dist ./dist +COPY --chown=bunuser:bunuser node_modules ./node_modules +COPY --chown=bunuser:bunuser package.json ./ + +# Show image info +RUN echo "=== Production image ready ===" && \ + echo "Commit: ${COMMIT_SHA:-unknown}" && \ + echo "Built: ${BUILD_DATE:-unknown}" && \ + echo "Size: $(du -sh /app | cut -f1)" + +USER bunuser +EXPOSE 3002 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD bun -e "fetch('http://localhost:' + (process.env.SERVER_PORT || 3002) + '/healthcheck').then(r => r.ok ? process.exit(0) : process.exit(1))" + +# Start the application +CMD ["bun", "run", "dist/index.js"] \ No newline at end of file