Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81fc27fa86 |
@@ -126,6 +126,25 @@ Lokaal zoals op de server, maar zonder nginx: `./deploy.sh` (zie het script).
|
|||||||
Back-ups buiten de server (bijv. de back-upoptie van OVH of een rsync van `/srv/vanemous-crm/data`) regel je apart:
|
Back-ups buiten de server (bijv. de back-upoptie van OVH of een rsync van `/srv/vanemous-crm/data`) regel je apart:
|
||||||
de nachtelijke kopie staat op dezelfde schijf en dekt `uploads/` niet.
|
de nachtelijke kopie staat op dezelfde schijf en dekt `uploads/` niet.
|
||||||
|
|
||||||
|
### Tectum (configurator) op dezelfde server
|
||||||
|
|
||||||
|
De configurator (`../configurator`) staat als statische site op een eigen subdomein, helemaal achter één
|
||||||
|
wachtwoord (nginx basic auth). Eenmalig, na `server/setup.sh`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
scp -r server ubuntu@SERVER:
|
||||||
|
ssh -t ubuntu@SERVER sudo bash server/tectum-setup.sh tectum.voorbeeld.nl jij@voorbeeld.nl [gebruikersnaam]
|
||||||
|
```
|
||||||
|
|
||||||
|
Dat vraagt het wachtwoord (gebruikersnaam standaard `vanemous`; wijzigen: `sudo WACHTWOORD=1 bash ...`), maakt
|
||||||
|
`/srv/www/tectum` (van `crm`, zodat releases via dezelfde SSH-toegang gaan) en de nginx-site met HTTPS.
|
||||||
|
Uitrollen of terugrollen vanaf je eigen machine, vanuit een tag van de configurator:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
tools/tectum-release.sh crm@tectum.voorbeeld.nl # nieuwste tag
|
||||||
|
tools/tectum-release.sh crm@tectum.voorbeeld.nl v0.7.6 # bepaalde versie
|
||||||
|
```
|
||||||
|
|
||||||
## Opslag
|
## Opslag
|
||||||
|
|
||||||
Alles staat in `data/`: `crm.db` (SQLite), `uploads/` (bestanden), `secret.key` (sessies).
|
Alles staat in `data/`: `crm.db` (SQLite), `uploads/` (bestanden), `secret.key` (sessies).
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Starten: python app.py
|
|||||||
E-mail ophalen: python app.py sync (bijv. elke 10 minuten via cron)
|
E-mail ophalen: python app.py sync (bijv. elke 10 minuten via cron)
|
||||||
Demoleads: python app.py demo (standaardmodellen uit demo/modellen als gekozen model)
|
Demoleads: python app.py demo (standaardmodellen uit demo/modellen als gekozen model)
|
||||||
"""
|
"""
|
||||||
__version__ = '0.0.2'
|
__version__ = '0.0.3'
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
import io
|
import io
|
||||||
|
|||||||
Executable
+66
@@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Eenmalig op de server (na server/setup.sh): Tectum, de configurator, als statische site achter een wachtwoord.
|
||||||
|
#
|
||||||
|
# scp -r server ubuntu@SERVER:
|
||||||
|
# ssh -t ubuntu@SERVER sudo bash server/tectum-setup.sh tectum.voorbeeld.nl jij@voorbeeld.nl [gebruikersnaam]
|
||||||
|
#
|
||||||
|
# Vraagt het wachtwoord als die gebruiker nog niet bestaat; met WACHTWOORD=1 ervoor wijzig je het:
|
||||||
|
# ssh -t ubuntu@SERVER sudo WACHTWOORD=1 bash server/tectum-setup.sh tectum.voorbeeld.nl jij@voorbeeld.nl
|
||||||
|
# Daarna rolt tools/tectum-release.sh (op je eigen machine) een versie uit naar crm@SERVER.
|
||||||
|
# Opnieuw draaien kan: elke stap controleert wat er al is.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DOMAIN="${1:-}"
|
||||||
|
EMAIL="${2:-}"
|
||||||
|
LOGIN="${3:-vanemous}"
|
||||||
|
ROOT=/srv/www/tectum
|
||||||
|
SITE=tectum
|
||||||
|
HTPASSWD=/etc/nginx/tectum.htpasswd
|
||||||
|
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 tectum-setup.sh <domein> <e-mail voor Let's Encrypt> [gebruikersnaam]"
|
||||||
|
id crm >/dev/null 2>&1 || fail "gebruiker crm bestaat niet; draai eerst server/setup.sh"
|
||||||
|
command -v nginx >/dev/null || fail "nginx ontbreekt; draai eerst server/setup.sh"
|
||||||
|
|
||||||
|
# --- map: releases komen binnen als crm (zelfde SSH-toegang als de CRM-releases) ----------------
|
||||||
|
say "map $ROOT"
|
||||||
|
install -d -o root -g root -m 755 /srv/www
|
||||||
|
install -d -o crm -g crm -m 755 "$ROOT" "$ROOT/releases"
|
||||||
|
|
||||||
|
# --- wachtwoord ----------------------------------------------------------------------------------
|
||||||
|
touch "$HTPASSWD"
|
||||||
|
chown root:www-data "$HTPASSWD"; chmod 640 "$HTPASSWD"
|
||||||
|
if [ -n "${WACHTWOORD:-}" ] || ! grep -q "^$LOGIN:" "$HTPASSWD"; then
|
||||||
|
say "wachtwoord voor gebruiker $LOGIN"
|
||||||
|
read -rsp "Wachtwoord: " pw1 </dev/tty; echo
|
||||||
|
read -rsp "Nog een keer: " pw2 </dev/tty; echo
|
||||||
|
[ -n "$pw1" ] || fail "leeg wachtwoord"
|
||||||
|
[ "$pw1" = "$pw2" ] || fail "wachtwoorden verschillen"
|
||||||
|
hash="$(printf '%s' "$pw1" | openssl passwd -6 -stdin)"
|
||||||
|
{ grep -v "^$LOGIN:" "$HTPASSWD" || true; printf '%s:%s\n' "$LOGIN" "$hash"; } > "$HTPASSWD.new"
|
||||||
|
chown root:www-data "$HTPASSWD.new"; chmod 640 "$HTPASSWD.new"
|
||||||
|
mv "$HTPASSWD.new" "$HTPASSWD"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- nginx -------------------------------------------------------------------------------
|
||||||
|
say "nginx voor $DOMAIN"
|
||||||
|
if [ ! -f /etc/nginx/sites-available/$SITE ] || ! grep -q "listen 443" /etc/nginx/sites-available/$SITE; then
|
||||||
|
sed "s/__DOMAIN__/$DOMAIN/g" "$HERE/tectum-site.conf" > /etc/nginx/sites-available/$SITE
|
||||||
|
fi
|
||||||
|
ln -sfn /etc/nginx/sites-available/$SITE /etc/nginx/sites-enabled/$SITE
|
||||||
|
nginx -t
|
||||||
|
systemctl reload nginx
|
||||||
|
|
||||||
|
# --- 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
|
||||||
|
|
||||||
|
say "klaar. Rol nu vanaf je eigen machine een versie uit: tools/tectum-release.sh crm@$DOMAIN"
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Tectum (configurator) als statische site achter één wachtwoord (server/tectum-setup.sh vult __DOMAIN__ in;
|
||||||
|
# certbot voegt HTTPS en de doorverwijzing toe; de ACME-controle valt niet onder auth_basic).
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name __DOMAIN__;
|
||||||
|
|
||||||
|
root /srv/www/tectum/current;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
auth_basic "Tectum";
|
||||||
|
auth_basic_user_file /etc/nginx/tectum.htpasswd;
|
||||||
|
|
||||||
|
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
# steeds even navragen zodat een nieuwe versie meteen zichtbaar is
|
||||||
|
add_header Cache-Control "no-cache";
|
||||||
|
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /assets/ {
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "no-cache";
|
||||||
|
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-1
@@ -455,7 +455,9 @@
|
|||||||
const raw = JSON.parse(document.getElementById('design').textContent);
|
const raw = JSON.parse(document.getElementById('design').textContent);
|
||||||
const key = raw.model || '', model = (HouseModel.MODELS || {})[key];
|
const key = raw.model || '', model = (HouseModel.MODELS || {})[key];
|
||||||
const name = (st.project && st.project.naam) || (model && model.label) || 'Uw woning';
|
const name = (st.project && st.project.naam) || (model && model.label) || 'Uw woning';
|
||||||
const full = HouseModel.computeParts(st, { skip3D: true });
|
// Afgewerkte woning met 3D, zoals light.js: met skip3D hebben de wandstukken geen specs (gewicht) en faalt computeTotals.
|
||||||
|
const full = HouseModel.computeParts(st, Object.assign({ layers: ViewLayers.all(), finishedOnly: true }, mats));
|
||||||
|
HouseModel.rootGroups(full).forEach(disposeGeo);
|
||||||
const totals = HouseModel.computeTotals(full), d = HouseModel.computeDimensions(full, S.groundLevel);
|
const totals = HouseModel.computeTotals(full), d = HouseModel.computeDimensions(full, S.groundLevel);
|
||||||
const info = {
|
const info = {
|
||||||
price: CostModel.compute(full, totals).summary.inclBtw, kg: totals.totalKg, units: st.units.length,
|
price: CostModel.compute(full, totals).summary.inclBtw, kg: totals.totalKg, units: st.units.length,
|
||||||
|
|||||||
Executable
+41
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Een getagde versie van Tectum (de configurator) naar de server brengen (eerst eenmalig server/tectum-setup.sh).
|
||||||
|
#
|
||||||
|
# tools/tectum-release.sh crm@tectum.voorbeeld.nl nieuwste tag
|
||||||
|
# tools/tectum-release.sh crm@tectum.voorbeeld.nl v0.7.6 een bepaalde versie (ook om terug te rollen)
|
||||||
|
#
|
||||||
|
# De bestanden komen uit `git archive <tag>` van $CONFIGURATOR (standaard ../configurator), dus niet-gecommit
|
||||||
|
# werk gaat niet mee. rsync met hardlinks naar de vorige versie, zodat alleen wijzigingen over de lijn gaan;
|
||||||
|
# daarna wijst `current` naar de nieuwe versie. De laatste 5 versies blijven staan.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
HOST="${1:-}"
|
||||||
|
CONFIGURATOR="${CONFIGURATOR:-$REPO/../configurator}"
|
||||||
|
ROOT=/srv/www/tectum
|
||||||
|
|
||||||
|
say() { printf '\033[38;2;185;89;19m▸\033[0m %s\n' "$*"; }
|
||||||
|
fail() { printf 'Fout: %s\n' "$*" >&2; exit 1; }
|
||||||
|
|
||||||
|
[ -n "$HOST" ] || fail "gebruik: tools/tectum-release.sh crm@server [vX.Y.Z]"
|
||||||
|
[ -f "$CONFIGURATOR/index.html" ] || fail "geen configurator in $CONFIGURATOR (zet CONFIGURATOR=pad)"
|
||||||
|
TAG="${2:-$(git -C "$CONFIGURATOR" tag --list 'v*' --sort=-v:refname | head -n1)}"
|
||||||
|
[[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || fail "onbekende versie '$TAG' (verwacht vX.Y.Z)"
|
||||||
|
git -C "$CONFIGURATOR" rev-parse -q --verify "refs/tags/$TAG" >/dev/null || fail "tag $TAG bestaat niet"
|
||||||
|
[ -z "$(git -C "$CONFIGURATOR" status --porcelain)" ] || say "let op: niet-gecommitte wijzigingen in de configurator zitten niet in $TAG"
|
||||||
|
|
||||||
|
tmp="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$tmp"' EXIT
|
||||||
|
chmod 755 "$tmp" # mktemp maakt hem 700, en rsync -a neemt dat mee (nginx moet erin kunnen)
|
||||||
|
git -C "$CONFIGURATOR" archive "$TAG" | tar -x -C "$tmp"
|
||||||
|
rm -f "$tmp/README.md" "$tmp/start.sh" "$tmp/.gitignore"
|
||||||
|
|
||||||
|
say "Tectum $TAG uploaden naar $HOST"
|
||||||
|
ssh "$HOST" "mkdir -p $ROOT/releases/$TAG"
|
||||||
|
rsync -az --delete --link-dest="$ROOT/current/" "$tmp/" "$HOST:$ROOT/releases/$TAG/"
|
||||||
|
|
||||||
|
say "$TAG actief maken"
|
||||||
|
ssh "$HOST" "set -e; cd $ROOT; ln -sfn releases/$TAG current.new; mv -T current.new current
|
||||||
|
ls -1 releases | sort -V | head -n -5 | grep -vxF '$TAG' | sed 's|^|releases/|' | xargs -r rm -rf"
|
||||||
|
|
||||||
|
say "klaar: Tectum $TAG staat live"
|
||||||
Reference in New Issue
Block a user