Names the deployed instance slpsoftware, not the software itself
SlpModularCms is the product; slpsoftware.nl is the customer running it - the first one, and a fine stand-in for what a real deployment looks like. Renamed the directories, systemd units, and backup paths accordingly. Left the backup script's own filename alone since the already-committed deploy-scp.yaml calls it by that exact name.
This commit is contained in:
@@ -1323,3 +1323,14 @@ by Infrastructure Design. U5 carries REF-U3-01's Umami origin gate plus FR-21 an
|
||||
**Context**: OPERATIONS — Deployment Setup, directory naming convention change before final approval
|
||||
|
||||
---
|
||||
## Deployment Setup — Instance-Specific Naming (slpsoftware, not slpmodularcms)
|
||||
|
||||
**Timestamp**: 2026-07-28T04:20:00Z
|
||||
|
||||
**User Input**: "omdat SLP Modular CMS voor meerdere klanten gebruikt kan worden is de mapnaam slpmodularcms niet logisch. kan je in de documentatie of een placeholder gebruiken of slpsoftware. slpsoftware is namenlijk mijn eigen site en de eerste gebruiker dus een prima voorbeeld om te gebruiken"
|
||||
|
||||
**AI Response**: "Correct distinction: SlpModularCms is the software (multi-tenant capable), slpsoftware.nl is this specific customer instance. Renamed all instance-scoped naming (directories under ~/apps/ and /mnt/storage1/www/html/, systemd unit names, backup directory, backup credentials file, DB_NAME examples) from slpmodularcms to slpsoftware throughout deployment-instructions.md and rollback-plan.md. Left unchanged what's genuinely software-level, not instance-level: the backup script's own filename (backup-slpmodularcms-db.sh, matching the actual hardcoded reference in the already-committed deploy-scp.yaml), the SlpModularCms.Api.dll binary name, the systemd Description= string, and JwtSettings Issuer/Audience (existing app-config convention from README.md, unrelated to this feature). Added a naming note at the top of deployment-instructions.md explaining the instance-vs-software distinction for future customers."
|
||||
|
||||
**Context**: OPERATIONS — Deployment Setup, instance-naming correction before final approval
|
||||
|
||||
---
|
||||
|
||||
+33
-27
@@ -4,6 +4,12 @@
|
||||
directory, `systemd --user` unit, and local port. Domains: `test.slpsoftware.nl` (test),
|
||||
`slpsoftware.nl` (production).
|
||||
|
||||
**Naming note**: directories, systemd units and the website-upload path below are named
|
||||
`slpsoftware` — the **customer/instance** running SlpModularCms (this repo's software), not the
|
||||
software itself. SlpModularCms can host multiple customers; `slpsoftware` is this one — the first,
|
||||
and the owner's own site. A future second customer on the same Pi would get its own instance name
|
||||
throughout, following the same pattern.
|
||||
|
||||
---
|
||||
|
||||
## 1. One-Time Host Setup
|
||||
@@ -35,7 +41,7 @@ sudo useradd -m -s /bin/bash gitea-workflow
|
||||
sudo passwd gitea-workflow
|
||||
```
|
||||
Each project deploying through this account gets its own subdirectory under its home (§ 1.4 already
|
||||
namespaces by project: `~/apps/slpmodularcms/<env>/`), so one generic account can serve multiple
|
||||
namespaces by project: `~/apps/slpsoftware/<env>/`), so one generic account can serve multiple
|
||||
projects without their release trees colliding.
|
||||
|
||||
**Fallback, only if no SSH-capable account exists at all and creating one genuinely isn't feasible**
|
||||
@@ -66,25 +72,25 @@ for the CMS's own release/current/shared structure to live anywhere near the oth
|
||||
which directly avoids interfering with them (as you asked in Q2):
|
||||
|
||||
```bash
|
||||
mkdir -p ~/apps/slpmodularcms/<env>/releases
|
||||
mkdir -p ~/apps/slpsoftware/<env>/releases
|
||||
```
|
||||
|
||||
`current` is created by the first deploy itself (`ln -sfn`) — don't pre-create it.
|
||||
|
||||
**`shared/wwwroot-web` is the one exception** — it must resolve to wherever `webadmin` actually
|
||||
uploads *this* customer's website via FileZilla, e.g. `/mnt/storage1/www/html/slpmodularcms/<env>/`
|
||||
uploads *this* customer's website via FileZilla, e.g. `/mnt/storage1/www/html/slpsoftware/<env>/`
|
||||
(adjust the exact folder name to whatever convention the other sites under `html/` already use, if
|
||||
one exists). Rather than a plain directory, make it a symlink across accounts:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/apps/slpmodularcms/<env>
|
||||
ln -s /mnt/storage1/www/html/slpmodularcms/<env> ~/apps/slpmodularcms/<env>/shared/wwwroot-web
|
||||
mkdir -p ~/apps/slpsoftware/<env>
|
||||
ln -s /mnt/storage1/www/html/slpsoftware/<env> ~/apps/slpsoftware/<env>/shared/wwwroot-web
|
||||
```
|
||||
|
||||
`deploy-scp.yaml`'s existing logic (`releases/{ts}/wwwroot/web -> ../../../shared/wwwroot-web`)
|
||||
needs no changes for this — it only ever resolves the symlink chain, it doesn't care how many hops
|
||||
that chain has. What **does** need attention: `gitea-workflow` needs read + traverse permission on
|
||||
`/mnt/storage1/www/html/slpmodularcms/<env>/` and its parent directories, which `webadmin` owns.
|
||||
`/mnt/storage1/www/html/slpsoftware/<env>/` and its parent directories, which `webadmin` owns.
|
||||
Simplest fix: put both accounts in a shared group (e.g. `webshared`), `chgrp -R webshared` that
|
||||
folder, and make sure webadmin's FTP server creates new uploads group-readable (`g+rx`, not just
|
||||
owner-readable) — a one-time permission setup, not something either pipeline touches per deploy.
|
||||
@@ -92,15 +98,15 @@ owner-readable) — a one-time permission setup, not something either pipeline t
|
||||
### 1.5 Runtime Configuration File
|
||||
One file per environment, **outside** the release directory so it survives every switch:
|
||||
```bash
|
||||
touch ~/apps/slpmodularcms/<env>/shared/env
|
||||
chmod 600 ~/apps/slpmodularcms/<env>/shared/env
|
||||
touch ~/apps/slpsoftware/<env>/shared/env
|
||||
chmod 600 ~/apps/slpsoftware/<env>/shared/env
|
||||
```
|
||||
Contents (fill in real values — this file is never read by the workflow, only by the systemd unit
|
||||
below):
|
||||
```ini
|
||||
ASPNETCORE_ENVIRONMENT=Production
|
||||
ASPNETCORE_URLS=http://localhost:<port>
|
||||
ConnectionStrings__DefaultConnection=Server=127.0.0.1,1433;User ID=<user>;Password=<password>;Database=SlpModularCms<Env>;TrustServerCertificate=True
|
||||
ConnectionStrings__DefaultConnection=Server=127.0.0.1,1433;User ID=<user>;Password=<password>;Database=SlpSoftware<Env>;TrustServerCertificate=True
|
||||
JwtSettings__Secret=<secure-long-random-secret>
|
||||
JwtSettings__Issuer=SlpModularCms
|
||||
JwtSettings__Audience=SlpModularCmsPortal
|
||||
@@ -120,16 +126,16 @@ gate only catches drift between the frontend build and that Gitea variable; it c
|
||||
so keeping the two in sync is a manual discipline, not something enforced automatically.
|
||||
|
||||
### 1.6 systemd User Units
|
||||
Create `~/.config/systemd/user/slpmodularcms-test.service`:
|
||||
Create `~/.config/systemd/user/slpsoftware-test.service`:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=SlpModularCms API (test)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=%h/apps/slpmodularcms/test/current
|
||||
ExecStart=/usr/bin/dotnet %h/apps/slpmodularcms/test/current/SlpModularCms.Api.dll
|
||||
EnvironmentFile=%h/apps/slpmodularcms/test/shared/env
|
||||
WorkingDirectory=%h/apps/slpsoftware/test/current
|
||||
ExecStart=/usr/bin/dotnet %h/apps/slpsoftware/test/current/SlpModularCms.Api.dll
|
||||
EnvironmentFile=%h/apps/slpsoftware/test/shared/env
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
KillSignal=SIGINT
|
||||
@@ -138,14 +144,14 @@ TimeoutStopSec=20
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
And `~/.config/systemd/user/slpmodularcms-production.service` — identical, with `test` replaced by
|
||||
And `~/.config/systemd/user/slpsoftware-production.service` — identical, with `test` replaced by
|
||||
`production` throughout (including the port inside `shared/env`).
|
||||
|
||||
Enable both (does not start them yet — nothing is deployed there until the first CI run):
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable slpmodularcms-test.service
|
||||
systemctl --user enable slpmodularcms-production.service
|
||||
systemctl --user enable slpsoftware-test.service
|
||||
systemctl --user enable slpsoftware-production.service
|
||||
```
|
||||
|
||||
### 1.7 nginx Routing
|
||||
@@ -177,12 +183,12 @@ feature — assumed already handled the same way the reference project's domains
|
||||
|
||||
### 1.8 Database Backup Credentials (§ 4 depends on this)
|
||||
```bash
|
||||
touch ~/.config/slpmodularcms-db-backup.env
|
||||
chmod 600 ~/.config/slpmodularcms-db-backup.env
|
||||
touch ~/.config/slpsoftware-db-backup.env
|
||||
chmod 600 ~/.config/slpsoftware-db-backup.env
|
||||
```
|
||||
```ini
|
||||
DB_SERVER=127.0.0.1,1433
|
||||
DB_NAME=SlpModularCmsProduction
|
||||
DB_NAME=SlpSoftwareProduction
|
||||
DB_USER=<a-login-with-backup-database-permission>
|
||||
DB_PASSWORD=<password>
|
||||
```
|
||||
@@ -202,10 +208,10 @@ change:
|
||||
| `PI_MAIN_PORT` | secret | SSH port |
|
||||
| `PI_MAIN_USERNAME` | secret | `gitea-workflow` — the generic, host-wide deploy account (§ 1.2), **not** `webadmin`; reuse the reference project's if it already has one |
|
||||
| `PI_MAIN_PASSWORD` | secret | `gitea-workflow`'s password |
|
||||
| `DEPLOY_PATH_TEST` | variable | `/home/gitea-workflow/apps/slpmodularcms/test` |
|
||||
| `DEPLOY_PATH_PRODUCTION` | variable | `/home/gitea-workflow/apps/slpmodularcms/production` |
|
||||
| `SERVICE_NAME_TEST` | variable | `slpmodularcms-test.service` |
|
||||
| `SERVICE_NAME_PRODUCTION` | variable | `slpmodularcms-production.service` |
|
||||
| `DEPLOY_PATH_TEST` | variable | `/home/gitea-workflow/apps/slpsoftware/test` |
|
||||
| `DEPLOY_PATH_PRODUCTION` | variable | `/home/gitea-workflow/apps/slpsoftware/production` |
|
||||
| `SERVICE_NAME_TEST` | variable | `slpsoftware-test.service` |
|
||||
| `SERVICE_NAME_PRODUCTION` | variable | `slpsoftware-production.service` |
|
||||
| `HEALTH_CHECK_URL_TEST` | variable | `https://test.slpsoftware.nl/health` |
|
||||
| `HEALTH_CHECK_URL_PRODUCTION` | variable | `https://slpsoftware.nl/health` |
|
||||
| `VITE_SENTRY_DSN` | variable | Sentry DSN (shared, not sensitive — safe in the client bundle) |
|
||||
@@ -223,7 +229,7 @@ Already built (U5/U6) — this is the read-only walkthrough for whoever operates
|
||||
2. `publish-test` runs (and `publish-production`, only if `workflow_dispatch` with the flag)
|
||||
3. `deploy-test` (always, if gates pass) calls `deploy-scp.yaml`, which uploads into a new
|
||||
`releases/{timestamp}/`, links `shared/wwwroot-web` in, switches `current`, restarts
|
||||
`slpmodularcms-test.service`, verifies `https://test.slpsoftware.nl/health`, then prunes old
|
||||
`slpsoftware-test.service`, verifies `https://test.slpsoftware.nl/health`, then prunes old
|
||||
releases (only test — `run_db_backup: false`)
|
||||
4. `deploy-production` (only with the flag) does the same, plus a database backup first
|
||||
(`run_db_backup: true`) — see § 4
|
||||
@@ -246,7 +252,7 @@ part of this repository, so no DB credential ever reaches Gitea):
|
||||
set -euo pipefail
|
||||
|
||||
ENVIRONMENT="${1:?Usage: backup-slpmodularcms-db.sh <environment>}"
|
||||
CREDENTIALS_FILE="$HOME/.config/slpmodularcms-db-backup.env"
|
||||
CREDENTIALS_FILE="$HOME/.config/slpsoftware-db-backup.env"
|
||||
|
||||
if [[ ! -f "$CREDENTIALS_FILE" ]]; then
|
||||
echo "Missing $CREDENTIALS_FILE — see deployment-instructions.md § 1.8" >&2
|
||||
@@ -256,7 +262,7 @@ fi
|
||||
source "$CREDENTIALS_FILE"
|
||||
: "${DB_SERVER:?}" "${DB_NAME:?}" "${DB_USER:?}" "${DB_PASSWORD:?}"
|
||||
|
||||
BACKUP_DIR="$HOME/backups/slpmodularcms/${ENVIRONMENT}"
|
||||
BACKUP_DIR="$HOME/backups/slpsoftware/${ENVIRONMENT}"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
TIMESTAMP=$(date -u +%Y%m%d%H%M%S)
|
||||
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}-${TIMESTAMP}.bak"
|
||||
@@ -278,7 +284,7 @@ chmod +x ~/scripts/backup-slpmodularcms-db.sh
|
||||
```bash
|
||||
~/scripts/backup-slpmodularcms-db.sh production
|
||||
```
|
||||
Confirm a `.bak` file appears under `~/backups/slpmodularcms/production/` and that `sqlcmd` didn't
|
||||
Confirm a `.bak` file appears under `~/backups/slpsoftware/production/` and that `sqlcmd` didn't
|
||||
silently fail (the script uses `set -euo pipefail`, so a real SQL error does propagate as a non-zero
|
||||
exit — which fails the calling `deploy-scp.yaml` step, correctly blocking the deploy).
|
||||
|
||||
|
||||
+3
-3
@@ -16,10 +16,10 @@ failed deploy never leaves fewer than two releases on disk.
|
||||
No rebuild needed. Over SSH, on the Pi:
|
||||
|
||||
```bash
|
||||
cd ~/apps/slpmodularcms/<env>/releases
|
||||
cd ~/apps/slpsoftware/<env>/releases
|
||||
ls -1t # confirm which directory is the previous, working release
|
||||
ln -sfn ~/apps/slpmodularcms/<env>/releases/<previous-timestamp> ~/apps/slpmodularcms/<env>/current
|
||||
systemctl --user restart slpmodularcms-<env>.service
|
||||
ln -sfn ~/apps/slpsoftware/<env>/releases/<previous-timestamp> ~/apps/slpsoftware/<env>/current
|
||||
systemctl --user restart slpsoftware-<env>.service
|
||||
curl -f https://<env-domain>/health # confirm the rollback itself is healthy
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user