mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 21:21:10 +02:00
🚀 feat(photos): add Docker deployment configuration
- Add Dockerfile for photos-backend (port 3039) - Add Dockerfile for photos-web (port 5019) - Add docker-entrypoint.sh for database migrations - Add health endpoint for photos-web - Add photos services to docker-compose.macmini.yml - Update CORS_ORIGINS for mana-auth and mana-media - Update CLAUDE.md with production URLs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
91f175c8f6
commit
5ce4e42c20
6 changed files with 278 additions and 7 deletions
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
**Photos** is a unified photo gallery application for the ManaCore ecosystem. It aggregates photos from all apps (Picture, Chat, Contacts, NutriPhi, etc.) via the mana-media service, providing a central place to view, organize, and manage photos.
|
||||
|
||||
| App | Port | URL |
|
||||
|-----|------|-----|
|
||||
| Backend | 3019 | http://localhost:3019 |
|
||||
| Web App | 5189 | http://localhost:5189 |
|
||||
| App | Dev Port | Prod Port | Prod URL |
|
||||
|-----|----------|-----------|----------|
|
||||
| Backend | 3019 | 3039 | https://photos-api.mana.how |
|
||||
| Web App | 5189 | 5019 | https://photos.mana.how |
|
||||
|
||||
## Project Structure
|
||||
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
apps/photos/
|
||||
├── apps/
|
||||
│ ├── backend/ # NestJS API server (@photos/backend)
|
||||
│ └── web/ # SvelteKit web application (@photos/web) [TODO]
|
||||
│ └── web/ # SvelteKit web application (@photos/web)
|
||||
├── packages/
|
||||
│ └── shared/ # Shared types (@photos/shared)
|
||||
├── package.json
|
||||
|
|
|
|||
88
apps/photos/apps/backend/Dockerfile
Normal file
88
apps/photos/apps/backend/Dockerfile
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
# 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 (all required dependencies)
|
||||
COPY packages/shared-errors ./packages/shared-errors
|
||||
COPY packages/shared-nestjs-auth ./packages/shared-nestjs-auth
|
||||
COPY packages/shared-nestjs-health ./packages/shared-nestjs-health
|
||||
COPY packages/shared-nestjs-metrics ./packages/shared-nestjs-metrics
|
||||
COPY packages/shared-nestjs-setup ./packages/shared-nestjs-setup
|
||||
COPY packages/shared-tsconfig ./packages/shared-tsconfig
|
||||
COPY packages/mana-core-nestjs-integration ./packages/mana-core-nestjs-integration
|
||||
COPY packages/shared-drizzle-config ./packages/shared-drizzle-config
|
||||
|
||||
# Copy photos shared package
|
||||
COPY apps/photos/packages/shared ./apps/photos/packages/shared
|
||||
|
||||
# Copy photos backend
|
||||
COPY apps/photos/apps/backend ./apps/photos/apps/backend
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages first (in dependency order)
|
||||
WORKDIR /app/packages/shared-errors
|
||||
RUN pnpm build
|
||||
|
||||
WORKDIR /app/packages/shared-nestjs-auth
|
||||
RUN pnpm build
|
||||
|
||||
WORKDIR /app/packages/shared-nestjs-health
|
||||
RUN pnpm build
|
||||
|
||||
WORKDIR /app/packages/shared-nestjs-metrics
|
||||
RUN pnpm build
|
||||
|
||||
WORKDIR /app/packages/shared-nestjs-setup
|
||||
RUN pnpm build
|
||||
|
||||
WORKDIR /app/packages/mana-core-nestjs-integration
|
||||
RUN pnpm build
|
||||
|
||||
# Build the backend
|
||||
WORKDIR /app/apps/photos/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/photos ./apps/photos
|
||||
|
||||
# Copy entrypoint script
|
||||
COPY apps/photos/apps/backend/docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
WORKDIR /app/apps/photos/apps/backend
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3039
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:3039/api/v1/health || exit 1
|
||||
|
||||
# Run entrypoint script
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
CMD ["node", "dist/main.js"]
|
||||
9
apps/photos/apps/backend/docker-entrypoint.sh
Normal file
9
apps/photos/apps/backend/docker-entrypoint.sh
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "📋 Running database migrations..."
|
||||
npx drizzle-kit push --config drizzle.config.ts --force || echo "⚠️ Migration failed, continuing anyway..."
|
||||
|
||||
# Start the application
|
||||
echo "🚀 Starting Photos Backend..."
|
||||
exec "$@"
|
||||
101
apps/photos/apps/web/Dockerfile
Normal file
101
apps/photos/apps/web/Dockerfile
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# Build arguments for SvelteKit static env vars
|
||||
ARG PUBLIC_BACKEND_URL=http://photos-backend:3039
|
||||
ARG PUBLIC_MANA_CORE_AUTH_URL=http://mana-core-auth:3001
|
||||
ARG PUBLIC_MANA_MEDIA_URL=http://mana-media:3015
|
||||
|
||||
# Set as environment variables for build
|
||||
ENV PUBLIC_BACKEND_URL=$PUBLIC_BACKEND_URL
|
||||
ENV PUBLIC_MANA_CORE_AUTH_URL=$PUBLIC_MANA_CORE_AUTH_URL
|
||||
ENV PUBLIC_MANA_MEDIA_URL=$PUBLIC_MANA_MEDIA_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 photos web
|
||||
COPY packages/shared-types ./packages/shared-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-help-content ./packages/shared-help-content
|
||||
COPY packages/shared-help-types ./packages/shared-help-types
|
||||
COPY packages/shared-help-ui ./packages/shared-help-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 packages/shared-tags ./packages/shared-tags
|
||||
COPY packages/shared-splitscreen ./packages/shared-splitscreen
|
||||
COPY packages/shared-vite-config ./packages/shared-vite-config
|
||||
COPY packages/shared-api-client ./packages/shared-api-client
|
||||
COPY packages/shared-stores ./packages/shared-stores
|
||||
|
||||
# Copy photos shared package
|
||||
COPY apps/photos/packages/shared ./apps/photos/packages/shared
|
||||
|
||||
# Copy photos web
|
||||
COPY apps/photos/apps/web ./apps/photos/apps/web
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build shared packages that need building
|
||||
WORKDIR /app/packages/shared-vite-config
|
||||
RUN pnpm build
|
||||
|
||||
WORKDIR /app/packages/shared-auth
|
||||
RUN pnpm build || true
|
||||
|
||||
# Build the web app
|
||||
WORKDIR /app/apps/photos/apps/web
|
||||
RUN pnpm exec svelte-kit sync
|
||||
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/photos/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/photos/apps/web/node_modules ./node_modules
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/apps/photos/apps/web/build ./build
|
||||
COPY --from=builder /app/apps/photos/apps/web/package.json ./
|
||||
|
||||
# Expose port
|
||||
EXPOSE 5019
|
||||
|
||||
# Set environment variables
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=5019
|
||||
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:5019/health || exit 1
|
||||
|
||||
# Run the app
|
||||
CMD ["node", "build"]
|
||||
10
apps/photos/apps/web/src/routes/health/+server.ts
Normal file
10
apps/photos/apps/web/src/routes/health/+server.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { json } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
export const GET: RequestHandler = async () => {
|
||||
return json({
|
||||
status: 'ok',
|
||||
service: 'photos-web',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
};
|
||||
|
|
@ -105,7 +105,7 @@ services:
|
|||
SMTP_USER: ${SMTP_USER:-94cde5002@smtp-brevo.com}
|
||||
SMTP_PASSWORD: ${SMTP_PASSWORD}
|
||||
SMTP_FROM: Mana <noreply@mana.how>
|
||||
CORS_ORIGINS: https://mana.how,https://chat.mana.how,https://todo.mana.how,https://calendar.mana.how,https://clock.mana.how,https://contacts.mana.how,https://storage.mana.how,https://presi.mana.how,https://nutriphi.mana.how,https://skilltree.mana.how,https://matrix.mana.how,https://element.mana.how,https://link.mana.how,https://playground.mana.how
|
||||
CORS_ORIGINS: https://mana.how,https://chat.mana.how,https://todo.mana.how,https://calendar.mana.how,https://clock.mana.how,https://contacts.mana.how,https://storage.mana.how,https://presi.mana.how,https://nutriphi.mana.how,https://skilltree.mana.how,https://photos.mana.how,https://matrix.mana.how,https://element.mana.how,https://link.mana.how,https://playground.mana.how
|
||||
DUCKDB_PATH: /data/analytics/metrics.duckdb
|
||||
SYNAPSE_OIDC_CLIENT_SECRET: ${SYNAPSE_OIDC_CLIENT_SECRET:-}
|
||||
volumes:
|
||||
|
|
@ -234,7 +234,7 @@ services:
|
|||
S3_PUBLIC_URL: https://media.mana.how
|
||||
MATRIX_HOMESERVER_URL: https://matrix.mana.how
|
||||
PUBLIC_URL: https://media.mana.how/api/v1
|
||||
CORS_ORIGINS: https://mana.how,https://nutriphi.mana.how,https://contacts.mana.how,https://chat.mana.how,https://storage.mana.how
|
||||
CORS_ORIGINS: https://mana.how,https://nutriphi.mana.how,https://contacts.mana.how,https://chat.mana.how,https://storage.mana.how,https://photos.mana.how
|
||||
ports:
|
||||
- "3015:3015"
|
||||
healthcheck:
|
||||
|
|
@ -485,6 +485,37 @@ services:
|
|||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
photos-backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/photos/apps/backend/Dockerfile
|
||||
image: photos-backend:local
|
||||
container_name: mana-app-photos-backend
|
||||
restart: always
|
||||
depends_on:
|
||||
mana-auth:
|
||||
condition: service_healthy
|
||||
mana-media:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 3039
|
||||
DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD:-mana123}@postgres:5432/photos
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_USER: postgres
|
||||
MANA_CORE_AUTH_URL: http://mana-auth:3001
|
||||
MANA_MEDIA_URL: http://mana-media:3015
|
||||
CORS_ORIGINS: https://photos.mana.how,https://mana.how
|
||||
ports:
|
||||
- "3039:3039"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3039/api/v1/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
# ============================================
|
||||
# Tier 4: Matrix Stack (Ports 4000-4099)
|
||||
# ============================================
|
||||
|
|
@ -1107,6 +1138,38 @@ services:
|
|||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
photos-web:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/photos/apps/web/Dockerfile
|
||||
args:
|
||||
PUBLIC_BACKEND_URL: http://photos-backend:3039
|
||||
PUBLIC_MANA_CORE_AUTH_URL: http://mana-auth:3001
|
||||
PUBLIC_MANA_MEDIA_URL: http://mana-media:3015
|
||||
image: photos-web:local
|
||||
container_name: mana-app-photos-web
|
||||
restart: always
|
||||
depends_on:
|
||||
photos-backend:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 5019
|
||||
PUBLIC_BACKEND_URL: http://photos-backend:3039
|
||||
PUBLIC_MANA_CORE_AUTH_URL: http://mana-auth:3001
|
||||
PUBLIC_MANA_MEDIA_URL: http://mana-media:3015
|
||||
PUBLIC_BACKEND_URL_CLIENT: https://photos-api.mana.how
|
||||
PUBLIC_MANA_CORE_AUTH_URL_CLIENT: https://auth.mana.how
|
||||
PUBLIC_MANA_MEDIA_URL_CLIENT: https://media.mana.how
|
||||
ports:
|
||||
- "5019:5019"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:5019/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
mana-llm:
|
||||
build:
|
||||
context: ./services/mana-llm
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue