Init stops-import, DB-Env
Deploy PBT / deploy (push) Failing after 16s

This commit is contained in:
2026-09-10 21:58:22 +02:00
parent 2a6e9c690b
commit 158311a329
6 changed files with 50 additions and 10 deletions
+4 -1
View File
@@ -31,7 +31,7 @@ jobs:
--exclude '__pycache__' \ --exclude '__pycache__' \
./ deploy@pbt:/opt/pbt/ ./ deploy@pbt:/opt/pbt/
- name: Abhängigkeiten installieren & Service neu starten - name: Abhängigkeiten installieren, Haltestellen importieren & Service neu starten
run: | run: |
ssh deploy@pbt ' ssh deploy@pbt '
set -e set -e
@@ -40,4 +40,7 @@ jobs:
source venv/bin/activate source venv/bin/activate
pip install -q -r requirements.txt pip install -q -r requirements.txt
sudo /usr/bin/systemctl restart pbt sudo /usr/bin/systemctl restart pbt
# oneshot unit: reads /etc/pbt/pbt.env for PBT_DATABASE_URL,
# runs "flask import-stops" (idempotent upsert of data/stops_at.csv.gz)
sudo /usr/bin/systemctl start pbt-import-stops.service
' '
+1
View File
@@ -2,4 +2,5 @@ venv/
__pycache__/ __pycache__/
*.pyc *.pyc
.env .env
pbt.env
instance/ instance/
+22 -7
View File
@@ -31,8 +31,9 @@ Nach dem Anlegen der Tabellen den Snapshot in die DB laden:
flask import-stops # FLASK_APP=app.py bzw. im Projektverzeichnis flask import-stops # FLASK_APP=app.py bzw. im Projektverzeichnis
``` ```
Der Import ist idempotent (Upsert) und braucht kein Internet. Beim Deploy per Der Import ist idempotent (Upsert) und braucht kein Internet. Im Produktivbetrieb
systemd einmalig ausführen, danach nur wenn der Snapshot aktualisiert wurde. übernimmt das die Unit `pbt-import-stops.service` (wird bei jedem Deploy
angestoßen, s. u.).
Snapshot neu von OpenStreetMap holen (dauert 12 min, braucht Netzugang): Snapshot neu von OpenStreetMap holen (dauert 12 min, braucht Netzugang):
@@ -44,15 +45,29 @@ flask import-stops
## Produktivbetrieb mit systemd + Gunicorn ## Produktivbetrieb mit systemd + Gunicorn
1. Projekt nach `/opt/pbt` kopieren, virtuelle Umgebung dort anlegen (s. oben). 1. Projekt nach `/opt/pbt` kopieren, virtuelle Umgebung dort anlegen (s. oben).
2. `pbt.service` nach `/etc/systemd/system/pbt.service` kopieren, DB-URL und 2. Secrets anlegen (nicht im Repo):
Secret-Key darin anpassen.
3. Aktivieren:
```bash ```bash
systemctl daemon-reload sudo install -d -m 750 -o root -g root /etc/pbt
systemctl enable --now pbt sudo cp /opt/pbt/pbt.env.example /etc/pbt/pbt.env
sudo chmod 640 /etc/pbt/pbt.env
sudo $EDITOR /etc/pbt/pbt.env # echte PBT_DATABASE_URL + PBT_SECRET_KEY
```
3. Beide Units installieren (lesen `/etc/pbt/pbt.env`):
```bash
sudo cp /opt/pbt/pbt.service /opt/pbt/pbt-import-stops.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now pbt
sudo systemctl start pbt-import-stops.service # Haltestellen laden
systemctl status pbt systemctl status pbt
``` ```
Die App lauscht dann intern auf `127.0.0.1:8000`. Die App lauscht dann intern auf `127.0.0.1:8000`.
4. Damit der Deploy-User (`deploy`) beim CI-Deploy neu starten und den
Haltestellen-Import anstoßen darf, in `/etc/sudoers.d/pbt-deploy`:
```
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart pbt, /usr/bin/systemctl start pbt-import-stops.service
```
Der Import selbst läuft als `www-data` und bekommt die DB-URL aus
`/etc/pbt/pbt.env` die Credentials liegen nie beim Deploy-User.
## Caddy-Eintrag ## Caddy-Eintrag
+14
View File
@@ -0,0 +1,14 @@
[Unit]
Description=PBT: import the Austrian stop list into the database
# Postgres runs on a separate host, so just wait for the network.
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
User=www-data
WorkingDirectory=/opt/pbt
# Same secrets file as pbt.service - gives the import command PBT_DATABASE_URL.
EnvironmentFile=/etc/pbt/pbt.env
Environment=FLASK_APP=app.py
ExecStart=/opt/pbt/venv/bin/flask import-stops
+6
View File
@@ -0,0 +1,6 @@
# Copy to /etc/pbt/pbt.env on the host (root:root, chmod 640) and fill in.
# Referenced by pbt.service and pbt-import-stops.service via EnvironmentFile=.
# systemd parses this itself: KEY=VALUE per line, no quotes, no `export`.
PBT_DATABASE_URL=postgresql://pbt_app:CHANGE_ME@postgres/pbt
PBT_SECRET_KEY=CHANGE_ME_long_random_string
+3 -2
View File
@@ -5,8 +5,9 @@ After=network.target
[Service] [Service]
User=www-data User=www-data
WorkingDirectory=/opt/pbt WorkingDirectory=/opt/pbt
Environment="PBT_DATABASE_URL=postgresql://pbt_app:changeme@postgres/pbt" # Secrets live in a root-owned file on the host, not in this tracked unit.
Environment="PBT_SECRET_KEY=bitte-aendern" # Copy pbt.env.example to /etc/pbt/pbt.env and fill in the real values.
EnvironmentFile=/etc/pbt/pbt.env
ExecStart=/opt/pbt/venv/bin/gunicorn --workers 2 --bind 127.0.0.1:8000 app:app ExecStart=/opt/pbt/venv/bin/gunicorn --workers 2 --bind 127.0.0.1:8000 app:app
Restart=always Restart=always