mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:41:09 +02:00
🚀 ci(picture): add picture app to CI/CD deployment pipeline
- Add picture-backend and picture-web to CI Docker build matrix - Add picture services to staging deployment workflow - Add picture-backend to production deployment workflow - Create Dockerfile and docker-entrypoint.sh for picture-web - Fix picture-backend Dockerfile port (3003→3006) and health endpoint - Add picture routes to Caddyfile.staging - Add REPLICATE_API_TOKEN and MANA_CORE_SERVICE_KEY env vars
This commit is contained in:
parent
74654e652a
commit
dcdc15f154
8 changed files with 285 additions and 2 deletions
3
.github/workflows/cd-production.yml
vendored
3
.github/workflows/cd-production.yml
vendored
|
|
@ -22,6 +22,7 @@ on:
|
|||
- manadeck-backend
|
||||
- nutriphi-backend
|
||||
- news-api
|
||||
- picture-backend
|
||||
environment:
|
||||
description: 'Deployment environment'
|
||||
required: true
|
||||
|
|
@ -269,7 +270,7 @@ jobs:
|
|||
|
||||
if [ "$SERVICE" == "all" ]; then
|
||||
# Rolling update for all services
|
||||
for service in mana-core-auth maerchenzauber-backend chat-backend manadeck-backend nutriphi-backend news-api; do
|
||||
for service in mana-core-auth maerchenzauber-backend chat-backend manadeck-backend nutriphi-backend news-api picture-backend; do
|
||||
echo "Deploying \$service..."
|
||||
docker compose up -d --no-deps --scale \$service=2 \$service
|
||||
sleep 10
|
||||
|
|
|
|||
13
.github/workflows/cd-staging.yml
vendored
13
.github/workflows/cd-staging.yml
vendored
|
|
@ -31,6 +31,8 @@ on:
|
|||
- calendar-web
|
||||
- clock-backend
|
||||
- clock-web
|
||||
- picture-backend
|
||||
- picture-web
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
|
|
@ -138,6 +140,12 @@ jobs:
|
|||
S3_SECRET_KEY=${{ secrets.S3_SECRET_KEY }}
|
||||
MANACORE_STORAGE_PUBLIC_URL=${{ secrets.MANACORE_STORAGE_PUBLIC_URL }}
|
||||
|
||||
# Replicate API (for Picture app AI image generation)
|
||||
REPLICATE_API_TOKEN=${{ secrets.REPLICATE_API_TOKEN }}
|
||||
|
||||
# Mana Core Service Key (for credit system)
|
||||
MANA_CORE_SERVICE_KEY=${{ secrets.MANA_CORE_SERVICE_KEY }}
|
||||
|
||||
# Environment
|
||||
NODE_ENV=staging
|
||||
EOF
|
||||
|
|
@ -217,6 +225,9 @@ jobs:
|
|||
# Create clock database (for clock-backend service)
|
||||
docker compose exec -T postgres psql -U postgres -c "CREATE DATABASE clock;" 2>/dev/null || echo "clock database already exists"
|
||||
|
||||
# Create picture database (for picture-backend service)
|
||||
docker compose exec -T postgres psql -U postgres -c "CREATE DATABASE picture;" 2>/dev/null || echo "picture database already exists"
|
||||
|
||||
echo "✅ Databases ready"
|
||||
EOF
|
||||
|
||||
|
|
@ -349,6 +360,8 @@ jobs:
|
|||
check_health calendar-web http://localhost:5186/health || exit 1
|
||||
check_health clock-backend http://localhost:3017/api/v1/health || exit 1
|
||||
check_health clock-web http://localhost:5187/health || exit 1
|
||||
check_health picture-backend http://localhost:3006/api/v1/health || exit 1
|
||||
check_health picture-web http://localhost:5175/health || exit 1
|
||||
|
||||
echo ""
|
||||
echo "✅ All health checks passed!"
|
||||
|
|
|
|||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -93,6 +93,8 @@ jobs:
|
|||
- { name: 'calendar-web', path: 'apps/calendar/apps/web', port: '5186' }
|
||||
- { name: 'clock-backend', path: 'apps/clock/apps/backend', port: '3017' }
|
||||
- { name: 'clock-web', path: 'apps/clock/apps/web', port: '5187' }
|
||||
- { name: 'picture-backend', path: 'apps/picture/apps/backend', port: '3006' }
|
||||
- { name: 'picture-web', path: 'apps/picture/apps/web', port: '5175' }
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
|
|
|||
95
apps/picture/apps/web/Dockerfile
Normal file
95
apps/picture/apps/web/Dockerfile
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# Build arguments for SvelteKit static env vars
|
||||
ARG PUBLIC_BACKEND_URL=http://picture-backend:3006
|
||||
ARG PUBLIC_MANA_CORE_AUTH_URL=http://mana-core-auth:3001
|
||||
|
||||
# Set as environment variables for build
|
||||
ENV PUBLIC_BACKEND_URL=$PUBLIC_BACKEND_URL
|
||||
ENV PUBLIC_MANA_CORE_AUTH_URL=$PUBLIC_MANA_CORE_AUTH_URL
|
||||
|
||||
# Install pnpm
|
||||
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy root workspace files
|
||||
COPY pnpm-workspace.yaml ./
|
||||
COPY package.json ./
|
||||
COPY pnpm-lock.yaml ./
|
||||
|
||||
# Copy shared packages needed by picture web
|
||||
COPY packages/better-auth-types ./packages/better-auth-types
|
||||
COPY packages/shared-auth ./packages/shared-auth
|
||||
COPY packages/shared-auth-ui ./packages/shared-auth-ui
|
||||
COPY packages/shared-branding ./packages/shared-branding
|
||||
COPY packages/shared-feedback-service ./packages/shared-feedback-service
|
||||
COPY packages/shared-feedback-types ./packages/shared-feedback-types
|
||||
COPY packages/shared-feedback-ui ./packages/shared-feedback-ui
|
||||
COPY packages/shared-i18n ./packages/shared-i18n
|
||||
COPY packages/shared-icons ./packages/shared-icons
|
||||
COPY packages/shared-tailwind ./packages/shared-tailwind
|
||||
COPY packages/shared-theme ./packages/shared-theme
|
||||
COPY packages/shared-theme-ui ./packages/shared-theme-ui
|
||||
COPY packages/shared-subscription-types ./packages/shared-subscription-types
|
||||
COPY packages/shared-subscription-ui ./packages/shared-subscription-ui
|
||||
COPY packages/shared-profile-ui ./packages/shared-profile-ui
|
||||
COPY packages/shared-ui ./packages/shared-ui
|
||||
COPY packages/shared-utils ./packages/shared-utils
|
||||
|
||||
# Copy picture packages
|
||||
COPY apps/picture/packages ./apps/picture/packages
|
||||
COPY apps/picture/apps/web ./apps/picture/apps/web
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages that need building
|
||||
WORKDIR /app/packages/better-auth-types
|
||||
RUN pnpm build || true
|
||||
|
||||
WORKDIR /app/packages/shared-auth
|
||||
RUN pnpm build || true
|
||||
|
||||
# Build the web app
|
||||
WORKDIR /app/apps/picture/apps/web
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
# Keep same directory structure as builder so pnpm symlinks resolve correctly
|
||||
WORKDIR /app/apps/picture/apps/web
|
||||
|
||||
# Copy the pnpm store that symlinks point to (at /app/node_modules/.pnpm)
|
||||
COPY --from=builder /app/node_modules/.pnpm /app/node_modules/.pnpm
|
||||
|
||||
# Copy the app's node_modules (contains symlinks to the pnpm store)
|
||||
COPY --from=builder /app/apps/picture/apps/web/node_modules ./node_modules
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/apps/picture/apps/web/build ./build
|
||||
COPY --from=builder /app/apps/picture/apps/web/package.json ./
|
||||
|
||||
# Copy entrypoint script for runtime config generation
|
||||
COPY apps/picture/apps/web/docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# Expose port
|
||||
EXPOSE 5175
|
||||
|
||||
# Set environment variables
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=5175
|
||||
ENV HOST=0.0.0.0
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:5175/health || exit 1
|
||||
|
||||
# Use entrypoint to generate runtime config
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
|
||||
# Run the app
|
||||
CMD ["node", "build"]
|
||||
31
apps/picture/apps/web/docker-entrypoint.sh
Normal file
31
apps/picture/apps/web/docker-entrypoint.sh
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "Generating runtime configuration..."
|
||||
|
||||
# Environment variables with development defaults
|
||||
BACKEND_URL=${BACKEND_URL:-"http://localhost:3006"}
|
||||
AUTH_URL=${AUTH_URL:-"http://localhost:3001"}
|
||||
|
||||
echo "Config values:"
|
||||
echo " BACKEND_URL: $BACKEND_URL"
|
||||
echo " AUTH_URL: $AUTH_URL"
|
||||
|
||||
# Generate config.json from environment variables
|
||||
cat > /app/apps/picture/apps/web/build/client/config.json <<EOF
|
||||
{
|
||||
"BACKEND_URL": "${BACKEND_URL}",
|
||||
"AUTH_URL": "${AUTH_URL}"
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Configuration generated at /app/apps/picture/apps/web/build/client/config.json"
|
||||
cat /app/apps/picture/apps/web/build/client/config.json
|
||||
|
||||
# Remove pre-compressed versions (SvelteKit serves these instead of the raw file)
|
||||
rm -f /app/apps/picture/apps/web/build/client/config.json.br
|
||||
rm -f /app/apps/picture/apps/web/build/client/config.json.gz
|
||||
echo "Removed stale pre-compressed config files"
|
||||
|
||||
echo "Starting Picture web app..."
|
||||
exec "$@"
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
version: '3.9'
|
||||
|
||||
# To add more services:
|
||||
# 1. Add service block below
|
||||
# 2. Add to cd-production.yml workflow_dispatch options
|
||||
# 3. Add Caddy routes to production Caddyfile
|
||||
|
||||
services:
|
||||
# ============================================
|
||||
# Backend Services (Production)
|
||||
|
|
@ -235,6 +240,53 @@ services:
|
|||
cpus: '0.5'
|
||||
memory: 256M
|
||||
|
||||
picture-backend:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/picture-backend:${PICTURE_VERSION:-latest}
|
||||
container_name: picture-backend-prod
|
||||
restart: always
|
||||
depends_on:
|
||||
mana-core-auth:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 3006
|
||||
DATABASE_URL: ${PICTURE_DATABASE_URL}
|
||||
MANA_CORE_AUTH_URL: http://mana-core-auth:3001
|
||||
# Replicate API for AI image generation
|
||||
REPLICATE_API_TOKEN: ${REPLICATE_API_TOKEN}
|
||||
# S3/MinIO storage
|
||||
S3_ENDPOINT: ${S3_ENDPOINT}
|
||||
S3_REGION: ${S3_REGION}
|
||||
S3_ACCESS_KEY: ${S3_ACCESS_KEY}
|
||||
S3_SECRET_KEY: ${S3_SECRET_KEY}
|
||||
MANACORE_STORAGE_PUBLIC_URL: ${MANACORE_STORAGE_PUBLIC_URL}
|
||||
# Credit system
|
||||
MANA_CORE_SERVICE_KEY: ${MANA_CORE_SERVICE_KEY}
|
||||
APP_ID: picture
|
||||
ports:
|
||||
- "127.0.0.1:3007:3006"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3006/api/v1/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- manacore-prod
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "50m"
|
||||
max-file: "5"
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2'
|
||||
memory: 1G
|
||||
reservations:
|
||||
cpus: '1'
|
||||
memory: 512M
|
||||
|
||||
# ============================================
|
||||
# Monitoring (Optional but recommended)
|
||||
# ============================================
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
# 1. Copy the service block from docker-compose.staging.full.yml
|
||||
# 2. Add corresponding health check in .github/workflows/cd-staging.yml
|
||||
# 3. Add service to workflow_dispatch options in cd-staging.yml
|
||||
# 4. Add Caddy routes to docker/caddy/Caddyfile.staging
|
||||
|
||||
services:
|
||||
# ============================================
|
||||
|
|
@ -83,7 +84,7 @@ services:
|
|||
# Frontend URL for password reset and email verification links
|
||||
FRONTEND_URL: ${FRONTEND_URL:-https://staging.manacore.ai}
|
||||
# CORS - Allow all staging web app origins (HTTPS domains + localhost for dev)
|
||||
CORS_ORIGINS: https://chat.staging.manacore.ai,https://staging.manacore.ai,https://calendar.staging.manacore.ai,https://clock.staging.manacore.ai,https://todo.staging.manacore.ai,http://localhost:3000,http://localhost:5173,http://localhost:5186,http://localhost:5187,http://localhost:5188
|
||||
CORS_ORIGINS: https://chat.staging.manacore.ai,https://staging.manacore.ai,https://calendar.staging.manacore.ai,https://clock.staging.manacore.ai,https://todo.staging.manacore.ai,https://picture.staging.manacore.ai,http://localhost:3000,http://localhost:5173,http://localhost:5175,http://localhost:5186,http://localhost:5187,http://localhost:5188
|
||||
ports:
|
||||
- "3001:3001"
|
||||
healthcheck:
|
||||
|
|
@ -189,6 +190,7 @@ services:
|
|||
CALENDAR_API_URL: https://calendar-api.staging.manacore.ai
|
||||
CLOCK_API_URL: https://clock-api.staging.manacore.ai
|
||||
CONTACTS_API_URL: https://contacts-api.staging.manacore.ai
|
||||
PICTURE_API_URL: https://picture-api.staging.manacore.ai
|
||||
ports:
|
||||
- "5173:5173"
|
||||
healthcheck:
|
||||
|
|
@ -411,6 +413,85 @@ services:
|
|||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ============================================
|
||||
# Picture App
|
||||
# ============================================
|
||||
|
||||
picture-backend:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/picture-backend:${PICTURE_VERSION:-latest}
|
||||
container_name: picture-backend-staging
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
mana-core-auth:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: staging
|
||||
PORT: 3006
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/picture
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_USER: ${POSTGRES_USER:-postgres}
|
||||
MANA_CORE_AUTH_URL: http://mana-core-auth:3001
|
||||
CORS_ORIGINS: https://picture.staging.manacore.ai,https://staging.manacore.ai,http://localhost:5175,http://localhost:5173
|
||||
# Replicate API for AI image generation
|
||||
REPLICATE_API_TOKEN: ${REPLICATE_API_TOKEN}
|
||||
# S3/MinIO storage
|
||||
S3_ENDPOINT: ${S3_ENDPOINT}
|
||||
S3_REGION: ${S3_REGION}
|
||||
S3_ACCESS_KEY: ${S3_ACCESS_KEY}
|
||||
S3_SECRET_KEY: ${S3_SECRET_KEY}
|
||||
MANACORE_STORAGE_PUBLIC_URL: ${MANACORE_STORAGE_PUBLIC_URL}
|
||||
# Credit system
|
||||
MANA_CORE_SERVICE_KEY: ${MANA_CORE_SERVICE_KEY}
|
||||
APP_ID: picture
|
||||
ports:
|
||||
- "3006:3006"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3006/api/v1/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- manacore-network
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
picture-web:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/picture-web:${PICTURE_WEB_VERSION:-latest}
|
||||
container_name: picture-web-staging
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
picture-backend:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: staging
|
||||
PORT: 5175
|
||||
# Runtime config generation (12-factor pattern)
|
||||
# These vars are used by docker-entrypoint.sh to generate /config.json
|
||||
BACKEND_URL: https://picture-api.staging.manacore.ai
|
||||
AUTH_URL: https://auth.staging.manacore.ai
|
||||
ports:
|
||||
- "5175:5175"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5175/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- manacore-network
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ============================================
|
||||
# Networks
|
||||
# ============================================
|
||||
|
|
|
|||
|
|
@ -43,3 +43,11 @@ todo.staging.manacore.ai {
|
|||
todo-api.staging.manacore.ai {
|
||||
reverse_proxy localhost:3018
|
||||
}
|
||||
|
||||
# Picture
|
||||
picture.staging.manacore.ai {
|
||||
reverse_proxy localhost:5175
|
||||
}
|
||||
picture-api.staging.manacore.ai {
|
||||
reverse_proxy localhost:3006
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue