Release: CI/CD Pipeline & Architecture Updates #177
@@ -80,12 +80,12 @@ WORKDIR /app/apps/api
|
||||
# Switch to non-root user
|
||||
USER nestjs
|
||||
|
||||
# Expose API port
|
||||
EXPOSE 3001
|
||||
# Expose API port (default 3001, can be overridden via PORT env var)
|
||||
EXPOSE ${PORT:-3001}
|
||||
|
||||
# Health check
|
||||
# Health check uses PORT env var (set by docker-compose or defaults to 3001)
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||
CMD node -e "require('http').get('http://localhost:3001/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
|
||||
CMD node -e "const port = process.env.PORT || 3001; require('http').get('http://localhost:' + port + '/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
|
||||
|
||||
# Use dumb-init to handle signals properly
|
||||
ENTRYPOINT ["dumb-init", "--"]
|
||||
|
||||
@@ -90,17 +90,16 @@ WORKDIR /app/apps/web
|
||||
# Switch to non-root user
|
||||
USER nextjs
|
||||
|
||||
# Expose web port
|
||||
EXPOSE 3000
|
||||
# Expose web port (default 3000, can be overridden via PORT env var)
|
||||
EXPOSE ${PORT:-3000}
|
||||
|
||||
# Environment variables
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME="0.0.0.0"
|
||||
|
||||
# Health check
|
||||
# Health check uses PORT env var (set by docker-compose or defaults to 3000)
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||
CMD node -e "require('http').get('http://localhost:3000', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
|
||||
CMD node -e "const port = process.env.PORT || 3000; require('http').get('http://localhost:' + port, (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
|
||||
|
||||
# Use dumb-init to handle signals properly
|
||||
ENTRYPOINT ["dumb-init", "--"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
version: '3.9'
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
# ======================
|
||||
@@ -149,7 +149,15 @@ services:
|
||||
authentik-redis:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9000/-/health/live/"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"wget",
|
||||
"--no-verbose",
|
||||
"--tries=1",
|
||||
"--spider",
|
||||
"http://localhost:9000/-/health/live/",
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -293,8 +301,8 @@ services:
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
# API Configuration
|
||||
API_PORT: ${API_PORT:-3001}
|
||||
# API Configuration - PORT is what NestJS reads
|
||||
PORT: ${API_PORT:-3001}
|
||||
API_HOST: ${API_HOST:-0.0.0.0}
|
||||
# Database
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER:-mosaic}:${POSTGRES_PASSWORD:-mosaic_dev_password}@postgres:5432/${POSTGRES_DB:-mosaic}
|
||||
@@ -311,14 +319,20 @@ services:
|
||||
# Ollama (optional)
|
||||
OLLAMA_ENDPOINT: ${OLLAMA_ENDPOINT:-http://ollama:11434}
|
||||
ports:
|
||||
- "${API_PORT:-3001}:3001"
|
||||
- "${API_PORT:-3001}:${API_PORT:-3001}"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
valkey:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3001/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"sh",
|
||||
"-c",
|
||||
'node -e "require(''http'').get(''http://localhost:${PORT:-3001}/health'', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"',
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -334,7 +348,7 @@ services:
|
||||
- "traefik.http.routers.mosaic-api.rule=Host(`${MOSAIC_API_DOMAIN:-api.mosaic.local}`)"
|
||||
- "traefik.http.routers.mosaic-api.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}"
|
||||
- "traefik.http.routers.mosaic-api.tls=${TRAEFIK_TLS_ENABLED:-true}"
|
||||
- "traefik.http.services.mosaic-api.loadbalancer.server.port=3001"
|
||||
- "traefik.http.services.mosaic-api.loadbalancer.server.port=${API_PORT:-3001}"
|
||||
- "traefik.docker.network=${TRAEFIK_DOCKER_NETWORK:-mosaic-public}"
|
||||
# Let's Encrypt (if enabled)
|
||||
- "traefik.http.routers.mosaic-api.tls.certresolver=${TRAEFIK_CERTRESOLVER:-}"
|
||||
@@ -352,14 +366,21 @@ services:
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: ${WEB_PORT:-3000}
|
||||
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:3001}
|
||||
ports:
|
||||
- "${WEB_PORT:-3000}:3000"
|
||||
- "${WEB_PORT:-3000}:${WEB_PORT:-3000}"
|
||||
depends_on:
|
||||
api:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"sh",
|
||||
"-c",
|
||||
'node -e "require(''http'').get(''http://localhost:${PORT:-3000}'', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"',
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -374,7 +395,7 @@ services:
|
||||
- "traefik.http.routers.mosaic-web.rule=Host(`${MOSAIC_WEB_DOMAIN:-mosaic.local}`)"
|
||||
- "traefik.http.routers.mosaic-web.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}"
|
||||
- "traefik.http.routers.mosaic-web.tls=${TRAEFIK_TLS_ENABLED:-true}"
|
||||
- "traefik.http.services.mosaic-web.loadbalancer.server.port=3000"
|
||||
- "traefik.http.services.mosaic-web.loadbalancer.server.port=${WEB_PORT:-3000}"
|
||||
- "traefik.docker.network=${TRAEFIK_DOCKER_NETWORK:-mosaic-public}"
|
||||
# Let's Encrypt (if enabled)
|
||||
- "traefik.http.routers.mosaic-web.tls.certresolver=${TRAEFIK_CERTRESOLVER:-}"
|
||||
|
||||
Reference in New Issue
Block a user