feat(staging): enforce MySQL-only staging deploy (fixes #133) #134

Merged
integrator-bot merged 2 commits from feat/staging-mysql-133 into main 2026-02-28 15:14:56 +01:00
5 changed files with 47 additions and 0 deletions

1
.gitignore vendored
View File

@@ -22,6 +22,7 @@ media/
.env .env
.env.* .env.*
!.env.test.example !.env.test.example
!.env.staging.example
!.env.prod.example !.env.prod.example
# Editors/OS # Editors/OS

12
infra/env/.env.staging.example vendored Normal file
View File

@@ -0,0 +1,12 @@
DJANGO_SECRET_KEY=change-me-staging
DJANGO_DEBUG=false
DJANGO_ALLOWED_HOSTS=staging.party.weircon.dk
DB_ENGINE=django.db.backends.mysql
DB_NAME=wpp_staging
DB_USER=wpp_staging
DB_PASSWORD=change-me
DB_HOST=127.0.0.1
DB_PORT=3306
TEST_DB_NAME=
CHANNEL_REDIS_HOST=127.0.0.1
CHANNEL_REDIS_PORT=6379

View File

@@ -4,15 +4,18 @@
## Databaser ## Databaser
- `wpp_test` - `wpp_test`
- `wpp_staging`
- `wpp_prod` - `wpp_prod`
## Brugere ## Brugere
- `wpp_test_user` (least privilege på `wpp_test`) - `wpp_test_user` (least privilege på `wpp_test`)
- `wpp_staging_user` (least privilege på `wpp_staging`)
- `wpp_prod_user` (least privilege på `wpp_prod`) - `wpp_prod_user` (least privilege på `wpp_prod`)
## Secrets placering ## Secrets placering
I Secrets-repo: I Secrets-repo:
- `wpp/wpp_test.env` - `wpp/wpp_test.env`
- `wpp/wpp_staging.env`
- `wpp/wpp_prod.env` - `wpp/wpp_prod.env`
Forventede felter: Forventede felter:

View File

@@ -8,6 +8,7 @@ Staging-miljø for WPP i Proxmox LXC, så release-klar kode kan deployes og smok
- App path: /opt/wpp-staging/app - App path: /opt/wpp-staging/app
- Service: wpp-staging.service - Service: wpp-staging.service
- Health endpoint: GET /healthz - Health endpoint: GET /healthz
- Database: MySQL (staging må ikke bruge SQLite, issue #133)
## Verifikation ## Verifikation
Kør fra devops-shell med Proxmox-adgang: Kør fra devops-shell med Proxmox-adgang:
@@ -21,6 +22,8 @@ Forventet:
- service er active - service er active
- healthz returnerer JSON med ok=true - healthz returnerer JSON med ok=true
Efter deploy vil scriptet også verificere at `DB_ENGINE` ikke er `django.db.backends.sqlite3` før migrations køres.
## Deploy (canonical execution context) ## Deploy (canonical execution context)
Deploy skal altid køres via Proxmox host over SSH (ikke fra lokal coder-shell med direkte sudo pct). Deploy skal altid køres via Proxmox host over SSH (ikke fra lokal coder-shell med direkte sudo pct).

View File

@@ -17,10 +17,38 @@ rm -rf src && mkdir src
tar -xzf app.tar.gz -C src --strip-components=1 tar -xzf app.tar.gz -C src --strip-components=1
rm -rf /opt/wpp-staging/app/* rm -rf /opt/wpp-staging/app/*
cp -a src/. /opt/wpp-staging/app/ cp -a src/. /opt/wpp-staging/app/
# Ensure deploy artifact copied as root does not leave app tree non-writable for wpp.
chown -R wpp:wpp /opt/wpp-staging/app
# Staging must not run on SQLite (issue #133). Remove bundled sqlite artifact.
rm -f /opt/wpp-staging/app/db.sqlite3
cd /opt/wpp-staging/app cd /opt/wpp-staging/app
# Load staging env before any manage.py call (issue #133 follow-up).
ENV_LOADED=0
for ENV_FILE in \
/opt/wpp-staging/.env.staging \
/opt/wpp-staging/.env \
/opt/wpp-staging/env/wpp_staging.env \
/opt/wpp-staging/secrets/wpp_staging.env
do
if [ -f "${ENV_FILE}" ]; then
set -a
. "${ENV_FILE}"
set +a
echo "[deploy] loaded staging env: ${ENV_FILE}"
ENV_LOADED=1
break
fi
done
if [ "${ENV_LOADED}" -ne 1 ]; then
echo "[deploy] ERROR: no staging env file found"
exit 1
fi
runuser -u wpp -- python3 -m venv .venv runuser -u wpp -- python3 -m venv .venv
runuser -u wpp -- .venv/bin/pip install -U pip >/dev/null runuser -u wpp -- .venv/bin/pip install -U pip >/dev/null
runuser -u wpp -- .venv/bin/pip install -r requirements.txt >/dev/null runuser -u wpp -- .venv/bin/pip install -r requirements.txt >/dev/null
runuser -u wpp -- .venv/bin/python manage.py shell -c \"from django.conf import settings; import sys; engine = settings.DATABASES['default']['ENGINE']; print(f'DB_ENGINE={engine}'); sys.exit(0 if engine != 'django.db.backends.sqlite3' else 1)\"
runuser -u wpp -- .venv/bin/python manage.py migrate --noinput runuser -u wpp -- .venv/bin/python manage.py migrate --noinput
systemctl restart wpp-staging.service systemctl restart wpp-staging.service
curl -fsS http://127.0.0.1:8000/healthz\"" curl -fsS http://127.0.0.1:8000/healthz\""