114 lines
5.2 KiB
Bash
Executable File
114 lines
5.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Eenmalig op een nieuwe Ubuntu-server (getest voor 26.04 LTS, OVHcloud-image): alles klaarzetten voor de CRM.
|
|
#
|
|
# scp -r server ubuntu@SERVER:
|
|
# ssh ubuntu@SERVER sudo bash server/setup.sh crm.voorbeeld.nl jij@voorbeeld.nl
|
|
#
|
|
# Daarna rolt tools/release.sh (op je eigen machine) een versie uit naar crm@SERVER.
|
|
# Opnieuw draaien kan: elke stap controleert wat er al is.
|
|
#
|
|
# Wat het doet: pakketten (Python, nginx, certbot, rsync, sqlite3), tijdzone Europe/Amsterdam, gebruiker `crm`
|
|
# met /srv/vanemous-crm, SSH-toegang voor releases (zelfde sleutels als de sudo-gebruiker), systemd-dienst,
|
|
# nginx-site met HTTPS (Let's Encrypt), firewall (alleen SSH, 80, 443), automatische beveiligingsupdates,
|
|
# cron voor de routines (elke minuut `app.py tick`: e-mail ophalen, nieuwsbrieven, …) en een dagelijkse
|
|
# databaseback-up (7 dagen rond).
|
|
set -euo pipefail
|
|
|
|
DOMAIN="${1:-}"
|
|
EMAIL="${2:-}"
|
|
APP=vanemous-crm
|
|
ROOT=/srv/$APP
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
say() { printf '\033[38;2;185;89;19m▸\033[0m %s\n' "$*"; }
|
|
fail() { printf 'Fout: %s\n' "$*" >&2; exit 1; }
|
|
|
|
[ "$(id -u)" = 0 ] || fail "draai dit met sudo"
|
|
[ -n "$DOMAIN" ] && [ -n "$EMAIL" ] || fail "gebruik: sudo bash setup.sh <domein> <e-mail voor Let's Encrypt>"
|
|
|
|
# --- pakketten ------------------------------------------------------------------------
|
|
say "pakketten installeren"
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -q
|
|
apt-get upgrade -yq
|
|
apt-get install -yq python3 python3-venv python3-pip nginx certbot python3-certbot-nginx \
|
|
rsync sqlite3 ufw unattended-upgrades cron curl
|
|
python3 -c 'import sys; assert sys.version_info >= (3, 11), sys.version' || fail "Python 3.11 of nieuwer nodig"
|
|
|
|
say "tijdzone Europe/Amsterdam"
|
|
timedatectl set-timezone Europe/Amsterdam
|
|
|
|
say "automatische beveiligingsupdates aan"
|
|
dpkg-reconfigure -f noninteractive unattended-upgrades
|
|
|
|
# --- gebruiker en mappen -----------------------------------------------------------------
|
|
if ! id crm >/dev/null 2>&1; then
|
|
say "gebruiker crm aanmaken"
|
|
useradd --system --create-home --home-dir "$ROOT" --shell /bin/bash crm
|
|
fi
|
|
install -d -o crm -g crm -m 755 "$ROOT" "$ROOT/releases"
|
|
install -d -o crm -g crm -m 700 "$ROOT/data" "$ROOT/data/backups"
|
|
|
|
# SSH-sleutels van de gebruiker die sudo deed (bij OVH: ubuntu), zodat releases als crm kunnen inloggen.
|
|
src_user="${SUDO_USER:-ubuntu}"
|
|
src_keys="$(getent passwd "$src_user" | cut -d: -f6)/.ssh/authorized_keys"
|
|
install -d -o crm -g crm -m 700 "$ROOT/.ssh"
|
|
if [ -f "$src_keys" ]; then
|
|
touch "$ROOT/.ssh/authorized_keys" # bij de eerste keer bestaat hij nog niet (en cat zou dan set -e laten stoppen)
|
|
sort -u "$src_keys" "$ROOT/.ssh/authorized_keys" > "$ROOT/.ssh/authorized_keys.new"
|
|
mv "$ROOT/.ssh/authorized_keys.new" "$ROOT/.ssh/authorized_keys"
|
|
chown crm:crm "$ROOT/.ssh/authorized_keys"; chmod 600 "$ROOT/.ssh/authorized_keys"
|
|
say "SSH-sleutels van $src_user toegevoegd aan crm"
|
|
else
|
|
say "let op: geen $src_keys; zet zelf een sleutel in $ROOT/.ssh/authorized_keys"
|
|
fi
|
|
|
|
# crm mag alleen de eigen dienst herstarten
|
|
cat > /etc/sudoers.d/$APP <<EOF
|
|
crm ALL=(root) NOPASSWD: /usr/bin/systemctl restart $APP, /usr/bin/systemctl is-active $APP, /usr/bin/journalctl -u $APP *
|
|
EOF
|
|
chmod 440 /etc/sudoers.d/$APP
|
|
visudo -cf /etc/sudoers.d/$APP >/dev/null
|
|
|
|
# --- systemd -----------------------------------------------------------------------------
|
|
say "systemd-dienst $APP"
|
|
install -m 644 "$HERE/$APP.service" /etc/systemd/system/$APP.service
|
|
systemctl daemon-reload
|
|
systemctl enable $APP >/dev/null 2>&1
|
|
# starten gebeurt bij de eerste release (er is nog geen code)
|
|
|
|
# --- nginx -------------------------------------------------------------------------------
|
|
say "nginx voor $DOMAIN"
|
|
if [ ! -f /etc/nginx/sites-available/$APP ] || ! grep -q "listen 443" /etc/nginx/sites-available/$APP; then
|
|
sed "s/__DOMAIN__/$DOMAIN/g" "$HERE/nginx-site.conf" > /etc/nginx/sites-available/$APP
|
|
fi
|
|
ln -sfn /etc/nginx/sites-available/$APP /etc/nginx/sites-enabled/$APP
|
|
rm -f /etc/nginx/sites-enabled/default
|
|
nginx -t
|
|
systemctl reload nginx
|
|
|
|
# --- firewall ------------------------------------------------------------------------------
|
|
say "firewall: alleen SSH, HTTP en HTTPS"
|
|
ufw allow OpenSSH >/dev/null
|
|
ufw allow 'Nginx Full' >/dev/null
|
|
ufw --force enable >/dev/null
|
|
|
|
# --- HTTPS -------------------------------------------------------------------------------
|
|
say "certificaat aanvragen (DNS van $DOMAIN moet al naar deze server wijzen)"
|
|
if certbot --nginx -d "$DOMAIN" -m "$EMAIL" --agree-tos --non-interactive --redirect; then
|
|
say "HTTPS actief; verlengen gaat automatisch (certbot.timer)"
|
|
else
|
|
say "let op: certificaat mislukt. Klopt de DNS? Daarna opnieuw: sudo certbot --nginx -d $DOMAIN -m $EMAIL --agree-tos --redirect"
|
|
fi
|
|
|
|
# --- cron: routines en back-up -----------------------------------------------------------------
|
|
say "cron: routines elke minuut, database-back-up elke nacht"
|
|
cat > /etc/cron.d/$APP <<EOF
|
|
# Van Emous CRM (server/setup.sh)
|
|
* * * * * crm [ -d $ROOT/current ] && cd $ROOT/current && CRM_DATA=$ROOT/data .venv/bin/python app.py tick 2>&1 | logger -t $APP-routines
|
|
15 3 * * * crm [ -f $ROOT/data/crm.db ] && sqlite3 $ROOT/data/crm.db ".backup '$ROOT/data/backups/nacht-\$(date +\%a).db'"
|
|
EOF
|
|
chmod 644 /etc/cron.d/$APP
|
|
|
|
say "klaar. Rol nu vanaf je eigen machine een versie uit: tools/release.sh crm@$DOMAIN"
|