From 09e6262c43ae8d8a77f7431744b8b43423267ca4 Mon Sep 17 00:00:00 2001 From: "edgar.mendez" Date: Mon, 30 Mar 2026 18:52:23 -0600 Subject: [PATCH] feat: add production environment configuration files for Docker setup --- Docker/Prod/.env.prod.example | 95 ++++++++++++++++++++++ Docker/Prod/docker-compose.yml | 25 +++--- Docker/Prod/dockerfile | 11 ++- Docker/Prod/nginx.conf | 144 +++++++++++++++++++++++++++++++++ 4 files changed, 261 insertions(+), 14 deletions(-) create mode 100644 Docker/Prod/.env.prod.example create mode 100644 Docker/Prod/nginx.conf diff --git a/Docker/Prod/.env.prod.example b/Docker/Prod/.env.prod.example new file mode 100644 index 0000000..c0a1044 --- /dev/null +++ b/Docker/Prod/.env.prod.example @@ -0,0 +1,95 @@ +APP_NAME="Holos" +APP_ENV=local +APP_KEY=base64:uMMHuP+HxJHF0MBovjSbbQTU0ySevqr87TD+SkelsoU= +APP_DEBUG=true +APP_TIMEZONE=America/Mexico_City +APP_URL=http://backend.holos.test +APP_FRONTEND_URL=http://localhost:7000 +APP_PAGINATION=25 + +APP_LOCALE=es +APP_FALLBACK_LOCALE=es +APP_FAKER_LOCALE=es_MX + +APP_MAINTENANCE_DRIVER=file +# APP_MAINTENANCE_STORE=database + +CORS_ALLOWED_ORIGINS=* + +PULSE_ENABLED=false +TELESCOPE_ENABLED=false + +PHP_CLI_SERVER_WORKERS=4 + +BCRYPT_ROUNDS=12 + +LOG_CHANNEL=stack +LOG_STACK=single +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=mysql +DB_HOST=repuve-mysql-prod +DB_PORT=3306 +DB_PORT_FORWARD=3308 +DB_DATABASE=repuve-prod +DB_USERNAME=laravel +DB_PASSWORD=secret +DB_ROOT_PASSWORD=root123.. + +NGINX_PORT=7001 # Puerto para Nginx + +SESSION_DRIVER=database +SESSION_LIFETIME=120 +SESSION_ENCRYPT=false +SESSION_PATH=/ +SESSION_DOMAIN=null + +BROADCAST_CONNECTION=reverb +FILESYSTEM_DISK=local +QUEUE_CONNECTION=database + +CACHE_STORE=database +CACHE_PREFIX= + +MEMCACHED_HOST=127.0.0.1 + +REDIS_CLIENT=phpredis +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=mail.smtp2go.com +MAIL_PORT=465 +MAIL_DOMAIN=notsoweb.com +MAIL_USERNAME=no-reply@notsoweb.com +MAIL_PASSWORD= +MAIL_ENCRYPTION=ssl +MAIL_FROM_ADDRESS="no-reply@notsoweb.com" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +REVERB_APP_ID= +REVERB_APP_KEY= +REVERB_APP_SECRET= +REVERB_HOST="localhost" +REVERB_PORT=8080 +REVERB_SCHEME=http + +VITE_APP_NAME="${APP_NAME}" +VITE_REVERB_APP_KEY="${REVERB_APP_KEY}" +VITE_REVERB_HOST="${REVERB_HOST}" +VITE_REVERB_PORT="${REVERB_PORT}" +VITE_REVERB_SCHEME="${REVERB_SCHEME}" + +REPUVE_FED_BASE_URL=http://10.241.76.15:8012 +REPUVE_FED_USERNAME=u2701595 +REPUVE_FED_PASSWORD=vWaxDyH3 + +REPUVE_EST_URL=http://10.14.3.24:8080/repuve/consultaPadronVehicularPort diff --git a/Docker/Prod/docker-compose.yml b/Docker/Prod/docker-compose.yml index e27e77d..11d78e8 100644 --- a/Docker/Prod/docker-compose.yml +++ b/Docker/Prod/docker-compose.yml @@ -1,13 +1,14 @@ name: repuve-backend-prod services: repuve-backend: + container_name: backend-prod build: context: ../../ - dockerfile: Docker/Prod/dockerfile + dockerfile: Docker/Dev/dockerfile working_dir: /var/www/repuve-backend-v1 environment: - - APP_ENV=production - - APP_DEBUG=false + - APP_ENV=development + - APP_DEBUG=true - APP_KEY=${APP_KEY} - DB_HOST=mysql - DB_USERNAME=${DB_USERNAME} @@ -17,7 +18,7 @@ services: volumes: - ../../storage:/var/www/repuve-backend-v1/storage networks: - - repuve-network + - repuve-prod-network mem_limit: 512M restart: unless-stopped depends_on: @@ -25,9 +26,10 @@ services: condition: service_healthy nginx: + container_name: repuve-nginx-prod image: nginx:alpine ports: - - "127.0.0.1:${NGINX_PORT}:80" + - "${NGINX_PORT}:80" volumes: - ../../public:/var/www/repuve-backend-v1/public - ../../storage:/var/www/repuve-backend-v1/storage @@ -39,24 +41,27 @@ services: max-size: "50m" max-file: "10" networks: - - repuve-network - mem_limit: 256m + - repuve-prod-network + mem_limit: 128M restart: unless-stopped depends_on: - repuve-backend mysql: + container_name: repuve-mysql-prod image: mysql:8.0 environment: MYSQL_DATABASE: ${DB_DATABASE} MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_USER: ${DB_USERNAME} + ports: + - "${DB_PORT_FORWARD}:3306" volumes: - mysql_data:/var/lib/mysql networks: - - repuve-network - mem_limit: 512m + - repuve-prod-network + mem_limit: 512M restart: unless-stopped healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] @@ -68,5 +73,5 @@ volumes: driver: local networks: - repuve-network: + repuve-prod-network: driver: bridge diff --git a/Docker/Prod/dockerfile b/Docker/Prod/dockerfile index 95b7b08..315e6be 100644 --- a/Docker/Prod/dockerfile +++ b/Docker/Prod/dockerfile @@ -3,6 +3,7 @@ FROM php:8.3-fpm-alpine WORKDIR /var/www/repuve-backend-v1 RUN apk add --no-cache \ + git \ curl \ libpng-dev \ oniguruma-dev \ @@ -10,8 +11,10 @@ RUN apk add --no-cache \ zip \ unzip \ libzip-dev \ + nano \ openssl \ bash \ + mysql-client \ libreoffice \ ttf-dejavu \ supervisor \ @@ -23,12 +26,12 @@ COPY --from=composer:latest /usr/bin/composer /usr/bin/composer COPY composer.json composer.lock ./ -RUN composer install --optimize-autoloader --no-interaction --no-scripts --no-dev +RUN composer install --optimize-autoloader --no-interaction --no-scripts COPY . . -COPY entrypoint-prod.sh /usr/local/bin/entrypoint-prod.sh -RUN chmod +x /usr/local/bin/entrypoint-prod.sh +COPY entrypoint-dev.sh /usr/local/bin/entrypoint-dev.sh +RUN chmod +x /usr/local/bin/entrypoint-dev.sh COPY Docker/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf RUN mkdir -p /var/log/supervisor @@ -40,5 +43,5 @@ RUN chmod -R 775 /var/www/repuve-backend-v1/storage /var/www/repuve-backend-v1/b EXPOSE 9000 -ENTRYPOINT ["/usr/local/bin/entrypoint-prod.sh"] +ENTRYPOINT ["/usr/local/bin/entrypoint-dev.sh"] CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] diff --git a/Docker/Prod/nginx.conf b/Docker/Prod/nginx.conf new file mode 100644 index 0000000..97eed02 --- /dev/null +++ b/Docker/Prod/nginx.conf @@ -0,0 +1,144 @@ +user nginx; +worker_processes auto; + +# Log de errores con máximo nivel de detalle +error_log /var/log/nginx/error.log debug; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # ─── FORMATO DE LOG FORENSE EXTENDIDO ─────────────────────────────────────── + log_format forensic_main + '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '"$http_x_forwarded_for" "$http_x_real_ip" ' + 'rt=$request_time ' # Tiempo total de la petición + 'uct="$upstream_connect_time" ' # Tiempo de conexión upstream + 'uht="$upstream_header_time" ' # Tiempo de cabeceras upstream + 'urt="$upstream_response_time" ' # Tiempo de respuesta upstream + 'cs=$upstream_cache_status ' # Estado de caché + 'ssl_protocol="$ssl_protocol" ' # Protocolo SSL usado + 'ssl_cipher="$ssl_cipher" ' # Cifrado SSL + 'ssl_session_id="$ssl_session_id" ' # ID sesión TLS (rastreo) + 'conn=$connection ' # ID de conexión + 'conn_reqs=$connection_requests ' # Peticiones por conexión + 'pipe=$pipe ' # Pipelining (y/n) + 'host="$host" ' # Host solicitado + 'server_name="$server_name" ' + 'scheme="$scheme" ' + 'request_method="$request_method" ' + 'request_uri="$request_uri" ' + 'server_port="$server_port" ' + 'http_version="$server_protocol" ' + 'bytes_sent=$bytes_sent ' # Total bytes enviados + 'request_length=$request_length ' # Tamaño de la petición + 'req_id="$request_id"'; # ID único por petición + + # Formato adicional para headers sensibles / seguridad + log_format forensic_headers + '$remote_addr [$time_local] req_id="$request_id" ' + 'Authorization="$http_authorization" ' + 'Cookie="$http_cookie" ' + 'Content-Type="$content_type" ' + 'Content-Length="$content_length" ' + 'Accept="$http_accept" ' + 'Accept-Language="$http_accept_language" ' + 'Accept-Encoding="$http_accept_encoding" ' + 'Origin="$http_origin" ' + 'Sec-Fetch-Site="$http_sec_fetch_site" ' + 'Sec-Fetch-Mode="$http_sec_fetch_mode" ' + 'Sec-Fetch-Dest="$http_sec_fetch_dest" ' + 'X-Custom-Header="$http_x_custom_header"'; + + # ─── ARCHIVOS DE LOG ──────────────────────────────────────────────────────── + access_log /var/log/nginx/access.log forensic_main buffer=16k flush=1s; + access_log /var/log/nginx/headers.log forensic_headers buffer=16k flush=1s; + error_log /var/log/nginx/error.log debug; + + # ─── OPCIONES GENERALES ───────────────────────────────────────────────────── + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + server_tokens off; # No revelar versión en respuestas (buena práctica) + + # Añadir request_id único a cada petición + add_header X-Request-ID $request_id always; + + # ─── SERVER BLOCK LARAVEL ─────────────────────────────────────────────────── + server { + listen 80; + server_name _; + root /var/www/repuve-backend-v1/public; + index index.php index.html; + + # Logging con formatos forenses (definidos en nginx.conf principal) + error_log /var/log/nginx/error.log debug; + access_log /var/log/nginx/access.log forensic_main; + + # Handle Laravel routes (Front Controller) + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + # Handle PHP files + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass backend-dev:9000; + fastcgi_index index.php; + + # Timeouts importantes para evitar errores 500 + fastcgi_read_timeout 300; + fastcgi_connect_timeout 300; + fastcgi_send_timeout 300; + + # Carga los parámetros por defecto + include fastcgi_params; + + # Parámetros críticos para Laravel + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param CONTENT_LENGTH $content_length; + fastcgi_param HTTP_HOST $http_host; + fastcgi_param HTTPS $https if_not_empty; + fastcgi_param HTTP_PROXY ""; + + # Añadir Request ID al backend para tracking + fastcgi_param HTTP_X_REQUEST_ID $request_id; + } + + client_max_body_size 150M; + + # Handle storage files (Laravel storage link) + location /storage/ { + alias /var/www/repuve-backend-v1/storage/app/public/; + } + + location /profile { + alias /var/www/repuve-backend-v1/storage/app/profile; + try_files $uri =404; + } + + location /images { + alias /var/www/repuve-backend-v1/storage/app/images; + try_files $uri =404; + } + + # Denegar acceso a archivos ocultos como .htaccess + location ~ /\.ht { + deny all; + } +} +}