Añade README de despliegue y soporte Docker
- README.md: guía de instalación (venv, .env, migraciones, gunicorn) y notas de producción/seguridad - Dockerfile: imagen Python 3.14 con deps de sistema para mysqlclient/Pillow - docker-compose.yml: servicios web (Django+gunicorn) y db (MySQL 8.4) con las 4 BBDD - docker/entrypoint.sh: espera a MySQL, migra, collectstatic y arranca gunicorn - docker/mysql-init.sql: crea django_wow + bases acore_* - .dockerignore y gunicorn en requirements Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.venv
|
||||||
|
venv
|
||||||
|
.env
|
||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
|
**/__pycache__/
|
||||||
|
staticfiles/
|
||||||
|
db.sqlite3
|
||||||
|
*.sqlite3
|
||||||
|
.dockerignore
|
||||||
|
Dockerfile
|
||||||
|
docker-compose.yml
|
||||||
|
README.md
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
# Nova WoW - imagen del portal Django
|
||||||
|
FROM python:3.14-slim
|
||||||
|
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Dependencias de sistema para mysqlclient (compilación + runtime) y Pillow
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
build-essential \
|
||||||
|
pkg-config \
|
||||||
|
default-libmysqlclient-dev \
|
||||||
|
libgmp-dev libmpfr-dev libmpc-dev \
|
||||||
|
libjpeg-dev zlib1g-dev \
|
||||||
|
netcat-openbsd \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Instalar dependencias Python primero (mejor cache)
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copiar el código
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Entrypoint
|
||||||
|
RUN chmod +x /app/docker/entrypoint.sh
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
ENTRYPOINT ["/app/docker/entrypoint.sh"]
|
||||||
|
CMD ["gunicorn", "novawow.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
# Nova WoW
|
||||||
|
|
||||||
|
Portal web (Django) para un servidor de World of Warcraft basado en AzerothCore.
|
||||||
|
|
||||||
|
- **Python:** 3.14
|
||||||
|
- **Framework:** Django 6.0
|
||||||
|
- **Base de datos:** MySQL (4 bases: la del portal `django_wow` + las de AzerothCore `acore_auth`, `acore_characters`, `acore_world`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Requisitos
|
||||||
|
|
||||||
|
- Python 3.14 y `venv`
|
||||||
|
- MySQL/MariaDB accesible
|
||||||
|
- Librerías de sistema para compilar algunas dependencias:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install python3.14-venv python3.14-dev build-essential pkg-config \
|
||||||
|
default-libmysqlclient-dev libgmp-dev libmpfr-dev libmpc-dev libjpeg-dev zlib1g-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Puesta en marcha (desarrollo)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.nightspire.gg/Inna/NovaWoW.git
|
||||||
|
cd NovaWoW
|
||||||
|
|
||||||
|
# Entorno virtual
|
||||||
|
python3 -m venv .venv
|
||||||
|
source .venv/bin/activate
|
||||||
|
pip install --upgrade pip
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# Variables de entorno
|
||||||
|
cp .env.example .env
|
||||||
|
# edita .env con tus credenciales reales (ver sección 3)
|
||||||
|
|
||||||
|
# Migraciones y arranque
|
||||||
|
python manage.py migrate
|
||||||
|
python manage.py createsuperuser # opcional
|
||||||
|
python manage.py runserver
|
||||||
|
```
|
||||||
|
|
||||||
|
La app queda en http://127.0.0.1:8000
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Configuración (`.env`)
|
||||||
|
|
||||||
|
Toda la configuración sensible se lee de variables de entorno mediante
|
||||||
|
[python-dotenv](https://pypi.org/project/python-dotenv/). Copia `.env.example`
|
||||||
|
a `.env` y rellena los valores. **El `.env` no se versiona.**
|
||||||
|
|
||||||
|
| Variable | Descripción |
|
||||||
|
|---|---|
|
||||||
|
| `DJANGO_SECRET_KEY` | Clave secreta de Django. Genera una nueva (ver abajo). |
|
||||||
|
| `DJANGO_DEBUG` | `True` en desarrollo, `False` en producción. |
|
||||||
|
| `DB_USER` / `DB_PASSWORD` | Credenciales MySQL (compartidas por las 4 BBDD). |
|
||||||
|
| `DB_HOST` / `DB_PORT` | Host y puerto de MySQL. |
|
||||||
|
| `DB_NAME_DEFAULT` | BD del portal (por defecto `django_wow`). |
|
||||||
|
| `DB_NAME_AUTH` / `DB_NAME_CHARACTERS` / `DB_NAME_WORLD` | BBDD de AzerothCore. |
|
||||||
|
| `AC_SOAP_*` | Conexión SOAP a AzerothCore (crear cuentas, etc.). |
|
||||||
|
| `SUMUP_*` / `STRIPE_*` | Pasarelas de pago. |
|
||||||
|
| `EMAIL_HOST_USER` / `EMAIL_HOST_PASSWORD` | SMTP de Gmail (App Password). |
|
||||||
|
|
||||||
|
Generar una `SECRET_KEY` nueva:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Producción
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Recopilar estáticos
|
||||||
|
python manage.py collectstatic --noinput
|
||||||
|
|
||||||
|
# Servir con gunicorn (4 workers)
|
||||||
|
gunicorn novawow.wsgi:application --bind 0.0.0.0:8000 --workers 4
|
||||||
|
```
|
||||||
|
|
||||||
|
Recomendaciones:
|
||||||
|
|
||||||
|
- `DJANGO_DEBUG=False` y una `DJANGO_SECRET_KEY` propia y secreta.
|
||||||
|
- Poner **Nginx** delante como proxy inverso y para servir `staticfiles/`.
|
||||||
|
- Revisar `ALLOWED_HOSTS` y `CSRF_TRUSTED_ORIGINS` en `novawow/settings.py`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Docker
|
||||||
|
|
||||||
|
Alternativamente, se puede levantar todo con Docker (web + MySQL):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env # ajusta los secretos (no las variables DB_*, las fija compose)
|
||||||
|
docker compose up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
- La web queda en http://127.0.0.1:8000
|
||||||
|
- El servicio `db` crea automáticamente las 4 bases de datos.
|
||||||
|
- El `entrypoint` espera a MySQL, aplica migraciones y recopila estáticos antes de arrancar gunicorn.
|
||||||
|
|
||||||
|
Ver `docker-compose.yml` y `Dockerfile` para los detalles.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Notas de seguridad
|
||||||
|
|
||||||
|
- Los secretos que estuvieron hardcodeados en el historial de git deben **rotarse**
|
||||||
|
(contraseña MySQL/SOAP, App Password de Gmail, claves de Stripe/SumUp).
|
||||||
|
- Nunca subas el archivo `.env` al repositorio.
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: mysql:8.4
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: rootpass
|
||||||
|
MYSQL_DATABASE: django_wow
|
||||||
|
MYSQL_USER: novawow
|
||||||
|
MYSQL_PASSWORD: novawow_pass
|
||||||
|
volumes:
|
||||||
|
- db_data:/var/lib/mysql
|
||||||
|
- ./docker/mysql-init.sql:/docker-entrypoint-initdb.d/init.sql:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-prootpass"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 20
|
||||||
|
|
||||||
|
web:
|
||||||
|
build: .
|
||||||
|
restart: unless-stopped
|
||||||
|
# Secretos de la app (Stripe, SumUp, SOAP, email, SECRET_KEY...) desde .env
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
# Las variables de BD las fija compose para apuntar al servicio 'db'
|
||||||
|
environment:
|
||||||
|
DJANGO_DEBUG: "False"
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: "3306"
|
||||||
|
DB_USER: novawow
|
||||||
|
DB_PASSWORD: novawow_pass
|
||||||
|
DB_NAME_DEFAULT: django_wow
|
||||||
|
DB_NAME_AUTH: acore_auth
|
||||||
|
DB_NAME_CHARACTERS: acore_characters
|
||||||
|
DB_NAME_WORLD: acore_world
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db_data:
|
||||||
Executable
+22
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Espera a que MySQL esté disponible
|
||||||
|
if [ -n "$DB_HOST" ]; then
|
||||||
|
echo "Esperando a MySQL en $DB_HOST:${DB_PORT:-3306}..."
|
||||||
|
until nc -z "$DB_HOST" "${DB_PORT:-3306}"; do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "MySQL disponible."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Migraciones (solo la base 'default' del portal)
|
||||||
|
echo "Aplicando migraciones..."
|
||||||
|
python manage.py migrate --noinput
|
||||||
|
|
||||||
|
# Estáticos
|
||||||
|
echo "Recopilando archivos estáticos..."
|
||||||
|
python manage.py collectstatic --noinput
|
||||||
|
|
||||||
|
# Ejecuta el comando indicado (gunicorn por defecto)
|
||||||
|
exec "$@"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
-- Crea las bases de datos que necesita el portal.
|
||||||
|
-- La del portal (django_wow) y las de AzerothCore.
|
||||||
|
-- Las de AzerothCore quedan vacías; en un entorno real las provee el core del juego.
|
||||||
|
CREATE DATABASE IF NOT EXISTS `django_wow` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
CREATE DATABASE IF NOT EXISTS `acore_auth` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
CREATE DATABASE IF NOT EXISTS `acore_characters` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
CREATE DATABASE IF NOT EXISTS `acore_world` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- Concede permisos al usuario de la aplicación sobre las 4 bases
|
||||||
|
GRANT ALL PRIVILEGES ON `django_wow`.* TO 'novawow'@'%';
|
||||||
|
GRANT ALL PRIVILEGES ON `acore_auth`.* TO 'novawow'@'%';
|
||||||
|
GRANT ALL PRIVILEGES ON `acore_characters`.* TO 'novawow'@'%';
|
||||||
|
GRANT ALL PRIVILEGES ON `acore_world`.* TO 'novawow'@'%';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
@@ -14,3 +14,4 @@ stripe==15.3.0
|
|||||||
typing_extensions==4.16.0
|
typing_extensions==4.16.0
|
||||||
urllib3==2.7.0
|
urllib3==2.7.0
|
||||||
python-dotenv==1.2.2
|
python-dotenv==1.2.2
|
||||||
|
gunicorn==26.0.0
|
||||||
|
|||||||
Reference in New Issue
Block a user