mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-16 14:19:39 +02:00
🚀 ci: add Docker deployment for Manacore, Todo, Calendar, and Clock apps
Add complete Docker deployment infrastructure for 4 new applications: - Dockerfiles for backend (NestJS) and web (SvelteKit) apps - docker-entrypoint.sh scripts with PostgreSQL wait and schema push - Updated docker-compose.staging.yml with 7 new services - Updated CI/CD workflows with build matrix and health checks
This commit is contained in:
parent
bb4e12c36e
commit
5e0b5a8e7a
13 changed files with 898 additions and 0 deletions
93
.github/workflows/cd-staging.yml
vendored
93
.github/workflows/cd-staging.yml
vendored
|
|
@ -24,6 +24,13 @@ on:
|
|||
- mana-core-auth
|
||||
- chat-backend
|
||||
- chat-web
|
||||
- manacore-web
|
||||
- todo-backend
|
||||
- todo-web
|
||||
- calendar-backend
|
||||
- calendar-web
|
||||
- clock-backend
|
||||
- clock-web
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
|
|
@ -184,6 +191,15 @@ jobs:
|
|||
# Create chat database (for chat-backend service)
|
||||
docker compose exec -T postgres psql -U postgres -c "CREATE DATABASE chat;" 2>/dev/null || echo "chat database already exists"
|
||||
|
||||
# Create todo database (for todo-backend service)
|
||||
docker compose exec -T postgres psql -U postgres -c "CREATE DATABASE todo;" 2>/dev/null || echo "todo database already exists"
|
||||
|
||||
# Create calendar database (for calendar-backend service)
|
||||
docker compose exec -T postgres psql -U postgres -c "CREATE DATABASE calendar;" 2>/dev/null || echo "calendar database already exists"
|
||||
|
||||
# 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"
|
||||
|
||||
echo "✅ Databases ready"
|
||||
EOF
|
||||
|
||||
|
|
@ -238,6 +254,83 @@ jobs:
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Check manacore-web
|
||||
echo "Checking manacore-web..."
|
||||
if docker compose exec -T manacore-web wget -q -O - http://localhost:5173/health > /dev/null 2>&1; then
|
||||
echo "✅ manacore-web is healthy"
|
||||
else
|
||||
echo "❌ manacore-web health check failed"
|
||||
echo "=== Logs ==="
|
||||
docker compose logs --tail=50 manacore-web
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check todo-backend
|
||||
echo "Checking todo-backend..."
|
||||
if docker compose exec -T todo-backend wget -q -O - http://localhost:3018/api/v1/health > /dev/null 2>&1; then
|
||||
echo "✅ todo-backend is healthy"
|
||||
else
|
||||
echo "❌ todo-backend health check failed"
|
||||
echo "=== Logs ==="
|
||||
docker compose logs --tail=50 todo-backend
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check todo-web
|
||||
echo "Checking todo-web..."
|
||||
if docker compose exec -T todo-web wget -q -O - http://localhost:5188/health > /dev/null 2>&1; then
|
||||
echo "✅ todo-web is healthy"
|
||||
else
|
||||
echo "❌ todo-web health check failed"
|
||||
echo "=== Logs ==="
|
||||
docker compose logs --tail=50 todo-web
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check calendar-backend
|
||||
echo "Checking calendar-backend..."
|
||||
if docker compose exec -T calendar-backend wget -q -O - http://localhost:3016/api/v1/health > /dev/null 2>&1; then
|
||||
echo "✅ calendar-backend is healthy"
|
||||
else
|
||||
echo "❌ calendar-backend health check failed"
|
||||
echo "=== Logs ==="
|
||||
docker compose logs --tail=50 calendar-backend
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check calendar-web
|
||||
echo "Checking calendar-web..."
|
||||
if docker compose exec -T calendar-web wget -q -O - http://localhost:5186/health > /dev/null 2>&1; then
|
||||
echo "✅ calendar-web is healthy"
|
||||
else
|
||||
echo "❌ calendar-web health check failed"
|
||||
echo "=== Logs ==="
|
||||
docker compose logs --tail=50 calendar-web
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check clock-backend
|
||||
echo "Checking clock-backend..."
|
||||
if docker compose exec -T clock-backend wget -q -O - http://localhost:3017/api/v1/health > /dev/null 2>&1; then
|
||||
echo "✅ clock-backend is healthy"
|
||||
else
|
||||
echo "❌ clock-backend health check failed"
|
||||
echo "=== Logs ==="
|
||||
docker compose logs --tail=50 clock-backend
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check clock-web
|
||||
echo "Checking clock-web..."
|
||||
if docker compose exec -T clock-web wget -q -O - http://localhost:5187/health > /dev/null 2>&1; then
|
||||
echo "✅ clock-web is healthy"
|
||||
else
|
||||
echo "❌ clock-web health check failed"
|
||||
echo "=== Logs ==="
|
||||
docker compose logs --tail=50 clock-web
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ All health checks passed!"
|
||||
EOF
|
||||
|
|
|
|||
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
|
|
@ -86,6 +86,13 @@ jobs:
|
|||
- { name: 'mana-core-auth', path: 'services/mana-core-auth', port: '3001' }
|
||||
- { name: 'chat-backend', path: 'apps/chat/apps/backend', port: '3002' }
|
||||
- { name: 'chat-web', path: 'apps/chat/apps/web', port: '3000' }
|
||||
- { name: 'manacore-web', path: 'apps/manacore/apps/web', port: '5173' }
|
||||
- { name: 'todo-backend', path: 'apps/todo/apps/backend', port: '3018' }
|
||||
- { name: 'todo-web', path: 'apps/todo/apps/web', port: '5188' }
|
||||
- { name: 'calendar-backend', path: 'apps/calendar/apps/backend', port: '3016' }
|
||||
- { 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' }
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
|
|
|||
68
apps/calendar/apps/backend/Dockerfile
Normal file
68
apps/calendar/apps/backend/Dockerfile
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# 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
|
||||
COPY packages/shared-errors ./packages/shared-errors
|
||||
COPY packages/shared-nestjs-auth ./packages/shared-nestjs-auth
|
||||
|
||||
# Copy calendar packages and backend
|
||||
COPY apps/calendar/packages ./apps/calendar/packages
|
||||
COPY apps/calendar/apps/backend ./apps/calendar/apps/backend
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages first
|
||||
WORKDIR /app/packages/shared-errors
|
||||
RUN pnpm build
|
||||
|
||||
WORKDIR /app/packages/shared-nestjs-auth
|
||||
RUN pnpm build
|
||||
|
||||
# Build the backend
|
||||
WORKDIR /app/apps/calendar/apps/backend
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
# Install pnpm and postgresql-client for health checks
|
||||
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate \
|
||||
&& apk add --no-cache postgresql-client
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy everything from builder (including node_modules)
|
||||
COPY --from=builder /app/pnpm-workspace.yaml ./
|
||||
COPY --from=builder /app/package.json ./
|
||||
COPY --from=builder /app/pnpm-lock.yaml ./
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/packages ./packages
|
||||
COPY --from=builder /app/apps/calendar ./apps/calendar
|
||||
|
||||
# Copy entrypoint script
|
||||
COPY apps/calendar/apps/backend/docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
WORKDIR /app/apps/calendar/apps/backend
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3016
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:3016/api/v1/health || exit 1
|
||||
|
||||
# Run entrypoint script
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
CMD ["node", "dist/main.js"]
|
||||
23
apps/calendar/apps/backend/docker-entrypoint.sh
Normal file
23
apps/calendar/apps/backend/docker-entrypoint.sh
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "=== Calendar Backend Entrypoint ==="
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "Waiting for PostgreSQL..."
|
||||
until pg_isready -h ${DB_HOST:-postgres} -p ${DB_PORT:-5432} -U ${DB_USER:-postgres} 2>/dev/null; do
|
||||
echo "PostgreSQL is unavailable - sleeping"
|
||||
sleep 2
|
||||
done
|
||||
echo "PostgreSQL is up!"
|
||||
|
||||
cd /app/apps/calendar/apps/backend
|
||||
|
||||
# Run schema push
|
||||
echo "Pushing database schema..."
|
||||
npx drizzle-kit push --force
|
||||
echo "Schema push completed!"
|
||||
|
||||
# Execute the main command
|
||||
echo "Starting application..."
|
||||
exec "$@"
|
||||
72
apps/calendar/apps/web/Dockerfile
Normal file
72
apps/calendar/apps/web/Dockerfile
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# 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 calendar web
|
||||
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 calendar packages and web
|
||||
COPY apps/calendar/packages ./apps/calendar/packages
|
||||
COPY apps/calendar/apps/web ./apps/calendar/apps/web
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages that need building
|
||||
WORKDIR /app/packages/shared-auth
|
||||
RUN pnpm build || true
|
||||
|
||||
# Build the web app
|
||||
WORKDIR /app/apps/calendar/apps/web
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/apps/calendar/apps/web/build ./build
|
||||
COPY --from=builder /app/apps/calendar/apps/web/package.json ./
|
||||
|
||||
# Install only production dependencies for the built app
|
||||
RUN npm install --omit=dev 2>/dev/null || true
|
||||
|
||||
# Expose port
|
||||
EXPOSE 5186
|
||||
|
||||
# Set environment variables
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=5186
|
||||
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:5186/health || exit 1
|
||||
|
||||
# Run the app
|
||||
CMD ["node", "build"]
|
||||
68
apps/clock/apps/backend/Dockerfile
Normal file
68
apps/clock/apps/backend/Dockerfile
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# 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
|
||||
COPY packages/shared-errors ./packages/shared-errors
|
||||
COPY packages/shared-nestjs-auth ./packages/shared-nestjs-auth
|
||||
|
||||
# Copy clock packages and backend
|
||||
COPY apps/clock/packages ./apps/clock/packages
|
||||
COPY apps/clock/apps/backend ./apps/clock/apps/backend
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages first
|
||||
WORKDIR /app/packages/shared-errors
|
||||
RUN pnpm build
|
||||
|
||||
WORKDIR /app/packages/shared-nestjs-auth
|
||||
RUN pnpm build
|
||||
|
||||
# Build the backend
|
||||
WORKDIR /app/apps/clock/apps/backend
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
# Install pnpm and postgresql-client for health checks
|
||||
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate \
|
||||
&& apk add --no-cache postgresql-client
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy everything from builder (including node_modules)
|
||||
COPY --from=builder /app/pnpm-workspace.yaml ./
|
||||
COPY --from=builder /app/package.json ./
|
||||
COPY --from=builder /app/pnpm-lock.yaml ./
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/packages ./packages
|
||||
COPY --from=builder /app/apps/clock ./apps/clock
|
||||
|
||||
# Copy entrypoint script
|
||||
COPY apps/clock/apps/backend/docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
WORKDIR /app/apps/clock/apps/backend
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3017
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:3017/api/v1/health || exit 1
|
||||
|
||||
# Run entrypoint script
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
CMD ["node", "dist/main.js"]
|
||||
23
apps/clock/apps/backend/docker-entrypoint.sh
Normal file
23
apps/clock/apps/backend/docker-entrypoint.sh
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "=== Clock Backend Entrypoint ==="
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "Waiting for PostgreSQL..."
|
||||
until pg_isready -h ${DB_HOST:-postgres} -p ${DB_PORT:-5432} -U ${DB_USER:-postgres} 2>/dev/null; do
|
||||
echo "PostgreSQL is unavailable - sleeping"
|
||||
sleep 2
|
||||
done
|
||||
echo "PostgreSQL is up!"
|
||||
|
||||
cd /app/apps/clock/apps/backend
|
||||
|
||||
# Run schema push
|
||||
echo "Pushing database schema..."
|
||||
npx drizzle-kit push --force
|
||||
echo "Schema push completed!"
|
||||
|
||||
# Execute the main command
|
||||
echo "Starting application..."
|
||||
exec "$@"
|
||||
72
apps/clock/apps/web/Dockerfile
Normal file
72
apps/clock/apps/web/Dockerfile
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# 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 clock web
|
||||
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 clock packages and web
|
||||
COPY apps/clock/packages ./apps/clock/packages
|
||||
COPY apps/clock/apps/web ./apps/clock/apps/web
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages that need building
|
||||
WORKDIR /app/packages/shared-auth
|
||||
RUN pnpm build || true
|
||||
|
||||
# Build the web app
|
||||
WORKDIR /app/apps/clock/apps/web
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/apps/clock/apps/web/build ./build
|
||||
COPY --from=builder /app/apps/clock/apps/web/package.json ./
|
||||
|
||||
# Install only production dependencies for the built app
|
||||
RUN npm install --omit=dev 2>/dev/null || true
|
||||
|
||||
# Expose port
|
||||
EXPOSE 5187
|
||||
|
||||
# Set environment variables
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=5187
|
||||
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:5187/health || exit 1
|
||||
|
||||
# Run the app
|
||||
CMD ["node", "build"]
|
||||
74
apps/manacore/apps/web/Dockerfile
Normal file
74
apps/manacore/apps/web/Dockerfile
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# 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 manacore web
|
||||
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-config ./packages/shared-config
|
||||
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-supabase ./packages/shared-supabase
|
||||
COPY packages/shared-types ./packages/shared-types
|
||||
COPY packages/shared-ui ./packages/shared-ui
|
||||
COPY packages/shared-utils ./packages/shared-utils
|
||||
|
||||
# Copy manacore web
|
||||
COPY apps/manacore/apps/web ./apps/manacore/apps/web
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages that need building
|
||||
WORKDIR /app/packages/shared-auth
|
||||
RUN pnpm build || true
|
||||
|
||||
# Build the web app
|
||||
WORKDIR /app/apps/manacore/apps/web
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/apps/manacore/apps/web/build ./build
|
||||
COPY --from=builder /app/apps/manacore/apps/web/package.json ./
|
||||
|
||||
# Install only production dependencies for the built app
|
||||
RUN npm install --omit=dev 2>/dev/null || true
|
||||
|
||||
# Expose port
|
||||
EXPOSE 5173
|
||||
|
||||
# Set environment variables
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=5173
|
||||
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:5173/health || exit 1
|
||||
|
||||
# Run the app
|
||||
CMD ["node", "build"]
|
||||
67
apps/todo/apps/backend/Dockerfile
Normal file
67
apps/todo/apps/backend/Dockerfile
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# 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
|
||||
COPY packages/shared-errors ./packages/shared-errors
|
||||
COPY packages/shared-nestjs-auth ./packages/shared-nestjs-auth
|
||||
|
||||
# Copy todo backend
|
||||
COPY apps/todo/apps/backend ./apps/todo/apps/backend
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages first
|
||||
WORKDIR /app/packages/shared-errors
|
||||
RUN pnpm build
|
||||
|
||||
WORKDIR /app/packages/shared-nestjs-auth
|
||||
RUN pnpm build
|
||||
|
||||
# Build the backend
|
||||
WORKDIR /app/apps/todo/apps/backend
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
# Install pnpm and postgresql-client for health checks
|
||||
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate \
|
||||
&& apk add --no-cache postgresql-client
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy everything from builder (including node_modules)
|
||||
COPY --from=builder /app/pnpm-workspace.yaml ./
|
||||
COPY --from=builder /app/package.json ./
|
||||
COPY --from=builder /app/pnpm-lock.yaml ./
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/packages ./packages
|
||||
COPY --from=builder /app/apps/todo/apps/backend ./apps/todo/apps/backend
|
||||
|
||||
# Copy entrypoint script
|
||||
COPY apps/todo/apps/backend/docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
WORKDIR /app/apps/todo/apps/backend
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3018
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:3018/api/v1/health || exit 1
|
||||
|
||||
# Run entrypoint script
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
CMD ["node", "dist/main.js"]
|
||||
23
apps/todo/apps/backend/docker-entrypoint.sh
Normal file
23
apps/todo/apps/backend/docker-entrypoint.sh
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "=== Todo Backend Entrypoint ==="
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "Waiting for PostgreSQL..."
|
||||
until pg_isready -h ${DB_HOST:-postgres} -p ${DB_PORT:-5432} -U ${DB_USER:-postgres} 2>/dev/null; do
|
||||
echo "PostgreSQL is unavailable - sleeping"
|
||||
sleep 2
|
||||
done
|
||||
echo "PostgreSQL is up!"
|
||||
|
||||
cd /app/apps/todo/apps/backend
|
||||
|
||||
# Run schema push
|
||||
echo "Pushing database schema..."
|
||||
npx drizzle-kit push --force
|
||||
echo "Schema push completed!"
|
||||
|
||||
# Execute the main command
|
||||
echo "Starting application..."
|
||||
exec "$@"
|
||||
72
apps/todo/apps/web/Dockerfile
Normal file
72
apps/todo/apps/web/Dockerfile
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# 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 todo web
|
||||
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 todo packages and web
|
||||
COPY apps/todo/packages ./apps/todo/packages
|
||||
COPY apps/todo/apps/web ./apps/todo/apps/web
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages that need building
|
||||
WORKDIR /app/packages/shared-auth
|
||||
RUN pnpm build || true
|
||||
|
||||
# Build the web app
|
||||
WORKDIR /app/apps/todo/apps/web
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/apps/todo/apps/web/build ./build
|
||||
COPY --from=builder /app/apps/todo/apps/web/package.json ./
|
||||
|
||||
# Install only production dependencies for the built app
|
||||
RUN npm install --omit=dev 2>/dev/null || true
|
||||
|
||||
# Expose port
|
||||
EXPOSE 5188
|
||||
|
||||
# Set environment variables
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=5188
|
||||
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:5188/health || exit 1
|
||||
|
||||
# Run the app
|
||||
CMD ["node", "build"]
|
||||
|
|
@ -159,6 +159,242 @@ services:
|
|||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ============================================
|
||||
# Manacore App
|
||||
# ============================================
|
||||
|
||||
manacore-web:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/manacore-web:${MANACORE_WEB_VERSION:-latest}
|
||||
container_name: manacore-web-staging
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
mana-core-auth:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: staging
|
||||
PORT: 5173
|
||||
PUBLIC_MANA_CORE_AUTH_URL: http://mana-core-auth:3001
|
||||
PUBLIC_MANA_CORE_AUTH_URL_CLIENT: http://46.224.108.214:3001
|
||||
ports:
|
||||
- "5173:5173"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5173/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- manacore-network
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ============================================
|
||||
# Todo App
|
||||
# ============================================
|
||||
|
||||
todo-backend:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/todo-backend:${TODO_VERSION:-latest}
|
||||
container_name: todo-backend-staging
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
mana-core-auth:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: staging
|
||||
PORT: 3018
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/todo
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_USER: ${POSTGRES_USER:-postgres}
|
||||
MANA_CORE_AUTH_URL: http://mana-core-auth:3001
|
||||
CORS_ORIGINS: http://46.224.108.214:5188,http://localhost:5188
|
||||
ports:
|
||||
- "3018:3018"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3018/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"
|
||||
|
||||
todo-web:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/todo-web:${TODO_WEB_VERSION:-latest}
|
||||
container_name: todo-web-staging
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
todo-backend:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: staging
|
||||
PORT: 5188
|
||||
PUBLIC_BACKEND_URL: http://todo-backend:3018
|
||||
PUBLIC_MANA_CORE_AUTH_URL: http://mana-core-auth:3001
|
||||
PUBLIC_BACKEND_URL_CLIENT: http://46.224.108.214:3018
|
||||
PUBLIC_MANA_CORE_AUTH_URL_CLIENT: http://46.224.108.214:3001
|
||||
ports:
|
||||
- "5188:5188"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5188/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- manacore-network
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ============================================
|
||||
# Calendar App
|
||||
# ============================================
|
||||
|
||||
calendar-backend:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/calendar-backend:${CALENDAR_VERSION:-latest}
|
||||
container_name: calendar-backend-staging
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
mana-core-auth:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: staging
|
||||
PORT: 3016
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/calendar
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_USER: ${POSTGRES_USER:-postgres}
|
||||
MANA_CORE_AUTH_URL: http://mana-core-auth:3001
|
||||
CORS_ORIGINS: http://46.224.108.214:5186,http://localhost:5186
|
||||
ports:
|
||||
- "3016:3016"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3016/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"
|
||||
|
||||
calendar-web:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/calendar-web:${CALENDAR_WEB_VERSION:-latest}
|
||||
container_name: calendar-web-staging
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
calendar-backend:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: staging
|
||||
PORT: 5186
|
||||
PUBLIC_BACKEND_URL: http://calendar-backend:3016
|
||||
PUBLIC_MANA_CORE_AUTH_URL: http://mana-core-auth:3001
|
||||
PUBLIC_BACKEND_URL_CLIENT: http://46.224.108.214:3016
|
||||
PUBLIC_MANA_CORE_AUTH_URL_CLIENT: http://46.224.108.214:3001
|
||||
ports:
|
||||
- "5186:5186"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5186/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- manacore-network
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ============================================
|
||||
# Clock App
|
||||
# ============================================
|
||||
|
||||
clock-backend:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/clock-backend:${CLOCK_VERSION:-latest}
|
||||
container_name: clock-backend-staging
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
mana-core-auth:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: staging
|
||||
PORT: 3017
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/clock
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_USER: ${POSTGRES_USER:-postgres}
|
||||
MANA_CORE_AUTH_URL: http://mana-core-auth:3001
|
||||
CORS_ORIGINS: http://46.224.108.214:5187,http://localhost:5187
|
||||
ports:
|
||||
- "3017:3017"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3017/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"
|
||||
|
||||
clock-web:
|
||||
image: ${DOCKER_REGISTRY:-ghcr.io/memo-2023}/clock-web:${CLOCK_WEB_VERSION:-latest}
|
||||
container_name: clock-web-staging
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
clock-backend:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: staging
|
||||
PORT: 5187
|
||||
PUBLIC_BACKEND_URL: http://clock-backend:3017
|
||||
PUBLIC_MANA_CORE_AUTH_URL: http://mana-core-auth:3001
|
||||
PUBLIC_BACKEND_URL_CLIENT: http://46.224.108.214:3017
|
||||
PUBLIC_MANA_CORE_AUTH_URL_CLIENT: http://46.224.108.214:3001
|
||||
ports:
|
||||
- "5187:5187"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5187/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
|
||||
# ============================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue