Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
# Local default DB. For external databases adapt connection options separately.
|
||||
backup_dir="${1:?Usage: backup.sh /protected/backup/path}"
|
||||
mkdir -p "$backup_dir"
|
||||
chmod 700 "$backup_dir"
|
||||
umask 077
|
||||
partial="$(mktemp "$backup_dir/.dilib-backup-XXXXXX.partial")"
|
||||
trap 'rm -f -- "$partial"' EXIT
|
||||
pg_dump --format=custom --file="$partial" dilib_dashboard
|
||||
pg_restore --list "$partial" >/dev/null
|
||||
final="$backup_dir/dilib-dashboard-$(date -u +%Y%m%dT%H%M%SZ)-$$.dump"
|
||||
mv -- "$partial" "$final"
|
||||
printf 'Backup created: %s\n' "$final"
|
||||
@@ -0,0 +1,25 @@
|
||||
"""Configure a new deployment; never reads secrets from shell arguments."""
|
||||
import argparse,os,re,secrets
|
||||
from pathlib import Path
|
||||
from dotenv import dotenv_values,set_key
|
||||
|
||||
def main():
|
||||
parser=argparse.ArgumentParser()
|
||||
parser.add_argument('--domain',required=True)
|
||||
parser.add_argument('--env',default='/etc/dilib-dashboard/dashboard.env')
|
||||
args=parser.parse_args()
|
||||
if not re.fullmatch(r'[a-zA-Z0-9](?:[a-zA-Z0-9.-]*[a-zA-Z0-9])?',args.domain):
|
||||
parser.error('Domain ohne Protokoll oder Port angeben')
|
||||
path=Path(args.env)
|
||||
if not path.is_file():parser.error('Env-Datei fehlt; zuerst install-central.sh ausführen')
|
||||
current=dotenv_values(path)
|
||||
# Updating the domain does not rotate existing secrets or change the database.
|
||||
changes={'ALLOWED_HOSTS':args.domain+',127.0.0.1,localhost',
|
||||
'CSRF_TRUSTED_ORIGINS':'https://'+args.domain}
|
||||
for key in ('DJANGO_SECRET_KEY','NICEGUI_STORAGE_SECRET'):
|
||||
if not current.get(key) or current[key].startswith('CHANGE_ME'):
|
||||
changes[key]=secrets.token_urlsafe(64)
|
||||
os.umask(0o077)
|
||||
for key,value in changes.items():set_key(path,key,value,quote_mode='never')
|
||||
print('Domain und gegebenenfalls Secrets gesetzt. DATABASE_URL und SMTP separat konfigurieren.')
|
||||
if __name__=='__main__':main()
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd /opt/dilib-dashboard
|
||||
[[ $EUID -eq 0 ]] || { echo 'Als root ausführen'; exit 1; }
|
||||
# DATABASE_URL, Redis und Domain müssen vorher gesetzt sein.
|
||||
bash scripts/manage-env.sh check
|
||||
bash scripts/manage-env.sh migrate --noinput
|
||||
bash scripts/manage-env.sh collectstatic --noinput
|
||||
bash scripts/manage-env.sh doctor
|
||||
systemctl enable --now dilib-api dilib-ui dilib-worker dilib-beat
|
||||
sleep 3
|
||||
bash scripts/manage-env.sh doctor --workers
|
||||
echo 'Dienste gestartet. Admin anlegen: sudo bash scripts/manage-env.sh createsuperuser'
|
||||
@@ -0,0 +1,6 @@
|
||||
import secrets,sys
|
||||
from pathlib import Path
|
||||
p=Path(sys.argv[1]);text=p.read_text()
|
||||
text=text.replace('DJANGO_SECRET_KEY=CHANGE_ME_GENERATE_WITH_SECRETS','DJANGO_SECRET_KEY='+secrets.token_urlsafe(64))
|
||||
text=text.replace('NICEGUI_STORAGE_SECRET=CHANGE_ME_GENERATE_SEPARATELY','NICEGUI_STORAGE_SECRET='+secrets.token_urlsafe(64))
|
||||
p.write_text(text)
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
[[ $EUID -eq 0 ]] || { echo 'Run as root on the monitored host.'; exit 1; }
|
||||
[[ "$PWD" == /opt/dilib-dashboard ]] || { echo 'Extract project to /opt/dilib-dashboard first.'; exit 1; }
|
||||
apt-get update
|
||||
apt-get install -y python3 python3-venv
|
||||
id dilib-agent >/dev/null 2>&1 || useradd --system --home /var/lib/dilib-agent --shell /usr/sbin/nologin dilib-agent
|
||||
install -d -o dilib-agent -g dilib-agent -m 750 /var/lib/dilib-agent /var/lib/dilib-flower
|
||||
install -d -o root -g dilib-agent -m 750 /etc/dilib-agent
|
||||
python3 -m venv .venv-agent
|
||||
.venv-agent/bin/pip install -r agent/requirements.txt
|
||||
if [[ ! -f /etc/dilib-agent/agent.env ]]; then
|
||||
install -m 640 -o root -g dilib-agent agent/.env.example /etc/dilib-agent/agent.env
|
||||
fi
|
||||
install -m 644 deploy/systemd/dilib-agent.service /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
echo 'Configure agent.env and start: systemctl enable --now dilib-agent'
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
[[ $EUID -eq 0 ]] || { echo 'Run as root on the target Ubuntu server.'; exit 1; }
|
||||
[[ "$PWD" == /opt/dilib-dashboard ]] || { echo 'Extract project to /opt/dilib-dashboard first.'; exit 1; }
|
||||
apt-get update
|
||||
apt-get install -y python3 python3-venv python3-dev build-essential libpq-dev postgresql postgresql-client redis-server
|
||||
id dilib >/dev/null 2>&1 || useradd --system --home /var/lib/dilib-dashboard --shell /usr/sbin/nologin dilib
|
||||
install -d -o dilib -g dilib -m 750 /var/lib/dilib-dashboard
|
||||
install -d -m 750 -o root -g dilib /etc/dilib-dashboard
|
||||
python3 -m venv .venv
|
||||
.venv/bin/pip install -r requirements.txt
|
||||
if [[ ! -f /etc/dilib-dashboard/dashboard.env ]]; then
|
||||
install -m 640 -o root -g dilib .env.example /etc/dilib-dashboard/dashboard.env
|
||||
.venv/bin/python scripts/generate-secrets.py /etc/dilib-dashboard/dashboard.env
|
||||
fi
|
||||
install -m 644 deploy/systemd/dilib-{api,ui,worker,beat,backup}.service /etc/systemd/system/
|
||||
install -m 644 deploy/systemd/dilib-backup.timer /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
printf '%s\n' 'Dependencies installed. Configure database, environment and HTTPS as described in docs/INSTALLATION.md. Services are not started yet.'
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
[[ $EUID -eq 0 && "$PWD" == /opt/dilib-dashboard ]] || { echo 'Als root in /opt/dilib-dashboard ausführen.'; exit 1; }
|
||||
[[ -x .venv-agent/bin/python ]] || { echo 'Zuerst scripts/install-agent.sh ausführen.'; exit 1; }
|
||||
.venv-agent/bin/pip install 'flower==2.2.0'
|
||||
if [[ ! -e /etc/dilib-agent/flower.env ]]; then
|
||||
install -m 640 -o root -g dilib-agent deploy/flower.env.example /etc/dilib-agent/flower.env
|
||||
fi
|
||||
install -m 644 deploy/systemd/dilib-flower.service /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
echo 'Broker und FLOWER_BASIC_AUTH in /etc/dilib-agent/flower.env setzen.'
|
||||
echo 'Dann: systemctl enable --now dilib-flower'
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd /opt/dilib-dashboard
|
||||
# Environment loading uses python-dotenv, not shell eval.
|
||||
exec /opt/dilib-dashboard/.venv/bin/python scripts/manage_env.py "$@"
|
||||
@@ -0,0 +1,4 @@
|
||||
import os,sys
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv('/etc/dilib-dashboard/dashboard.env',override=True)
|
||||
os.execv(sys.executable,[sys.executable,'manage.py',*sys.argv[1:]])
|
||||
@@ -0,0 +1,13 @@
|
||||
"""Generate HTTP-only reverse proxy config. Certbot configures TLS afterward."""
|
||||
import argparse,re
|
||||
from pathlib import Path
|
||||
p=argparse.ArgumentParser()
|
||||
p.add_argument('--domain',required=True)
|
||||
p.add_argument('--server',choices=['nginx','apache'],default='nginx')
|
||||
p.add_argument('--output',required=True)
|
||||
a=p.parse_args()
|
||||
if not re.fullmatch(r'[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?',a.domain):p.error('Invalid domain')
|
||||
src=Path(__file__).resolve().parents[1]/'deploy'/f'{a.server}-http.conf'
|
||||
target=Path(a.output)
|
||||
with target.open('x') as f:f.write(src.read_text().replace('dashboard.example.com',a.domain))
|
||||
print(target)
|
||||
Reference in New Issue
Block a user