managarten/maerchenzauber/apps/backend/Dockerfile
Till-JS e7f5f942f3 chore: initial commit - consolidate 4 projects into monorepo
Projects included:
- maerchenzauber (NestJS backend + Expo mobile + SvelteKit web + Astro landing)
- manacore (Expo mobile + SvelteKit web + Astro landing)
- manadeck (NestJS backend + Expo mobile + SvelteKit web)
- memoro (Expo mobile + SvelteKit web + Astro landing)

This commit preserves the current state before monorepo restructuring.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 23:38:24 +01:00

128 lines
No EOL
4.4 KiB
Docker

# syntax=docker/dockerfile:1
# Build stage
FROM node:20-alpine AS builder
# Set working directory to monorepo root
WORKDIR /app
# Install build dependencies
RUN apk add --no-cache python3 make g++ git openssh-client
# Configure git to use HTTPS with token
RUN git config --global url."https://github.com/".insteadOf "git@github.com:" && \
git config --global url."https://".insteadOf "git://"
# Clone, build and package mana-core as a tarball
RUN --mount=type=secret,id=github_token \
if [ -f /run/secrets/github_token ]; then \
export GITHUB_TOKEN=$(cat /run/secrets/github_token) && \
echo "Using GitHub token for private repo access" && \
git clone https://${GITHUB_TOKEN}@github.com/Memo-2023/mana-core-nestjs-package.git /tmp/mana-core; \
else \
echo "No GitHub token provided, attempting public clone" && \
git clone https://github.com/Memo-2023/mana-core-nestjs-package.git /tmp/mana-core; \
fi && \
cd /tmp/mana-core && \
npm install --force && \
npm run build && \
npm pack && \
mv *.tgz /app/mana-core.tgz && \
echo "Mana-core packaged as tarball at /app/mana-core.tgz"
# Copy backend package.json
COPY backend/package.json ./backend/package.json
# Replace GitHub URL with the tarball (../ because package.json is in backend/)
RUN sed -i 's|"git+https://github.com/Memo-2023/mana-core-nestjs-package.git"|"file:../mana-core.tgz"|g' backend/package.json || \
sed -i 's|"github:Memo-2023/mana-core-nestjs-package"|"file:../mana-core.tgz"|g' backend/package.json
# Debug: Verify the replacement and file existence
RUN echo "=== Verifying tarball and package.json ===" && \
ls -la mana-core.tgz && \
echo "Tarball exists at /app/mana-core.tgz" && \
echo "Checking package.json replacement:" && \
grep -n "mana-core" backend/package.json && \
echo "=== End verification ==="
# Install backend dependencies
WORKDIR /app/backend
RUN npm install --legacy-peer-deps && \
echo "Dependencies installed with mana-core from tarball"
# Copy shared packages source code and build them if they exist
WORKDIR /app
COPY packages ./packages/
RUN if [ -d "packages/shared-types" ]; then \
cd packages/shared-types && npm install && npm run build || echo "No build script for shared-types"; \
else \
echo "No packages/shared-types directory found"; \
fi
# Copy backend source code
COPY backend/ ./backend/
# Build the backend application
WORKDIR /app/backend
RUN npm run build
# Debug: List the contents to verify build output
RUN echo "=== Listing dist contents ===" && \
ls -la dist/ || echo "No dist folder found" && \
ls -la dist/src/ || echo "No dist/src folder found" && \
echo "=== Build complete ==="
# Production stage
FROM node:20-alpine
# Install dumb-init for proper signal handling
RUN apk add --no-cache dumb-init
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
# Set working directory
WORKDIR /app
# Copy the entire dist folder structure
COPY --from=builder /app/backend/dist ./dist
# Copy package.json for metadata
COPY --from=builder /app/backend/package.json ./
# Copy backend node_modules
COPY --from=builder /app/backend/node_modules ./node_modules
# Backend specific node_modules are not needed since we use root node_modules
# Debug in production to verify file structure
RUN echo "=== Production stage file check ===" && \
ls -la /app/ && \
echo "=== Checking dist folder ===" && \
ls -la /app/dist/ || echo "No dist folder" && \
echo "=== Checking dist/src folder ===" && \
ls -la /app/dist/src/ || echo "No dist/src folder" && \
echo "=== Looking for main.js ===" && \
find /app -name "main.js" -type f 2>/dev/null || echo "main.js not found"
# Change ownership to nodejs user
RUN chown -R nodejs:nodejs /app
# Switch to non-root user
USER nodejs
# Expose the port (Cloud Run will set PORT env var)
EXPOSE 8080
# Set environment to production
ENV NODE_ENV=production
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:' + (process.env.PORT || 8080) + '/health', (r) => {r.statusCode === 200 ? process.exit(0) : process.exit(1)})" || exit 1
# Use dumb-init to handle signals properly
ENTRYPOINT ["dumb-init", "--"]
# Start the application - use the actual path found during debug
CMD ["node", "dist/src/main.js"]