@@ -31,7 +31,7 @@ jobs:
|
||||
--exclude '__pycache__' \
|
||||
./ deploy@pbt:/opt/pbt/
|
||||
|
||||
- name: Abhängigkeiten installieren & Service neu starten
|
||||
- name: Abhängigkeiten installieren, Haltestellen importieren & Service neu starten
|
||||
run: |
|
||||
ssh deploy@pbt '
|
||||
set -e
|
||||
@@ -40,4 +40,7 @@ jobs:
|
||||
source venv/bin/activate
|
||||
pip install -q -r requirements.txt
|
||||
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
|
||||
'
|
||||
|
||||
@@ -2,4 +2,5 @@ venv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.env
|
||||
pbt.env
|
||||
instance/
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
Der Import ist idempotent (Upsert) und braucht kein Internet. Beim Deploy per
|
||||
systemd einmalig ausführen, danach nur wenn der Snapshot aktualisiert wurde.
|
||||
Der Import ist idempotent (Upsert) und braucht kein Internet. Im Produktivbetrieb
|
||||
übernimmt das die Unit `pbt-import-stops.service` (wird bei jedem Deploy
|
||||
angestoßen, s. u.).
|
||||
|
||||
Snapshot neu von OpenStreetMap holen (dauert 1–2 min, braucht Netzugang):
|
||||
|
||||
@@ -44,15 +45,29 @@ flask import-stops
|
||||
## Produktivbetrieb mit systemd + Gunicorn
|
||||
|
||||
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
|
||||
Secret-Key darin anpassen.
|
||||
3. Aktivieren:
|
||||
2. Secrets anlegen (nicht im Repo):
|
||||
```bash
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now pbt
|
||||
sudo install -d -m 750 -o root -g root /etc/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
|
||||
```
|
||||
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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -5,8 +5,9 @@ After=network.target
|
||||
[Service]
|
||||
User=www-data
|
||||
WorkingDirectory=/opt/pbt
|
||||
Environment="PBT_DATABASE_URL=postgresql://pbt_app:changeme@postgres/pbt"
|
||||
Environment="PBT_SECRET_KEY=bitte-aendern"
|
||||
# Secrets live in a root-owned file on the host, not in this tracked unit.
|
||||
# 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
|
||||
Restart=always
|
||||
|
||||
|
||||
Reference in New Issue
Block a user