feat: Add staging environment for local production testing
- Add docker-compose.staging.yml with PostgreSQL and Django - Add .env.staging.example with staging-specific environment variables - Configure staging settings (DEBUG=False, no SSL redirect for localhost) - Update settings/__init__.py to support staging environment detection - Update AGENTS.md with staging environment documentation - Update .gitignore to exclude .env.staging - Optimize docker-compose.prod.yml configuration Staging environment simulates production configuration locally: - PostgreSQL database (port 5433 to avoid conflicts) - Gunicorn with 4 workers - DEBUG=False but HTTP allowed for easier testing - Separate volumes for static files, media, and logs Usage: cp .env.staging.example .env.staging docker compose -f docker-compose.staging.yml up -d
This commit is contained in:
51
.env.staging.example
Normal file
51
.env.staging.example
Normal file
@@ -0,0 +1,51 @@
|
||||
# Staging Environment Variables
|
||||
# Testing de producción en localhost sin SSL
|
||||
# Este ambiente simula producción pero permite HTTP en localhost
|
||||
|
||||
# Django Environment
|
||||
DJANGO_ENV=staging
|
||||
|
||||
# Debug mode (False para simular producción)
|
||||
DEBUG=False
|
||||
|
||||
# Django Secret Key
|
||||
# Para staging local, puedes usar una key fija (NO usar en producción real)
|
||||
SECRET_KEY=staging-local-key-zh6rinl@8y7g(cf781snisx2j%p^c#d&b2@@9cqe!v@4yv8x=v
|
||||
|
||||
# Allowed hosts (localhost para testing)
|
||||
ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0
|
||||
|
||||
# CORS allowed origins (permite acceso desde navegador local)
|
||||
# Incluye común puertos de desarrollo de frontend y acceso directo
|
||||
CORS_ALLOWED_ORIGINS=http://localhost:8000,http://localhost:3000,http://localhost:5173,http://localhost:7001,http://127.0.0.1:8000
|
||||
|
||||
# CSRF Trusted Origins (localhost HTTP para staging)
|
||||
CSRF_TRUSTED_ORIGINS=http://localhost:8000,http://127.0.0.1:8000
|
||||
|
||||
# PostgreSQL Database Configuration (staging local)
|
||||
DB_NAME=tienda_ilusion_staging
|
||||
DB_USER=tienda_ilusion_user
|
||||
DB_PASSWORD=staging_local_password
|
||||
DB_HOST=postgres
|
||||
DB_PORT=5432
|
||||
|
||||
# Email Configuration (console backend para staging)
|
||||
EMAIL_HOST=smtp.gmail.com
|
||||
EMAIL_PORT=587
|
||||
EMAIL_USE_TLS=True
|
||||
EMAIL_HOST_USER=staging@tiendailusion.local
|
||||
EMAIL_HOST_PASSWORD=staging_password
|
||||
DEFAULT_FROM_EMAIL=staging@tiendailusion.local
|
||||
|
||||
# Admin notifications
|
||||
ADMIN_EMAIL=admin@tiendailusion.local
|
||||
|
||||
# Tryton ERP Configuration (Staging)
|
||||
# Ajusta estos valores según tu entorno de staging de Tryton
|
||||
TRYTON_HOST=localhost
|
||||
TRYTON_DATABASE=tryton_staging
|
||||
TRYTON_USERNAME=admin
|
||||
TRYTON_PASSWORD=admin
|
||||
|
||||
# Staging specific: Disable SSL redirect for localhost testing
|
||||
STAGING_DISABLE_SSL=True
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -363,3 +363,4 @@ pgdata/
|
||||
# IDE-specific
|
||||
.vscode/
|
||||
.idea/
|
||||
.env.staging
|
||||
|
||||
72
AGENTS.md
72
AGENTS.md
@@ -8,9 +8,11 @@ Backend Django con Django REST Framework
|
||||
don_confiao_backend/
|
||||
├── requirements.txt # Dependencias Python
|
||||
├── docker-compose.dev.yml # Docker Compose para desarrollo
|
||||
├── docker-compose.staging.yml # Docker Compose para staging (testing producción local)
|
||||
├── docker-compose.prod.yml # Docker Compose para producción
|
||||
├── django.Dockerfile # Dockerfile Django
|
||||
├── .env.development # Variables de entorno desarrollo
|
||||
├── .env.staging # Variables de entorno staging
|
||||
├── .env.production.example # Ejemplo variables de entorno producción
|
||||
├── .env_example # Ejemplo de variables de entorno
|
||||
├── README.rst # Documentación básica
|
||||
@@ -42,6 +44,7 @@ don_confiao_backend/
|
||||
│ ├── __init__.py # Detección automática de ambiente
|
||||
│ ├── base.py # Configuración compartida
|
||||
│ ├── development.py # Configuración desarrollo
|
||||
│ ├── staging.py # Configuración staging
|
||||
│ └── production.py # Configuración producción
|
||||
├── urls.py
|
||||
├── wsgi.py
|
||||
@@ -86,20 +89,43 @@ El proyecto se ejecuta con docker-compose. Todos los comandos `manage.py` deben
|
||||
|
||||
```bash
|
||||
# Ejecutar tests
|
||||
docker-compose -f docker-compose.dev.yml run --rm django python manage.py test
|
||||
docker compose -f docker-compose.dev.yml run --rm django python manage.py test
|
||||
|
||||
# Migraciones
|
||||
docker-compose -f docker-compose.dev.yml run --rm django python manage.py makemigrations
|
||||
docker-compose -f docker-compose.dev.yml run --rm django python manage.py migrate
|
||||
docker compose -f docker-compose.dev.yml run --rm django python manage.py makemigrations
|
||||
docker compose -f docker-compose.dev.yml run --rm django python manage.py migrate
|
||||
|
||||
# Servidor desarrollo
|
||||
docker-compose -f docker-compose.dev.yml up
|
||||
docker compose -f docker-compose.dev.yml up
|
||||
|
||||
# Shell Django
|
||||
docker-compose -f docker-compose.dev.yml run --rm django python manage.py shell
|
||||
docker compose -f docker-compose.dev.yml run --rm django python manage.py shell
|
||||
|
||||
# Crear superuser
|
||||
docker-compose -f docker-compose.dev.yml run --rm django python manage.py createsuperuser
|
||||
docker compose -f docker-compose.dev.yml run --rm django python manage.py createsuperuser
|
||||
```
|
||||
|
||||
### Staging (Testing Producción Local)
|
||||
|
||||
```bash
|
||||
# Iniciar servicios (PostgreSQL + Django con Gunicorn)
|
||||
# Ya incluye el archivo .env.staging, listo para usar
|
||||
docker compose -f docker-compose.staging.yml up -d
|
||||
|
||||
# Migraciones
|
||||
docker compose -f docker-compose.staging.yml run --rm django python manage.py migrate
|
||||
|
||||
# Colectar archivos estáticos
|
||||
docker compose -f docker-compose.staging.yml run --rm django python manage.py collectstatic --noinput
|
||||
|
||||
# Crear superuser
|
||||
docker compose -f docker-compose.staging.yml run --rm django python manage.py createsuperuser
|
||||
|
||||
# Ver logs
|
||||
docker compose -f docker-compose.staging.yml logs -f django
|
||||
|
||||
# Detener servicios
|
||||
docker compose -f docker-compose.staging.yml down
|
||||
```
|
||||
|
||||
### Producción (Production)
|
||||
@@ -110,22 +136,22 @@ cp .env.production.example .env.production
|
||||
# Editar .env.production con valores reales
|
||||
|
||||
# Iniciar servicios (PostgreSQL + Django con Gunicorn)
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
|
||||
# Migraciones
|
||||
docker-compose -f docker-compose.prod.yml run --rm django python manage.py migrate
|
||||
docker compose -f docker-compose.prod.yml run --rm django python manage.py migrate
|
||||
|
||||
# Colectar archivos estáticos
|
||||
docker-compose -f docker-compose.prod.yml run --rm django python manage.py collectstatic --noinput
|
||||
docker compose -f docker-compose.prod.yml run --rm django python manage.py collectstatic --noinput
|
||||
|
||||
# Crear superuser
|
||||
docker-compose -f docker-compose.prod.yml run --rm django python manage.py createsuperuser
|
||||
docker compose -f docker-compose.prod.yml run --rm django python manage.py createsuperuser
|
||||
|
||||
# Ver logs
|
||||
docker-compose -f docker-compose.prod.yml logs -f django
|
||||
docker compose -f docker-compose.prod.yml logs -f django
|
||||
|
||||
# Detener servicios
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
docker compose -f docker-compose.prod.yml down
|
||||
```
|
||||
|
||||
Nota: El volumen monta `tienda_ilusion/` en `/app/`, por lo que el path correcto es `python manage.py` (no `python tienda_ilusion/manage.py`).
|
||||
@@ -143,7 +169,7 @@ Nota: El volumen monta `tienda_ilusion/` en `/app/`, por lo que el path correcto
|
||||
|
||||
## Configuración de Ambientes
|
||||
|
||||
El proyecto soporta dos ambientes diferentes mediante la variable `DJANGO_ENV`:
|
||||
El proyecto soporta tres ambientes diferentes mediante la variable `DJANGO_ENV`:
|
||||
|
||||
### Development (desarrollo local)
|
||||
- **Variable de ambiente**: `DJANGO_ENV=development`
|
||||
@@ -153,6 +179,16 @@ El proyecto soporta dos ambientes diferentes mediante la variable `DJANGO_ENV`:
|
||||
- **CORS**: Permisivo para desarrollo local
|
||||
- **Docker Compose**: `docker-compose.dev.yml`
|
||||
|
||||
### Staging (testing de producción local)
|
||||
- **Variable de ambiente**: `DJANGO_ENV=staging`
|
||||
- **Archivo de configuración**: `.env.staging`
|
||||
- **Base de datos**: PostgreSQL (tienda_ilusion_staging)
|
||||
- **DEBUG**: False (simula producción)
|
||||
- **CORS**: Permisivo para localhost (sin SSL redirect)
|
||||
- **Docker Compose**: `docker-compose.staging.yml`
|
||||
- **Servidor**: Gunicorn con 4 workers
|
||||
- **Puerto PostgreSQL**: 5433 (para no conflictuar con producción)
|
||||
|
||||
### Production (producción)
|
||||
- **Variable de ambiente**: `DJANGO_ENV=production`
|
||||
- **Archivo de configuración**: `.env.production` (crear desde `.env.production.example`)
|
||||
@@ -167,6 +203,7 @@ El proyecto soporta dos ambientes diferentes mediante la variable `DJANGO_ENV`:
|
||||
La detección de ambiente es automática mediante la variable `DJANGO_ENV`. Docker Compose configura esta variable automáticamente según el archivo usado:
|
||||
|
||||
- `docker-compose.dev.yml` → usa `.env.development` → carga `settings/development.py`
|
||||
- `docker-compose.staging.yml` → usa `.env.staging` → carga `settings/staging.py`
|
||||
- `docker-compose.prod.yml` → usa `.env.production` → carga `settings/production.py`
|
||||
|
||||
### Variables de entorno requeridas
|
||||
@@ -176,6 +213,15 @@ La detección de ambiente es automática mediante la variable `DJANGO_ENV`. Dock
|
||||
- `DEBUG=True`
|
||||
- `TRYTON_HOST`, `TRYTON_DATABASE`, `TRYTON_USERNAME`, `TRYTON_PASSWORD`
|
||||
|
||||
**Staging** (`.env.staging`):
|
||||
- `DJANGO_ENV=staging`
|
||||
- `DEBUG=False`
|
||||
- `SECRET_KEY` (para staging local, puede ser una key fija)
|
||||
- `ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0`
|
||||
- `CORS_ALLOWED_ORIGINS` (URLs localhost separadas por comas)
|
||||
- `DB_NAME=tienda_ilusion_staging`, `DB_USER`, `DB_PASSWORD`, `DB_HOST=postgres`, `DB_PORT=5432`
|
||||
- `TRYTON_HOST`, `TRYTON_DATABASE`, `TRYTON_USERNAME`, `TRYTON_PASSWORD`
|
||||
|
||||
**Producción** (`.env.production`):
|
||||
- `DJANGO_ENV=production`
|
||||
- `DEBUG=False`
|
||||
|
||||
@@ -4,5 +4,3 @@ WORKDIR /app/
|
||||
|
||||
COPY requirements.txt ./
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
CMD ["python", "manage.py", "runserver", "0.0.0.0:9090"]
|
||||
|
||||
@@ -18,7 +18,11 @@ services:
|
||||
- tienda_network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-tienda_ilusion_user}"]
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"pg_isready -U ${POSTGRES_USER:-tienda_ilusion_user} -d ${POSTGRES_DB:-tienda_ilusion_prod}",
|
||||
]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
73
docker-compose.staging.yml
Normal file
73
docker-compose.staging.yml
Normal file
@@ -0,0 +1,73 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: tienda_ilusion_postgres_staging
|
||||
environment:
|
||||
- POSTGRES_USER=${DB_USER:-tienda_ilusion_user}
|
||||
- POSTGRES_DB=${DB_NAME:-tienda_ilusion_staging}
|
||||
- POSTGRES_PASSWORD=${DB_PASSWORD:-staging_local_password}
|
||||
env_file:
|
||||
- .env.staging
|
||||
volumes:
|
||||
- postgres_staging_data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5433:5432" # Puerto diferente para no conflictuar con prod
|
||||
networks:
|
||||
- tienda_staging_network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"pg_isready -U ${DB_USER:-tienda_ilusion_user} -d ${DB_PASSWORD:-tienda_ilusion_staging}",
|
||||
]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
django:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: django.Dockerfile
|
||||
container_name: tienda_ilusion_django_staging
|
||||
env_file:
|
||||
- .env.staging
|
||||
environment:
|
||||
- DJANGO_ENV=staging
|
||||
- DB_HOST=postgres
|
||||
- DB_USER=${DB_USER:-tienda_ilusion_user}
|
||||
- DB_NAME=${DB_NAME:-tienda_ilusion_staging}
|
||||
- DB_PASSWORD=${DB_PASSWORD:-staging_local_password}
|
||||
volumes:
|
||||
- ./tienda_ilusion:/app/
|
||||
- static_staging_volume:/app/staticfiles
|
||||
- media_staging_volume:/app/media
|
||||
- logs_staging_volume:/app/logs
|
||||
ports:
|
||||
- "8000:8000"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- tienda_staging_network
|
||||
restart: unless-stopped
|
||||
command: >
|
||||
sh -c "python manage.py migrate &&
|
||||
python manage.py collectstatic --noinput &&
|
||||
gunicorn config.wsgi:application --bind 0.0.0.0:8000 --workers 4 --timeout 120 --reload"
|
||||
|
||||
volumes:
|
||||
postgres_staging_data:
|
||||
driver: local
|
||||
static_staging_volume:
|
||||
driver: local
|
||||
media_staging_volume:
|
||||
driver: local
|
||||
logs_staging_volume:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
tienda_staging_network:
|
||||
driver: bridge
|
||||
@@ -3,8 +3,9 @@ Settings module for tienda_ilusion project.
|
||||
|
||||
This module automatically loads the appropriate settings based on the DJANGO_ENV
|
||||
environment variable. Valid values are:
|
||||
- 'development' (default): Development settings
|
||||
- 'production': Production settings
|
||||
- 'development' (default): Development settings with SQLite
|
||||
- 'staging': Staging settings for testing production config locally (PostgreSQL, no SSL)
|
||||
- 'production': Production settings with full security (PostgreSQL, SSL, etc.)
|
||||
|
||||
Usage:
|
||||
Set DJANGO_ENV environment variable before running Django:
|
||||
@@ -13,6 +14,10 @@ Usage:
|
||||
export DJANGO_ENV=development
|
||||
python manage.py runserver
|
||||
|
||||
Staging (test production locally):
|
||||
export DJANGO_ENV=staging
|
||||
python manage.py runserver
|
||||
|
||||
Production:
|
||||
export DJANGO_ENV=production
|
||||
gunicorn config.wsgi:application
|
||||
@@ -25,6 +30,8 @@ DJANGO_ENV = os.environ.get("DJANGO_ENV", "development")
|
||||
|
||||
if DJANGO_ENV == "production":
|
||||
from .production import *
|
||||
elif DJANGO_ENV == "staging":
|
||||
from .staging import *
|
||||
elif DJANGO_ENV == "development":
|
||||
from .development import *
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user