diff --git a/docker-compose.local.yml b/docker-compose.local.yml new file mode 100644 index 0000000..66bd261 --- /dev/null +++ b/docker-compose.local.yml @@ -0,0 +1,159 @@ +version: '3.8' + +# =========================================== +# LOCAL NETWORK - Social Media Automation +# Acceso por IP local sin SSL +# Uso: docker-compose -f docker-compose.local.yml up -d +# =========================================== + +services: + app: + build: + context: . + dockerfile: Dockerfile + container_name: social-automation-app + ports: + - "8000:8000" + environment: + - DATABASE_URL=postgresql://${POSTGRES_USER:-social_user}:${POSTGRES_PASSWORD:-social_pass}@db:5432/${POSTGRES_DB:-social_automation} + - REDIS_URL=redis://redis:6379/0 + env_file: + - .env + volumes: + - ./app:/app/app + - ./dashboard:/app/dashboard + - uploaded_images:/app/uploads + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + restart: unless-stopped + networks: + - social-network + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + + worker: + build: + context: . + dockerfile: Dockerfile + container_name: social-automation-worker + command: celery -A app.worker.celery_app worker --loglevel=info --concurrency=2 + environment: + - DATABASE_URL=postgresql://${POSTGRES_USER:-social_user}:${POSTGRES_PASSWORD:-social_pass}@db:5432/${POSTGRES_DB:-social_automation} + - REDIS_URL=redis://redis:6379/0 + env_file: + - .env + volumes: + - ./app:/app/app + - uploaded_images:/app/uploads + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + restart: unless-stopped + networks: + - social-network + + beat: + build: + context: . + dockerfile: Dockerfile + container_name: social-automation-beat + command: celery -A app.worker.celery_app beat --loglevel=info + environment: + - DATABASE_URL=postgresql://${POSTGRES_USER:-social_user}:${POSTGRES_PASSWORD:-social_pass}@db:5432/${POSTGRES_DB:-social_automation} + - REDIS_URL=redis://redis:6379/0 + env_file: + - .env + volumes: + - ./app:/app/app + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + restart: unless-stopped + networks: + - social-network + + flower: + build: + context: . + dockerfile: Dockerfile + container_name: social-automation-flower + command: celery -A app.worker.celery_app flower --port=5555 + ports: + - "5555:5555" + environment: + - REDIS_URL=redis://redis:6379/0 + env_file: + - .env + depends_on: + - redis + - worker + restart: unless-stopped + networks: + - social-network + + db: + image: postgres:15-alpine + container_name: social-automation-db + environment: + - POSTGRES_USER=${POSTGRES_USER:-social_user} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-social_pass} + - POSTGRES_DB=${POSTGRES_DB:-social_automation} + volumes: + - postgres_data:/var/lib/postgresql/data + - ./backups:/backups + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-social_user}"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + networks: + - social-network + + redis: + image: redis:7-alpine + container_name: social-automation-redis + command: redis-server --appendonly yes + volumes: + - redis_data:/data + ports: + - "6379:6379" + restart: unless-stopped + networks: + - social-network + + nginx: + image: nginx:alpine + container_name: social-automation-nginx + ports: + - "80:80" + volumes: + - ./nginx/nginx.local.conf:/etc/nginx/nginx.conf:ro + - ./dashboard/static:/usr/share/nginx/html/static:ro + depends_on: + - app + restart: unless-stopped + networks: + - social-network + +volumes: + postgres_data: + redis_data: + uploaded_images: + +networks: + social-network: + driver: bridge diff --git a/nginx/nginx.local.conf b/nginx/nginx.local.conf new file mode 100644 index 0000000..97d6e3a --- /dev/null +++ b/nginx/nginx.local.conf @@ -0,0 +1,93 @@ +# =========================================== +# NGINX Configuration - Local Network Access +# Sin SSL, acceso directo por IP local +# =========================================== + +user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - [$time_local] "$request" $status $body_bytes_sent'; + access_log /var/log/nginx/access.log main; + + sendfile on; + keepalive_timeout 65; + + # Gzip + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml; + + # Upstreams + upstream app { + server app:8000; + keepalive 32; + } + + upstream flower { + server flower:5555; + } + + # HTTP Server (sin SSL) + server { + listen 80; + server_name _; + + client_max_body_size 10M; + + # Static files + location /static { + alias /usr/share/nginx/html/static; + expires 7d; + } + + # API + location /api { + proxy_pass http://app; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_connect_timeout 30s; + proxy_read_timeout 60s; + } + + # Dashboard + location /dashboard { + proxy_pass http://app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # Flower (Celery monitor) + location /flower/ { + proxy_pass http://flower/; + proxy_set_header Host $host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # Health check + location /health { + proxy_pass http://app/api/health; + } + + # Root + location / { + proxy_pass http://app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + } +}