more restructuring
This commit is contained in:
71
cfg/amar/ctrl/Dockerfile.backend
Normal file
71
cfg/amar/ctrl/Dockerfile.backend
Normal file
@@ -0,0 +1,71 @@
|
||||
# =============================================================================
|
||||
# Dockerfile for Django Backend with Uvicorn
|
||||
# =============================================================================
|
||||
# Usage:
|
||||
# Development: WORKERS=1 RELOAD=--reload (source mounted, hot reload)
|
||||
# Production: WORKERS=4 RELOAD="" (no reload, multiple workers)
|
||||
|
||||
# =============================================================================
|
||||
# Stage 1: Base with system dependencies
|
||||
# =============================================================================
|
||||
FROM python:3.11-slim AS base
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies (cached layer)
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
libpq-dev \
|
||||
gdal-bin \
|
||||
libgdal-dev \
|
||||
libgeos-dev \
|
||||
libproj-dev \
|
||||
postgresql-client \
|
||||
# WeasyPrint dependencies (for django-afip PDF generation)
|
||||
libglib2.0-0 \
|
||||
libpango-1.0-0 \
|
||||
libpangocairo-1.0-0 \
|
||||
libgdk-pixbuf-2.0-0 \
|
||||
libffi-dev \
|
||||
libcairo2 \
|
||||
libgirepository1.0-dev \
|
||||
gir1.2-pango-1.0 \
|
||||
fonts-dejavu-core \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# =============================================================================
|
||||
# Stage 2: Dependencies (cached layer)
|
||||
# =============================================================================
|
||||
FROM base AS deps
|
||||
|
||||
# Copy only requirements for dependency installation
|
||||
COPY requirements.txt .
|
||||
|
||||
# Install Python dependencies
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# =============================================================================
|
||||
# Stage 3: Runtime (uvicorn with configurable workers)
|
||||
# =============================================================================
|
||||
FROM base AS runtime
|
||||
|
||||
# Copy dependencies from deps stage
|
||||
COPY --from=deps /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
|
||||
COPY --from=deps /usr/local/bin /usr/local/bin
|
||||
|
||||
# Copy requirements (for reference)
|
||||
COPY requirements.txt .
|
||||
|
||||
# Create directories
|
||||
RUN mkdir -p /var/etc/static /app/media
|
||||
|
||||
# Note: Source code mounted at runtime for dev, copied for prod
|
||||
EXPOSE 8000
|
||||
|
||||
# Uvicorn with configurable workers and reload
|
||||
# Dev: WORKERS=1 RELOAD=--reload
|
||||
# Prod: WORKERS=4 RELOAD=""
|
||||
CMD uvicorn amar_django_back.asgi:application --host 0.0.0.0 --port 8000 --workers ${WORKERS:-1} ${RELOAD}
|
||||
80
cfg/amar/ctrl/Dockerfile.frontend
Normal file
80
cfg/amar/ctrl/Dockerfile.frontend
Normal file
@@ -0,0 +1,80 @@
|
||||
# =============================================================================
|
||||
# Multi-stage Dockerfile for Next.js Frontend
|
||||
# =============================================================================
|
||||
# Usage:
|
||||
# Development: docker compose up (mounts source, hot reload)
|
||||
# Production: docker compose -f docker-compose.yml -f docker-compose.prod.yml up
|
||||
|
||||
# =============================================================================
|
||||
# Stage 1: Dependencies (cached layer)
|
||||
# =============================================================================
|
||||
FROM node:18-alpine AS deps
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy only package files for dependency installation
|
||||
COPY package*.json ./
|
||||
|
||||
# Install ALL dependencies (including devDependencies for dev mode)
|
||||
RUN npm ci
|
||||
|
||||
# =============================================================================
|
||||
# Stage 2: Development (hot reload, source mounted)
|
||||
# =============================================================================
|
||||
FROM node:18-alpine AS development
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy dependencies from deps stage
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
|
||||
# Copy package files (for npm scripts)
|
||||
COPY package*.json ./
|
||||
|
||||
# Copy config files
|
||||
COPY next.config.js postcss.config.js tailwind.config.js tsconfig.json ./
|
||||
|
||||
# Note: src/ and public/ are mounted at runtime for hot reload
|
||||
# Start dev server
|
||||
EXPOSE 3000
|
||||
CMD ["npm", "run", "dev"]
|
||||
|
||||
# =============================================================================
|
||||
# Stage 3: Builder (compile for production)
|
||||
# =============================================================================
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy dependencies
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
|
||||
# Copy all source files
|
||||
COPY . .
|
||||
|
||||
# Build for production
|
||||
RUN npm run build
|
||||
|
||||
# =============================================================================
|
||||
# Stage 4: Production (optimized, minimal)
|
||||
# =============================================================================
|
||||
FROM node:18-alpine AS production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# Copy only production dependencies
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production && npm cache clean --force
|
||||
|
||||
# Copy built application from builder
|
||||
COPY --from=builder /app/.next ./.next
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/next.config.js ./
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
USER node
|
||||
|
||||
CMD ["npm", "run", "start"]
|
||||
202
cfg/amar/ctrl/docker-compose.managed.yml
Normal file
202
cfg/amar/ctrl/docker-compose.managed.yml
Normal file
@@ -0,0 +1,202 @@
|
||||
# Amar Room - Docker Compose
|
||||
#
|
||||
# Creates: db, redis, backend, celery, celery-beat, frontend
|
||||
# Network: Joins external network defined by NETWORK_NAME
|
||||
#
|
||||
# Usage:
|
||||
# cd cfg/amar && docker compose up -d
|
||||
#
|
||||
# Required Environment Variables (from .env):
|
||||
# - DEPLOYMENT_NAME: Prefix for container names
|
||||
# - NETWORK_NAME: Network to join
|
||||
# - BACKEND_PATH, FRONTEND_PATH: Source code paths (absolute)
|
||||
# - DOCKERFILE_BACKEND, DOCKERFILE_FRONTEND: Dockerfile paths (absolute)
|
||||
# - DB_DUMP: Database dump file (relative to dumps/)
|
||||
# - Plus all app-specific vars (POSTGRES_*, etc.)
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgis/postgis:15-3.4
|
||||
container_name: ${DEPLOYMENT_NAME}_db
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
# Database dump loaded on init (if volume is empty)
|
||||
- ./dumps/${DB_DUMP}:/docker-entrypoint-initdb.d/dump.sql:ro
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- default
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: ${DEPLOYMENT_NAME}_redis
|
||||
volumes:
|
||||
- redisdata:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- default
|
||||
|
||||
backend:
|
||||
build:
|
||||
context: ${BACKEND_PATH}
|
||||
dockerfile: ${DOCKERFILE_BACKEND}
|
||||
target: runtime
|
||||
container_name: ${DEPLOYMENT_NAME}_backend
|
||||
environment:
|
||||
- SECRET_KEY
|
||||
- DEBUG
|
||||
- ALLOWED_HOSTS
|
||||
- DJANGO_ENV
|
||||
- DB_NAME=${POSTGRES_DB}
|
||||
- DB_USER=${POSTGRES_USER}
|
||||
- DB_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DB_HOST=db
|
||||
- DB_PORT=5432
|
||||
- CELERY_BROKER_URL=redis://redis:6379/0
|
||||
- CELERY_RESULT_BACKEND=redis://redis:6379/0
|
||||
- CORS_ALLOW_ALL
|
||||
- CORS_ALLOWED_ORIGINS
|
||||
# Uvicorn config (dev: 1 worker + reload, prod: 4 workers)
|
||||
- WORKERS=${BACKEND_WORKERS:-1}
|
||||
- RELOAD=${BACKEND_RELOAD:---reload}
|
||||
# Google
|
||||
- SUBJECT_CALENDAR
|
||||
- SHEET_ID
|
||||
- RANGE_NAME
|
||||
- GOOGLE_MAPS_API_KEY
|
||||
# Analytics
|
||||
- GA4_MEASUREMENT_ID
|
||||
- AMPLITUDE_API_KEY
|
||||
- HOTJAR_API_KEY
|
||||
# Payments
|
||||
- ACCESS_TOKEN_MERCADO_PAGO
|
||||
- MP_PLATFORM_ACCESS_TOKEN
|
||||
- USER_ID
|
||||
# Push
|
||||
- WEBPUSH_VAPID_PUBLIC_KEY
|
||||
- WEBPUSH_VAPID_PRIVATE_KEY
|
||||
- WEBPUSH_VAPID_ADMIN_EMAIL
|
||||
# Init
|
||||
- USER_PASSWORD
|
||||
volumes:
|
||||
- ${BACKEND_PATH}:/app
|
||||
- backend_static:/var/etc/static
|
||||
- backend_media:/app/media
|
||||
ports:
|
||||
- "${BACKEND_PORT}:8000"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- default
|
||||
command: >
|
||||
sh -c "python manage.py migrate --noinput &&
|
||||
uvicorn amar_django_back.asgi:application --host 0.0.0.0 --port 8000 --workers $${WORKERS:-1} $${RELOAD}"
|
||||
|
||||
celery:
|
||||
build:
|
||||
context: ${BACKEND_PATH}
|
||||
dockerfile: ${DOCKERFILE_BACKEND}
|
||||
target: runtime
|
||||
container_name: ${DEPLOYMENT_NAME}_celery
|
||||
environment:
|
||||
- SECRET_KEY
|
||||
- DEBUG
|
||||
- DJANGO_ENV
|
||||
- DB_NAME=${POSTGRES_DB}
|
||||
- DB_USER=${POSTGRES_USER}
|
||||
- DB_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DB_HOST=db
|
||||
- DB_PORT=5432
|
||||
- CELERY_BROKER_URL=redis://redis:6379/0
|
||||
- CELERY_RESULT_BACKEND=redis://redis:6379/0
|
||||
volumes:
|
||||
- ${BACKEND_PATH}:/app
|
||||
- backend_media:/app/media
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- default
|
||||
command: celery -A amar_django_back worker -l INFO
|
||||
|
||||
celery-beat:
|
||||
build:
|
||||
context: ${BACKEND_PATH}
|
||||
dockerfile: ${DOCKERFILE_BACKEND}
|
||||
target: runtime
|
||||
container_name: ${DEPLOYMENT_NAME}_celery_beat
|
||||
environment:
|
||||
- SECRET_KEY
|
||||
- DEBUG
|
||||
- DJANGO_ENV
|
||||
- DB_NAME=${POSTGRES_DB}
|
||||
- DB_USER=${POSTGRES_USER}
|
||||
- DB_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- DB_HOST=db
|
||||
- DB_PORT=5432
|
||||
- CELERY_BROKER_URL=redis://redis:6379/0
|
||||
- CELERY_RESULT_BACKEND=redis://redis:6379/0
|
||||
volumes:
|
||||
- ${BACKEND_PATH}:/app
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- default
|
||||
command: celery -A amar_django_back beat -l INFO
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ${FRONTEND_PATH}
|
||||
dockerfile: ${DOCKERFILE_FRONTEND}
|
||||
target: development
|
||||
container_name: ${DEPLOYMENT_NAME}_frontend
|
||||
environment:
|
||||
- NEXT_PUBLIC_APP_API_URL_BACKOFFICE
|
||||
- NEXT_PUBLIC_APP_API_URL_STAGE
|
||||
- NEXT_PUBLIC_IS_STAGE
|
||||
- NEXT_PUBLIC_FB_PIXEL_ID
|
||||
- NEXT_PUBLIC_TAG_MANAGER
|
||||
- NEXT_PUBLIC_WHATSAPP_CONTACT
|
||||
- NEXT_PUBLIC_API_KEY
|
||||
- NEXT_PUBLIC_AMPLITUDE_API_KEY
|
||||
- NEXT_PUBLIC_GMAPS_API_KEY
|
||||
volumes:
|
||||
- ${FRONTEND_PATH}/src:/app/src
|
||||
- ${FRONTEND_PATH}/public:/app/public
|
||||
ports:
|
||||
- "${FRONTEND_PORT}:3000"
|
||||
depends_on:
|
||||
- backend
|
||||
networks:
|
||||
- default
|
||||
# CMD from Dockerfile.frontend development stage: npm run dev
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
redisdata:
|
||||
backend_static:
|
||||
backend_media:
|
||||
|
||||
networks:
|
||||
default:
|
||||
external: true
|
||||
name: ${NETWORK_NAME}
|
||||
Reference in New Issue
Block a user