v0.3.1 - UI restyle, inklapbaar menu, taalmodule
This commit is contained in:
parent
d866a13c20
commit
34edd95c9b
8 changed files with 1306 additions and 2 deletions
47
.forgejo/workflows/build.yml
Normal file
47
.forgejo/workflows/build.yml
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Forgejo Actions — bouw + push image bij elke tag-push
|
||||||
|
#
|
||||||
|
# Activeert wanneer je `git push --tags` doet met een v*-tag.
|
||||||
|
# Bakt de tag in als SU_VERSION zodat het image z'n eigen versie kent.
|
||||||
|
#
|
||||||
|
# Vereisten in Forgejo:
|
||||||
|
# Settings → Variables → REGISTRY=git.example.com, OWNER=bes-r
|
||||||
|
# Settings → Secrets → PACKAGE_TOKEN=<token met write:package scope>
|
||||||
|
|
||||||
|
name: Build and push image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: docker
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Extract versie uit tag
|
||||||
|
id: tag
|
||||||
|
run: echo "v=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Login op Forgejo registry
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.PACKAGE_TOKEN }}" \
|
||||||
|
| docker login ${{ vars.REGISTRY }} \
|
||||||
|
-u ${{ vars.OWNER }} \
|
||||||
|
--password-stdin
|
||||||
|
|
||||||
|
- name: Bouw image met versie ingebakken
|
||||||
|
run: |
|
||||||
|
docker build \
|
||||||
|
--build-arg SU_VERSION=${{ steps.tag.outputs.v }} \
|
||||||
|
-t ${{ vars.REGISTRY }}/${{ vars.OWNER }}/server-up:${{ steps.tag.outputs.v }} \
|
||||||
|
-t ${{ vars.REGISTRY }}/${{ vars.OWNER }}/server-up:latest \
|
||||||
|
.
|
||||||
|
|
||||||
|
- name: Push image
|
||||||
|
run: |
|
||||||
|
docker push ${{ vars.REGISTRY }}/${{ vars.OWNER }}/server-up:${{ steps.tag.outputs.v }}
|
||||||
|
docker push ${{ vars.REGISTRY }}/${{ vars.OWNER }}/server-up:latest
|
||||||
23
CHANGELOG.md
23
CHANGELOG.md
|
|
@ -1,3 +1,26 @@
|
||||||
|
# v0.3.1 — UI-restyle + taalmodule (add-on)
|
||||||
|
|
||||||
|
## Nieuw in v0.3.1
|
||||||
|
|
||||||
|
### 🎨 Grondige UI-restyle
|
||||||
|
Grotere, touch-vriendelijke knoppen (min. 44px), ruimere spacing, grotere
|
||||||
|
typografie en kaarten. Layout gecentreerd met max-breedte voor meer lucht op
|
||||||
|
grote schermen. Volledig mobielvriendelijk.
|
||||||
|
|
||||||
|
### 📐 Inklapbaar menu (ook op desktop)
|
||||||
|
De hamburger klapt de sidebar nu ook op desktop in/uit; voorkeur wordt onthouden
|
||||||
|
(`localStorage`), hoofdinhoud en log-paneel schuiven mee. Op mobiel een
|
||||||
|
tap-to-close overlay.
|
||||||
|
|
||||||
|
### 🌐 Taalmodule als add-on
|
||||||
|
Nieuwe sectie in Instellingen → "Taalmodule": talen toevoegen, bewerken,
|
||||||
|
verwijderen en ingebouwde talen (NL/EN) dupliceren als startpunt. Editor toont
|
||||||
|
per sleutel de Engelse referentie met zoekfilter. Backend-endpoints:
|
||||||
|
`POST/DELETE /api/i18n`, `GET /api/i18n/keys`, `GET /api/i18n/<code>/raw`.
|
||||||
|
Toegevoegde talen komen als JSON in `translations/` en zijn direct beschikbaar.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# v0.3.01 — Boilerplates fixes + git-driven versioning
|
# v0.3.01 — Boilerplates fixes + git-driven versioning
|
||||||
|
|
||||||
## Fixes bovenop v0.3.0
|
## Fixes bovenop v0.3.0
|
||||||
|
|
|
||||||
669
docs/forgejo-actions-setup.md
Normal file
669
docs/forgejo-actions-setup.md
Normal file
|
|
@ -0,0 +1,669 @@
|
||||||
|
# Forgejo Actions — deploy-pipeline opzetten voor Server Up
|
||||||
|
|
||||||
|
Volledig stappenplan om vanuit je laptop via Forgejo automatisch te deployen naar een Ubuntu/Debian server met Docker Compose. Inclusief een dev/prod-splitsing zodat je `dev`-server alleen de ontwikkelversie krijgt en prod-servers alleen stabiele releases.
|
||||||
|
|
||||||
|
## Al eerder opgezet? Lees dit eerst
|
||||||
|
|
||||||
|
Als je de pipeline al hebt ingericht en alleen de dev/prod-splitsing wilt toevoegen, hoef je niet alles opnieuw te doen. Voer alleen deze stappen uit:
|
||||||
|
|
||||||
|
1. **Runner opnieuw registreren met label `dev`** — zie [Stap 4b](#4b-registreren-op-de-app-server)
|
||||||
|
2. **`dev`-branch aanmaken** in je repo: `git checkout -b dev && git push -u origin dev`
|
||||||
|
3. **Workflow-bestanden bijwerken** — commit en push de gewijzigde `.forgejo/workflows/deploy.yml` en nieuwe `deploy-prod.yml` naar `dev`
|
||||||
|
4. **`/opt/server-up/.env`** aanmaken voor handmatige builds buiten de pipeline:
|
||||||
|
```bash
|
||||||
|
echo "SU_VERSION=dev-handmatig" > /opt/server-up/.env
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architectuur
|
||||||
|
|
||||||
|
```
|
||||||
|
[ Laptop ]
|
||||||
|
|
|
||||||
|
| git push naar dev-branch
|
||||||
|
v
|
||||||
|
[ Forgejo VPS ] ──── dispatcht workflow ────> [ Dev-server ]
|
||||||
|
- act_runner (label: dev)
|
||||||
|
- Docker + Compose
|
||||||
|
- /opt/server-up/
|
||||||
|
|
||||||
|
[ Forgejo VPS ] ──── dispatcht workflow ────> [ Prod-server(s) ]
|
||||||
|
- act_runner (label: prod)
|
||||||
|
- Docker + Compose
|
||||||
|
- /opt/server-up/
|
||||||
|
```
|
||||||
|
|
||||||
|
Twee soorten servers:
|
||||||
|
|
||||||
|
- **Dev-server** — draait de `dev` branch. Wordt automatisch bijgewerkt bij elke push naar `dev`. Bedoeld voor testen.
|
||||||
|
- **Prod-server(s)** — draaien de `main` branch of een `v*`-tag. Worden alleen bijgewerkt als je bewust naar `main` merget of een release tagt.
|
||||||
|
|
||||||
|
De routing werkt via **runner-labels**: elke server registreert zijn runner met een eigen label (`dev` of `prod`). De workflow kiest op dat label. Zo pikt een dev-server nooit een prod-deploy op en andersom.
|
||||||
|
|
||||||
|
We draaien de runner in _host mode_: jobs draaien direct op de host, niet in een container. Dat is voor deploy-jobs verreweg het simpelst — Docker socket en bind-mount paden kloppen vanzelf.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wat je nodig hebt
|
||||||
|
|
||||||
|
- Forgejo VPS met root- of admin-toegang
|
||||||
|
- App-server (Ubuntu 22.04/24.04 of Debian 12) met root- of sudo-toegang
|
||||||
|
- DNS-naam voor je Forgejo-instance (bv. `forgejo.example.com`) met geldig TLS-certificaat
|
||||||
|
- Server Up uitgecheckt lokaal, met `Dockerfile` en `docker-compose.yml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 1 — Actions globaal aanzetten in Forgejo
|
||||||
|
|
||||||
|
Forgejo heeft **geen UI-toggle** voor Actions. Je zet het aan in `app.ini`. Zolang het uit staat zie je geen **Actions**-tab in repo's.
|
||||||
|
|
||||||
|
### 1a. Snelle check: staat het al aan?
|
||||||
|
|
||||||
|
Open een willekeurige repo in Forgejo. Zie je bovenaan een **Actions**-tab? Dan is het al aan — ga door naar stap 1d.
|
||||||
|
|
||||||
|
### 1b. `app.ini` vinden
|
||||||
|
|
||||||
|
SSH naar je Forgejo VPS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Zoek de containernaam
|
||||||
|
docker ps --format 'table {{.Names}}\t{{.Image}}' | grep -i forgejo
|
||||||
|
|
||||||
|
# Bekijk huidige Actions-config
|
||||||
|
docker exec forgejo cat /data/gitea/conf/app.ini | grep -A2 "\[actions\]" \
|
||||||
|
|| echo "Geen [actions] blok gevonden"
|
||||||
|
|
||||||
|
# Vind het hostpad van de data-map
|
||||||
|
docker inspect forgejo --format \
|
||||||
|
'{{ range .Mounts }}{{ .Source }} -> {{ .Destination }}{{ "\n" }}{{ end }}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Zoek de regel waar `Destination` `/data` is. Het bestand staat dan op `<Source>/gitea/conf/app.ini`. Typische plekken:
|
||||||
|
|
||||||
|
- `/var/lib/forgejo/gitea/conf/app.ini`
|
||||||
|
- `./forgejo/gitea/conf/app.ini` (relatief aan je `docker-compose.yml`)
|
||||||
|
- Bij een named volume: `/var/lib/docker/volumes/<naam>/_data/gitea/conf/app.ini`
|
||||||
|
|
||||||
|
### 1c. `app.ini` aanpassen en Forgejo herstarten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
APP_INI=/var/lib/forgejo/gitea/conf/app.ini # pas aan naar jouw pad
|
||||||
|
sudo cp "$APP_INI" "$APP_INI.bak"
|
||||||
|
sudo nano "$APP_INI"
|
||||||
|
```
|
||||||
|
|
||||||
|
Voeg onderaan toe — of update het bestaande `[actions]`-blok:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[actions]
|
||||||
|
ENABLED = true
|
||||||
|
DEFAULT_ACTIONS_URL = https://code.forgejo.org
|
||||||
|
```
|
||||||
|
|
||||||
|
Herstart Forgejo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose restart forgejo # in de map waar je docker-compose.yml staat
|
||||||
|
# of zonder compose:
|
||||||
|
docker restart forgejo
|
||||||
|
```
|
||||||
|
|
||||||
|
Refresh een repo-pagina — de **Actions**-tab moet nu zichtbaar zijn.
|
||||||
|
|
||||||
|
### 1d. Repo-Actions inschakelen
|
||||||
|
|
||||||
|
Ga in je repo naar **Settings → Actions → General → Enable Repository Actions** (dit is standaard aan zodra Actions globaal aan staan).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 2 — App-server voorbereiden
|
||||||
|
|
||||||
|
SSH naar de app-server als root of met `sudo`.
|
||||||
|
|
||||||
|
### 2a. Systeem up-to-date
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt update && apt upgrade -y
|
||||||
|
apt install -y curl ca-certificates gnupg git rsync ufw
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2b. Docker + Compose plugin installeren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
install -m 0755 -d /etc/apt/keyrings
|
||||||
|
curl -fsSL https://download.docker.com/linux/debian/gpg | \
|
||||||
|
gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||||
|
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||||
|
|
||||||
|
# Voor Ubuntu vervang 'debian' door 'ubuntu'
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
||||||
|
https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
|
||||||
|
> /etc/apt/sources.list.d/docker.list
|
||||||
|
|
||||||
|
apt update
|
||||||
|
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
|
systemctl enable --now docker
|
||||||
|
docker --version && docker compose version
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2c. Deploy-user aanmaken
|
||||||
|
|
||||||
|
```bash
|
||||||
|
useradd -m -s /bin/bash deploy
|
||||||
|
usermod -aG docker deploy
|
||||||
|
mkdir -p /opt/server-up
|
||||||
|
chown deploy:deploy /opt/server-up
|
||||||
|
```
|
||||||
|
|
||||||
|
De runner draait als `deploy`. Door deze user in de `docker`-groep te zetten kan hij `docker compose` zonder sudo aanroepen.
|
||||||
|
|
||||||
|
### 2d. Firewall (optioneel maar aanbevolen)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ufw default deny incoming
|
||||||
|
ufw default allow outgoing
|
||||||
|
ufw allow OpenSSH
|
||||||
|
ufw allow 80/tcp
|
||||||
|
ufw allow 443/tcp
|
||||||
|
ufw enable
|
||||||
|
```
|
||||||
|
|
||||||
|
De runner heeft alleen _uitgaande_ HTTPS naar je Forgejo nodig — geen inkomende poort.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 3 — Act_runner installeren
|
||||||
|
|
||||||
|
Forgejo gebruikt `act_runner` als runner-daemon.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Controleer de nieuwste versie op:
|
||||||
|
# https://code.forgejo.org/forgejo/act_runner/releases
|
||||||
|
VERSION=6.2.2
|
||||||
|
ARCH=amd64 # of arm64 voor ARM-servers
|
||||||
|
curl -fsSL -o /usr/local/bin/act_runner \
|
||||||
|
"https://code.forgejo.org/forgejo/runner/releases/download/v${VERSION}/forgejo-runner-${VERSION}-linux-${ARCH}"
|
||||||
|
chmod +x /usr/local/bin/act_runner
|
||||||
|
act_runner --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### Werkdirectory en config
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /etc/act_runner /var/lib/act_runner
|
||||||
|
chown deploy:deploy /var/lib/act_runner
|
||||||
|
act_runner generate-config > /etc/act_runner/config.yaml
|
||||||
|
chown root:deploy /etc/act_runner/config.yaml
|
||||||
|
chmod 640 /etc/act_runner/config.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Open `/etc/act_runner/config.yaml` en pas deze velden aan:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
runner:
|
||||||
|
file: /var/lib/act_runner/.runner
|
||||||
|
capacity: 1
|
||||||
|
timeout: 30m
|
||||||
|
insecure: false
|
||||||
|
fetch_timeout: 5s
|
||||||
|
fetch_interval: 2s
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
dir: /var/lib/act_runner/cache
|
||||||
|
host:
|
||||||
|
workdir_parent: /var/lib/act_runner/host-work
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 4 — Runner registreren
|
||||||
|
|
||||||
|
### 4a. Token ophalen uit Forgejo
|
||||||
|
|
||||||
|
Ga in Forgejo naar je repo → **Settings → Actions → Runners → Create new Runner**. Kopieer het token.
|
||||||
|
|
||||||
|
Kies het niveau dat bij je gebruik past:
|
||||||
|
|
||||||
|
- **Repo-niveau** (alleen deze repo) — veiligst
|
||||||
|
- **Organization-niveau** — handig als je meerdere repo's hebt
|
||||||
|
- **Site-niveau** — alleen als je veel repo's wilt deployen
|
||||||
|
|
||||||
|
### 4b. Registreren op de app-server
|
||||||
|
|
||||||
|
**Dev-server** — registreer met label `dev`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u deploy bash -c '
|
||||||
|
cd /var/lib/act_runner && \
|
||||||
|
act_runner register \
|
||||||
|
--no-interactive \
|
||||||
|
--instance https://jouw-forgejo-url \
|
||||||
|
--token JOUW_TOKEN \
|
||||||
|
--name dev-server \
|
||||||
|
--labels self-hosted,dev \
|
||||||
|
--config /etc/act_runner/config.yaml
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Prod-server** — registreer met label `prod`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u deploy bash -c '
|
||||||
|
cd /var/lib/act_runner && \
|
||||||
|
act_runner register \
|
||||||
|
--no-interactive \
|
||||||
|
--instance https://jouw-forgejo-url \
|
||||||
|
--token JOUW_TOKEN \
|
||||||
|
--name prod-server-1 \
|
||||||
|
--labels self-hosted,prod \
|
||||||
|
--config /etc/act_runner/config.yaml
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Al geregistreerd met andere labels?** Stop de service, verwijder het `.runner`-bestand en registreer opnieuw:
|
||||||
|
> ```bash
|
||||||
|
> systemctl stop act_runner
|
||||||
|
> rm /var/lib/act_runner/.runner
|
||||||
|
> # voer daarna bovenstaand register-commando uit
|
||||||
|
> ```
|
||||||
|
|
||||||
|
Controleer in Forgejo onder **Settings → Actions → Runners** — je runner staat als **Idle**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 5 — Runner als systemd-service instellen
|
||||||
|
|
||||||
|
Doe dit op elke server na de registratie:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat > /etc/systemd/system/act_runner.service << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Forgejo Actions runner
|
||||||
|
After=network-online.target docker.service
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=deploy
|
||||||
|
Group=deploy
|
||||||
|
WorkingDirectory=/var/lib/act_runner
|
||||||
|
ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
NoNewPrivileges=true
|
||||||
|
ProtectSystem=full
|
||||||
|
ProtectHome=read-only
|
||||||
|
PrivateTmp=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now act_runner
|
||||||
|
systemctl status act_runner
|
||||||
|
```
|
||||||
|
|
||||||
|
Logs volgen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl -u act_runner -f
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 6 — Branches inrichten
|
||||||
|
|
||||||
|
De workflows zijn opgezet rond twee branches:
|
||||||
|
|
||||||
|
| Branch | Doel | Deploy naar |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| `dev` | Ontwikkeling, testen | Dev-server |
|
||||||
|
| `main` | Stabiele releases | Prod-server(s) |
|
||||||
|
|
||||||
|
Maak de `dev`-branch aan als die er nog niet is:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout -b dev
|
||||||
|
git push -u origin dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Typische werkwijze:
|
||||||
|
|
||||||
|
```
|
||||||
|
feature-branch → merge naar dev → automatisch op dev-server getest
|
||||||
|
dev → stabiel → merge naar main → automatisch op prod-server(s)
|
||||||
|
main → git tag v1.2.3 → deploy met versienummer ingebakken
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 7 — Workflow-bestanden
|
||||||
|
|
||||||
|
De repo bevat twee deploy-workflows in `.forgejo/workflows/`:
|
||||||
|
|
||||||
|
### `deploy.yml` — dev-server
|
||||||
|
|
||||||
|
Triggert bij elke push naar `dev`. Draait alleen op runners met label `dev`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Deploy server-up (dev)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [dev]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: server-up-deploy-dev
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: [self-hosted, dev]
|
||||||
|
timeout-minutes: 20
|
||||||
|
|
||||||
|
env:
|
||||||
|
DEPLOY_DIR: /opt/server-up
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Bepaal versie
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
VERSION="dev-${GITHUB_SHA:0:8}"
|
||||||
|
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
|
||||||
|
echo "SU_VERSION=${VERSION}" >> "$GITHUB_ENV"
|
||||||
|
echo "CHANNEL=dev" >> "$GITHUB_ENV"
|
||||||
|
echo "Deploying version: ${VERSION}"
|
||||||
|
|
||||||
|
- name: Sync code naar deploy-directory
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
rsync -a --delete \
|
||||||
|
--exclude='.git/' \
|
||||||
|
--exclude='.forgejo/' \
|
||||||
|
./ "$DEPLOY_DIR/"
|
||||||
|
|
||||||
|
- name: Schrijf VERSION-bestand
|
||||||
|
working-directory: ${{ env.DEPLOY_DIR }}
|
||||||
|
run: echo "${VERSION}" > VERSION
|
||||||
|
|
||||||
|
- name: Build image
|
||||||
|
working-directory: ${{ env.DEPLOY_DIR }}
|
||||||
|
run: |
|
||||||
|
docker compose build --pull
|
||||||
|
docker tag "server-up:${VERSION}" server-up:latest
|
||||||
|
docker tag "server-up:${VERSION}" server-up:dev
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
working-directory: ${{ env.DEPLOY_DIR }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
docker compose up -d --remove-orphans
|
||||||
|
docker compose ps
|
||||||
|
|
||||||
|
- name: Wachten op healthcheck
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
for i in {1..40}; do
|
||||||
|
status=$(docker inspect --format '{{.State.Health.Status}}' server-up 2>/dev/null || echo "starting")
|
||||||
|
echo "poll $i: $status"
|
||||||
|
if [ "$status" = "healthy" ]; then
|
||||||
|
echo "server-up is healthy als versie ${VERSION}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
|
echo "server-up werd niet healthy in tijd — logs:"
|
||||||
|
cd "$DEPLOY_DIR" && docker compose logs --tail=200
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
- name: Oude images opruimen (behoud laatste 5)
|
||||||
|
if: success()
|
||||||
|
run: |
|
||||||
|
docker images server-up --format '{{.Tag}} {{.ID}}' \
|
||||||
|
| grep -vE '^(latest|release|dev) ' \
|
||||||
|
| tail -n +6 \
|
||||||
|
| awk '{print $2}' \
|
||||||
|
| xargs -r docker rmi -f || true
|
||||||
|
docker image prune -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### `deploy-prod.yml` — prod-servers
|
||||||
|
|
||||||
|
Triggert bij push naar `main` of een `v*`-tag. Draait alleen op runners met label `prod`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Deploy server-up (prod)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
tags: ['v*']
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: server-up-deploy-prod
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: [self-hosted, prod]
|
||||||
|
timeout-minutes: 20
|
||||||
|
|
||||||
|
env:
|
||||||
|
DEPLOY_DIR: /opt/server-up
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Bepaal versie
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
|
||||||
|
VERSION="${GITHUB_REF_NAME}"
|
||||||
|
CHANNEL="release"
|
||||||
|
else
|
||||||
|
VERSION="main-${GITHUB_SHA:0:8}"
|
||||||
|
CHANNEL="main"
|
||||||
|
fi
|
||||||
|
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
|
||||||
|
echo "CHANNEL=${CHANNEL}" >> "$GITHUB_ENV"
|
||||||
|
echo "SU_VERSION=${VERSION}" >> "$GITHUB_ENV"
|
||||||
|
echo "Deploying version: ${VERSION} (${CHANNEL})"
|
||||||
|
|
||||||
|
- name: Sync code naar deploy-directory
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
rsync -a --delete \
|
||||||
|
--exclude='.git/' \
|
||||||
|
--exclude='.forgejo/' \
|
||||||
|
./ "$DEPLOY_DIR/"
|
||||||
|
|
||||||
|
- name: Schrijf VERSION-bestand
|
||||||
|
working-directory: ${{ env.DEPLOY_DIR }}
|
||||||
|
run: echo "${VERSION}" > VERSION
|
||||||
|
|
||||||
|
- name: Build image
|
||||||
|
working-directory: ${{ env.DEPLOY_DIR }}
|
||||||
|
run: |
|
||||||
|
docker compose build --pull
|
||||||
|
docker tag "server-up:${VERSION}" server-up:latest
|
||||||
|
docker tag "server-up:${VERSION}" "server-up:${CHANNEL}"
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
working-directory: ${{ env.DEPLOY_DIR }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
docker compose up -d --remove-orphans
|
||||||
|
docker compose ps
|
||||||
|
|
||||||
|
- name: Wachten op healthcheck
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
for i in {1..40}; do
|
||||||
|
status=$(docker inspect --format '{{.State.Health.Status}}' server-up 2>/dev/null || echo "starting")
|
||||||
|
echo "poll $i: $status"
|
||||||
|
if [ "$status" = "healthy" ]; then
|
||||||
|
echo "server-up is healthy als versie ${VERSION}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
|
echo "server-up werd niet healthy in tijd — logs:"
|
||||||
|
cd "$DEPLOY_DIR" && docker compose logs --tail=200
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
- name: Oude images opruimen (behoud laatste 5)
|
||||||
|
if: success()
|
||||||
|
run: |
|
||||||
|
docker images server-up --format '{{.Tag}} {{.ID}}' \
|
||||||
|
| grep -vE '^(latest|release|main) ' \
|
||||||
|
| tail -n +6 \
|
||||||
|
| awk '{print $2}' \
|
||||||
|
| xargs -r docker rmi -f || true
|
||||||
|
docker image prune -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wat doet een deploy-workflow?
|
||||||
|
|
||||||
|
1. Code uitchecken in de runner-workspace
|
||||||
|
2. Versienummer bepalen (`dev-<sha>` voor dev, `v1.2.3` voor tags)
|
||||||
|
3. Code naar `/opt/server-up` synchen via `rsync --delete`
|
||||||
|
4. Docker-image bouwen met `docker compose build --pull` en `SU_VERSION` ingebakken
|
||||||
|
5. Container herstarten met `docker compose up -d`
|
||||||
|
6. Wachten tot de healthcheck groen is (max. ~2 minuten)
|
||||||
|
7. Oude images opruimen (behoudt de laatste 5)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 8 — Handmatig triggeren
|
||||||
|
|
||||||
|
Elke workflow heeft `workflow_dispatch`, waarmee je hem handmatig start zonder een commit:
|
||||||
|
|
||||||
|
**Forgejo UI**: Actions → selecteer de workflow → **Run workflow**
|
||||||
|
|
||||||
|
Handig als je de pipeline opnieuw wilt draaien na een serverherstel of configuratiewijziging.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 9 — Eerste deploy testen
|
||||||
|
|
||||||
|
Vanuit je repo op je laptop:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout dev
|
||||||
|
echo "# Deploy test $(date)" >> README.md
|
||||||
|
git add README.md
|
||||||
|
git commit -m "ci: trigger first deploy"
|
||||||
|
git push origin dev
|
||||||
|
```
|
||||||
|
|
||||||
|
In Forgejo: ga naar de **Actions**-tab van je repo. Je ziet de workflow-run starten. Klik erop om de logs live te volgen.
|
||||||
|
|
||||||
|
Op de server parallel meekijken:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl -u act_runner -f
|
||||||
|
# in een tweede shell:
|
||||||
|
docker logs -f server-up
|
||||||
|
```
|
||||||
|
|
||||||
|
Als alles goed gaat: groen vinkje, container draait nieuwe image.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 10 — Rollback
|
||||||
|
|
||||||
|
Omdat images getagd worden met de git SHA is rollback eenvoudig:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/server-up
|
||||||
|
|
||||||
|
# Beschikbare images bekijken
|
||||||
|
docker images server-up --format '{{.Tag}}\t{{.CreatedAt}}'
|
||||||
|
|
||||||
|
# Rollback naar een eerdere SHA — pas aan
|
||||||
|
SU_VERSION=dev-abcdef12 docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Voor extra zekerheid kun je in de workflow de huidige tag wegschrijven vóór de deploy:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "$(docker inspect server-up --format '{{.Config.Image}}')" \
|
||||||
|
> /opt/server-up/.last-good-image
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 11 — Uitbreidingen
|
||||||
|
|
||||||
|
### CI vóór deploy (tests, lint)
|
||||||
|
|
||||||
|
Splits in twee jobs zodat tests in isolatie draaien en de deploy alleen bij groen start:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: docker build --target build -t server-up:test .
|
||||||
|
# voeg je eigen testcommando's toe
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
needs: test
|
||||||
|
runs-on: [self-hosted, dev]
|
||||||
|
steps:
|
||||||
|
# ... zoals hierboven
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nieuwe prod-server toevoegen
|
||||||
|
|
||||||
|
1. Installeer `act_runner` op de nieuwe server (stap 3)
|
||||||
|
2. Maak een nieuw runner-token aan in Forgejo
|
||||||
|
3. Registreer met `--labels self-hosted,prod` (stap 4b)
|
||||||
|
4. Stel de systemd-service in (stap 5)
|
||||||
|
|
||||||
|
De `deploy-prod.yml` workflow pikt de nieuwe runner automatisch op bij de volgende push naar `main` of een tag.
|
||||||
|
|
||||||
|
### Image registry
|
||||||
|
|
||||||
|
Voor grotere setups wil je niet op de productieserver bouwen. Push de image naar de Forgejo Container Registry (ingebouwd onder **Packages**) vanuit een aparte build-job, en trek alleen op de app-server. Scheelt CPU en disk op productie.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Beveiligingstips
|
||||||
|
|
||||||
|
- **Runner draait niet als root** — de `deploy`-user heeft alleen rechten op `/opt/server-up` en is lid van de `docker`-groep. Het Server Up-container zelf draait als root (`user: "0:0"` in compose), dat is een bewuste keuze voor Docker socket-toegang.
|
||||||
|
- **Repo-niveau token** is veiliger dan site-niveau — bij een lek heeft een aanvaller niet meteen toegang tot alle repo's.
|
||||||
|
- **Branch protection op `main`** — Repo → Settings → Branches → Add Rule. Vereis dat pushes via een PR gaan en de dev-pipeline groen is.
|
||||||
|
- **Secrets nooit in compose of git** — zet gevoelige waarden in Forgejo Secrets en schrijf ze in de workflow-step naar `.env`.
|
||||||
|
- **Runner-binary updaten** — periodiek bijwerken: nieuwe versie naar `/usr/local/bin/act_runner` schrijven en `systemctl restart act_runner`. Geen herregistratie nodig.
|
||||||
|
- **Forgejo zelf** — zet 2FA aan, draai achter een reverse proxy met TLS, configureer fail2ban op de SSH-poort.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problemen oplossen
|
||||||
|
|
||||||
|
| Symptoom | Oorzaak / oplossing |
|
||||||
|
|----------|---------------------|
|
||||||
|
| Workflow blijft "queued" hangen | Geen runner met het juiste label online. Check `systemctl status act_runner` en of het label (`dev`/`prod`) overeenkomt met `runs-on` in de workflow. |
|
||||||
|
| `permission denied` bij Docker | `deploy`-user niet in `docker`-groep, of service gestart vóór die toevoeging — `systemctl restart act_runner`. |
|
||||||
|
| `rsync: not found` | `apt install rsync` op de server. |
|
||||||
|
| `SU_VERSION ontbreekt` bij handmatige build | Maak `/opt/server-up/.env` aan: `echo "SU_VERSION=dev-handmatig" > /opt/server-up/.env` |
|
||||||
|
| Container draait oude code na rebuild | Deploy-directory niet bijgewerkt. Controleer: `docker exec --workdir /app server-up grep -n "trim_blocks" core/boilerplates.py`. Als dit `True` toont, trigger de pipeline handmatig of sync de code zelf: `rsync -a --delete --exclude='.git/' --exclude='.forgejo/' ./ /opt/server-up/` |
|
||||||
|
| Boilerplate geeft `yaml: line 5` fout | Zelfde oorzaak als boven — `trim_blocks=True` in de draaiende container. Fix: rebuild na correcte sync. Eerder geïnstalleerde stacks met kapotte compose-bestanden opnieuw installeren via de app-store. |
|
||||||
|
| Healthcheck-step faalt altijd | Check `docker compose logs`. Vaak ontbreekt een env-var of klopt een pad niet. |
|
||||||
|
| TLS-fout bij registreren | Zet `runner.insecure: true` in config alleen tijdelijk voor self-signed certs. Een geldig certificaat (Let's Encrypt) is de structurele oplossing. |
|
||||||
389
docs/synchroniseren.md
Normal file
389
docs/synchroniseren.md
Normal file
|
|
@ -0,0 +1,389 @@
|
||||||
|
# Code synchroniseren via Forgejo
|
||||||
|
|
||||||
|
Dit is hoe je code van je eigen apparaat automatisch op een server krijgt via Forgejo. Je pusht naar een branch, en de server haalt de wijzigingen zelf op en herstart de applicatie. Je hoeft nooit handmatig in te loggen op de server om iets bij te werken.
|
||||||
|
|
||||||
|
Als voorbeeld gebruik ik Server Up, maar de werkwijze is voor elke applicatie hetzelfde.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hoe het werkt
|
||||||
|
|
||||||
|
Je werkt met twee branches in je repository:
|
||||||
|
|
||||||
|
| Branch | Doel | Wat er gebeurt bij een push |
|
||||||
|
|--------|------|-----------------------------|
|
||||||
|
| `dev` | Testen en ontwikkelen | De dev-server wordt automatisch bijgewerkt |
|
||||||
|
| `main` | Stabiele versie voor eindgebruikers | De prod-server wordt automatisch bijgewerkt |
|
||||||
|
|
||||||
|
Jij pusht code naar Forgejo. Forgejo start automatisch een workflow (een reeks stappen). Die workflow draait op de server zelf via een kleine achtergrondservice genaamd `act_runner`. De server haalt de code op, bouwt een nieuw Docker-image en herstart de applicatie.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 1 — Git installeren op je eigen apparaat
|
||||||
|
|
||||||
|
Git heb je nodig om code te beheren en naar Forgejo te pushen.
|
||||||
|
|
||||||
|
Download en installeer Git via [git-scm.com](https://git-scm.com). Tijdens de installatie kun je alle standaardinstellingen accepteren.
|
||||||
|
|
||||||
|
Controleer daarna of het werkt:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git --version
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 2 — Pakketten installeren op de server
|
||||||
|
|
||||||
|
Log in op de server als root of met `sudo`. Installeer de benodigde pakketten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt update
|
||||||
|
apt install -y git rsync nodejs
|
||||||
|
```
|
||||||
|
|
||||||
|
Toelichting:
|
||||||
|
- **git** — de pipeline checkt de repository uit op de server
|
||||||
|
- **rsync** — kopieert de bestanden naar de juiste map op de server
|
||||||
|
- **nodejs** — vereist door `actions/checkout`, de stap die de code ophaalt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 3 — Docker installeren op de server
|
||||||
|
|
||||||
|
Docker is nodig om de applicatie te draaien en te bouwen.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install -y ca-certificates curl gnupg
|
||||||
|
install -m 0755 -d /etc/apt/keyrings
|
||||||
|
curl -fsSL https://download.docker.com/linux/debian/gpg | \
|
||||||
|
gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||||
|
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||||
|
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
||||||
|
https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
|
||||||
|
> /etc/apt/sources.list.d/docker.list
|
||||||
|
|
||||||
|
apt update
|
||||||
|
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
|
systemctl enable --now docker
|
||||||
|
```
|
||||||
|
|
||||||
|
Controleer of Docker werkt:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker --version
|
||||||
|
docker compose version
|
||||||
|
```
|
||||||
|
|
||||||
|
> Draai je Ubuntu in plaats van Debian? Vervang beide keren `debian` door `ubuntu` in bovenstaande commando's.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 4 — Runner-gebruiker aanmaken op de server
|
||||||
|
|
||||||
|
De pipeline draait niet als root maar als een aparte gebruiker. Maak die aan en geef hem toegang tot Docker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
useradd -m -s /bin/bash git-user
|
||||||
|
usermod -aG docker git-user
|
||||||
|
```
|
||||||
|
|
||||||
|
Controleer of het gelukt is:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
groups git-user
|
||||||
|
```
|
||||||
|
|
||||||
|
Je ziet `git-user docker` in de uitvoer.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 5 — Act_runner installeren op de server
|
||||||
|
|
||||||
|
`act_runner` is de achtergrondservice die de Forgejo-workflows uitvoert.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
VERSION=6.2.2
|
||||||
|
ARCH=amd64 # gebruik arm64 voor ARM-servers
|
||||||
|
curl -fsSL -o /usr/local/bin/act_runner \
|
||||||
|
"https://code.forgejo.org/forgejo/runner/releases/download/v${VERSION}/forgejo-runner-${VERSION}-linux-${ARCH}"
|
||||||
|
chmod +x /usr/local/bin/act_runner
|
||||||
|
act_runner --version
|
||||||
|
```
|
||||||
|
|
||||||
|
Maak de benodigde mappen aan:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /etc/act_runner /var/lib/act_runner
|
||||||
|
chown git-user:git-user /var/lib/act_runner
|
||||||
|
act_runner generate-config > /etc/act_runner/config.yaml
|
||||||
|
chown root:git-user /etc/act_runner/config.yaml
|
||||||
|
chmod 640 /etc/act_runner/config.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 6 — Runner registreren in Forgejo
|
||||||
|
|
||||||
|
### Token ophalen
|
||||||
|
|
||||||
|
Ga in Forgejo naar je repository → **Settings → Actions → Runners → Create new Runner**. Kopieer het token.
|
||||||
|
|
||||||
|
### Registreren
|
||||||
|
|
||||||
|
**Voor een dev-server:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u git-user bash -c '
|
||||||
|
cd /var/lib/act_runner && \
|
||||||
|
act_runner register \
|
||||||
|
--no-interactive \
|
||||||
|
--instance https://jouw-forgejo-url \
|
||||||
|
--token JOUW_TOKEN \
|
||||||
|
--name dev-server \
|
||||||
|
--labels self-hosted,dev \
|
||||||
|
--config /etc/act_runner/config.yaml
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Voor een prod-server:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u git-user bash -c '
|
||||||
|
cd /var/lib/act_runner && \
|
||||||
|
act_runner register \
|
||||||
|
--no-interactive \
|
||||||
|
--instance https://jouw-forgejo-url \
|
||||||
|
--token JOUW_TOKEN \
|
||||||
|
--name prod-server \
|
||||||
|
--labels self-hosted,prod \
|
||||||
|
--config /etc/act_runner/config.yaml
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
Controleer in Forgejo onder **Settings → Actions → Runners** — de runner verschijnt als **Idle**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 7 — Runner instellen als achtergrondservice
|
||||||
|
|
||||||
|
Zodat de runner automatisch start bij een herstart van de server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat > /etc/systemd/system/act_runner.service << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Forgejo Actions runner
|
||||||
|
After=network-online.target docker.service
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=git-user
|
||||||
|
Group=git-user
|
||||||
|
WorkingDirectory=/var/lib/act_runner
|
||||||
|
ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now act_runner
|
||||||
|
systemctl status act_runner
|
||||||
|
```
|
||||||
|
|
||||||
|
De runner is nu actief en start automatisch opnieuw na een herstart.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 8 — Deploy-map aanmaken op de server
|
||||||
|
|
||||||
|
De pipeline kopieert de code naar een vaste map. Maak die eenmalig aan:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /opt/docker/server-up
|
||||||
|
chown git-user:git-user /opt/docker/server-up
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 9 — Repository klonen op je eigen apparaat
|
||||||
|
|
||||||
|
Als je de repository nog niet lokaal hebt staan:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://jouw-forgejo-url/gebruiker/server-up.git
|
||||||
|
cd server-up
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stap 10 — Dev-branch aanmaken
|
||||||
|
|
||||||
|
Doe dit één keer. Als de branch al bestaat, sla je deze stap over.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout -b dev
|
||||||
|
git push -u origin dev
|
||||||
|
```
|
||||||
|
|
||||||
|
De pipeline voor de dev-server is nu gekoppeld aan deze branch.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dagelijks gebruik: wijzigingen naar de dev-server sturen
|
||||||
|
|
||||||
|
Dit doe je elke keer als je iets hebt aangepast en wilt testen.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Zorg dat je op de dev-branch zit
|
||||||
|
git checkout dev
|
||||||
|
|
||||||
|
# Voeg je gewijzigde bestanden toe
|
||||||
|
git add .
|
||||||
|
|
||||||
|
# Maak een commit met een korte omschrijving
|
||||||
|
git commit -m "Omschrijving van je wijziging"
|
||||||
|
|
||||||
|
# Push naar Forgejo
|
||||||
|
git push origin dev
|
||||||
|
```
|
||||||
|
|
||||||
|
De pipeline start automatisch. Binnen een paar minuten draait de dev-server de nieuwe versie.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Controleren of de pipeline gelukt is
|
||||||
|
|
||||||
|
Ga in Forgejo naar je repository en klik op **Actions**. Je ziet de pipeline-run staan:
|
||||||
|
|
||||||
|
- **Groen vinkje** — gelukt, de server draait de nieuwe versie
|
||||||
|
- **Rood kruis** — er is iets misgegaan, klik erop om de logs te zien
|
||||||
|
|
||||||
|
Je kunt ook direct op de server controleren:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker inspect --format '{{.State.Health.Status}}' server-up
|
||||||
|
```
|
||||||
|
|
||||||
|
`healthy` betekent dat alles goed draait.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stabiele versie naar de prod-server sturen
|
||||||
|
|
||||||
|
Doe dit alleen als de versie op dev goed werkt.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Schakel over naar main
|
||||||
|
git checkout main
|
||||||
|
|
||||||
|
# Haal de laatste versie van main op
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Voeg alles uit dev samen met main
|
||||||
|
git merge dev
|
||||||
|
|
||||||
|
# Push naar Forgejo
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
De prod-server wordt automatisch bijgewerkt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Een versienummer vastleggen (optioneel)
|
||||||
|
|
||||||
|
Wil je een officieel versienummer aan een release hangen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout main
|
||||||
|
git tag v1.2.3
|
||||||
|
git push origin v1.2.3
|
||||||
|
```
|
||||||
|
|
||||||
|
Het versienummer `v1.2.3` wordt ingebakken in het Docker-image en is zichtbaar in de applicatie.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pipeline handmatig opnieuw starten
|
||||||
|
|
||||||
|
Wil je de pipeline herhalen zonder iets te wijzigen:
|
||||||
|
|
||||||
|
1. Ga naar je repository → **Actions**
|
||||||
|
2. Klik op de workflow die je wilt starten
|
||||||
|
3. Klik rechtsboven op **Run workflow**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Iets terugdraaien
|
||||||
|
|
||||||
|
Elk gebouwd image krijgt een versietag mee. Je kunt altijd terug:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Bekijk beschikbare versies
|
||||||
|
docker images server-up --format '{{.Tag}}\t{{.CreatedAt}}'
|
||||||
|
|
||||||
|
# Start de container met een eerdere versie
|
||||||
|
cd /opt/docker/server-up
|
||||||
|
SU_VERSION=dev-abcdef12 docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Vervang `dev-abcdef12` door de versietag die je terug wilt zetten.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problemen oplossen
|
||||||
|
|
||||||
|
**De pipeline start niet**
|
||||||
|
Ga in Forgejo naar **Settings → Actions → Runners**. Als de runner offline is, log dan in op de server en voer uit:
|
||||||
|
```bash
|
||||||
|
systemctl start act_runner
|
||||||
|
systemctl status act_runner
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fout: `rsync: command not found`**
|
||||||
|
```bash
|
||||||
|
apt install -y rsync
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fout: `Cannot find node in PATH`**
|
||||||
|
```bash
|
||||||
|
apt install -y nodejs
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fout: `permission denied` bij rsync**
|
||||||
|
De runner-gebruiker heeft geen schrijfrechten op de deploy-map:
|
||||||
|
```bash
|
||||||
|
chown -R git-user:git-user /opt/docker/server-up
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fout: `usermod: command not found`**
|
||||||
|
Je bent niet ingelogd als root. Zet `sudo` voor het commando:
|
||||||
|
```bash
|
||||||
|
sudo usermod -aG docker git-user
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fout: `No such image` bij docker tag**
|
||||||
|
Docker Compose bouwt het image als `latest`. De workflow moet `latest` taggen als de versie, niet andersom. Controleer de build-stap in `.forgejo/workflows/deploy.yml` — die moet er zo uitzien:
|
||||||
|
```yaml
|
||||||
|
docker compose build --pull
|
||||||
|
docker tag server-up:latest "server-up:${VERSION}"
|
||||||
|
docker tag server-up:latest "server-up:${CHANNEL}"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Je staat op de verkeerde branch**
|
||||||
|
```bash
|
||||||
|
git branch # toont welke branch actief is
|
||||||
|
git checkout dev # wissel naar dev
|
||||||
|
git checkout main # wissel naar main
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bestanden worden niet meegenomen**
|
||||||
|
```bash
|
||||||
|
git status # toont welke bestanden nog niet zijn toegevoegd
|
||||||
|
git add . # voeg alles toe
|
||||||
|
```
|
||||||
47
fix-config.sh
Normal file
47
fix-config.sh
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Repareer de APP_REPOS in de Server Up config:
|
||||||
|
# - Verwijdert dubbele entries
|
||||||
|
# - Geeft de Forgejo dev-repo een uniek id (bes-r-dev)
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
docker exec server-up python3 -c "
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
p = Path('/data/config.json')
|
||||||
|
cfg = json.loads(p.read_text())
|
||||||
|
|
||||||
|
cfg['APP_REPOS'] = [
|
||||||
|
{
|
||||||
|
'id': 'server-up',
|
||||||
|
'name': 'server-up (GitHub)',
|
||||||
|
'url': 'https://github.com/bes-r/server-up.git',
|
||||||
|
'branch': 'main',
|
||||||
|
'subdir': 'apps',
|
||||||
|
'token': ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'boilerplates',
|
||||||
|
'name': 'Boilerplates (ChristianLempa)',
|
||||||
|
'url': 'https://github.com/ChristianLempa/boilerplates-library.git',
|
||||||
|
'branch': 'main',
|
||||||
|
'subdir': 'compose'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'bes-r-dev',
|
||||||
|
'name': 'bes-r (dev)',
|
||||||
|
'url': 'http://10.0.20.22:3000/bes-r/server-up.git',
|
||||||
|
'branch': 'dev',
|
||||||
|
'token': '',
|
||||||
|
'subdir': 'apps'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
p.write_text(json.dumps(cfg, indent=2))
|
||||||
|
print('Config bijgewerkt.')
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "Container herstarten..."
|
||||||
|
cd /opt/docker/server-up && docker compose restart
|
||||||
|
echo "Klaar. Ga in Server Up naar de app-store en klik op Synchroniseren voor 'bes-r (dev)'."
|
||||||
129
release.ps1
Normal file
129
release.ps1
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
# release.ps1 — Server Up release-script
|
||||||
|
#
|
||||||
|
# Eén commando: stage alles → commit → tag → push (commit + tag) naar Forgejo.
|
||||||
|
# Forgejo Actions pakt de tag en bouwt automatisch het image met de juiste
|
||||||
|
# SU_VERSION (zie .forgejo/workflows/build.yml of server-up-deploy/README.md).
|
||||||
|
#
|
||||||
|
# Gebruik:
|
||||||
|
# .\release.ps1 -Version 0.3.02 -Message "Boilerplates YAML rendering fix"
|
||||||
|
#
|
||||||
|
# Optioneel:
|
||||||
|
# -DryRun Toon alles, voer niets uit
|
||||||
|
# -NoPush Wel taggen, niet pushen
|
||||||
|
# -AllowDirty Sla de "wel echt iets gewijzigd?" check over
|
||||||
|
# -ChangelogTop Plak een ## v$Version blok bovenaan CHANGELOG.md
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)][string]$Version,
|
||||||
|
[Parameter(Mandatory = $true)][string]$Message,
|
||||||
|
[string]$Remote = "origin",
|
||||||
|
[switch]$DryRun,
|
||||||
|
[switch]$NoPush,
|
||||||
|
[switch]$AllowDirty,
|
||||||
|
[switch]$ChangelogTop
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
# ── Sanity checks ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
# Versie formaat (semver met optionele suffix)
|
||||||
|
if ($Version -notmatch '^\d+\.\d+(\.\d+)?([\-_.][\w]+)?$') {
|
||||||
|
throw "Versie moet 'x.y' of 'x.y.z' formaat zijn, kreeg: '$Version'"
|
||||||
|
}
|
||||||
|
|
||||||
|
# In een git repo?
|
||||||
|
$gitRoot = & git rev-parse --show-toplevel 2>$null
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "Niet in een git-repository" }
|
||||||
|
Set-Location $gitRoot
|
||||||
|
Write-Host "Repo: $gitRoot" -ForegroundColor DarkGray
|
||||||
|
|
||||||
|
# Tag bestaat al?
|
||||||
|
$existing = & git tag --list "v$Version"
|
||||||
|
if ($existing) { throw "Tag v$Version bestaat al — kies een ander versienummer of verwijder de tag eerst" }
|
||||||
|
|
||||||
|
# Iets om te committen?
|
||||||
|
$status = & git status --porcelain
|
||||||
|
if (-not $status -and -not $AllowDirty) {
|
||||||
|
Write-Host "Geen wijzigingen om te committen." -ForegroundColor Yellow
|
||||||
|
$reply = Read-Host "Alleen taggen op huidige HEAD? [y/N]"
|
||||||
|
if ($reply -notmatch '^[yY]') { exit 0 }
|
||||||
|
$tagOnly = $true
|
||||||
|
} else {
|
||||||
|
$tagOnly = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Plan tonen ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "═══ Release plan ═══" -ForegroundColor Cyan
|
||||||
|
Write-Host " Versie : v$Version"
|
||||||
|
Write-Host " Bericht: $Message"
|
||||||
|
Write-Host " Remote : $Remote"
|
||||||
|
if ($DryRun) { Write-Host " Mode : DRY RUN — niets wordt uitgevoerd" -ForegroundColor Yellow }
|
||||||
|
if ($tagOnly) { Write-Host " Mode : alleen tag (geen nieuwe commit)" -ForegroundColor Yellow }
|
||||||
|
if ($NoPush) { Write-Host " Push : OVERGESLAGEN" -ForegroundColor Yellow }
|
||||||
|
|
||||||
|
if (-not $tagOnly) {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Gewijzigde bestanden:" -ForegroundColor DarkGray
|
||||||
|
& git status --short
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Optioneel: CHANGELOG bijwerken ────────────────────────────────────────────
|
||||||
|
|
||||||
|
if ($ChangelogTop -and -not $DryRun -and -not $tagOnly) {
|
||||||
|
$clog = Join-Path $gitRoot "CHANGELOG.md"
|
||||||
|
if (Test-Path $clog) {
|
||||||
|
$date = Get-Date -Format "yyyy-MM-dd"
|
||||||
|
$header = "# v$Version — $date`n`n$Message`n`n---`n`n"
|
||||||
|
$original = Get-Content $clog -Raw
|
||||||
|
Set-Content $clog ($header + $original) -NoNewline
|
||||||
|
& git add CHANGELOG.md
|
||||||
|
Write-Host "✓ CHANGELOG.md bijgewerkt" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Uitvoeren ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function Run([string]$Description, [scriptblock]$Action) {
|
||||||
|
Write-Host "→ $Description" -ForegroundColor Cyan
|
||||||
|
if (-not $DryRun) { & $Action }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $tagOnly) {
|
||||||
|
Run "git add -A" { & git add -A }
|
||||||
|
Run "git commit" {
|
||||||
|
# Commit met header "release: vX.Y.Z" + jouw message als body
|
||||||
|
& git commit -m "release: v$Version" -m $Message
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "git commit faalde" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Run "git tag -a v$Version" {
|
||||||
|
& git tag -a "v$Version" -m "v$Version — $Message"
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "git tag faalde" }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $NoPush) {
|
||||||
|
Run "git push $Remote HEAD" {
|
||||||
|
& git push $Remote HEAD
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "git push (commit) faalde" }
|
||||||
|
}
|
||||||
|
Run "git push $Remote v$Version" {
|
||||||
|
& git push $Remote "v$Version"
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "git push (tag) faalde" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Klaar ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "✓ Release v$Version klaar" -ForegroundColor Green
|
||||||
|
if (-not $NoPush -and -not $DryRun) {
|
||||||
|
Write-Host " Forgejo Actions bouwt nu het image (zie repo → Actions)" -ForegroundColor DarkGray
|
||||||
|
Write-Host " Daarna op je server:" -ForegroundColor DarkGray
|
||||||
|
Write-Host " SU_VERSION=$Version in .env" -ForegroundColor DarkGray
|
||||||
|
Write-Host " docker compose pull && docker compose up -d" -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
|
@ -18,7 +18,7 @@ from core.modules import Module, CORE, discover
|
||||||
|
|
||||||
app = Flask(__name__, static_folder="static", template_folder="templates")
|
app = Flask(__name__, static_folder="static", template_folder="templates")
|
||||||
|
|
||||||
VERSION = os.environ.get("SU_VERSION", "0.3.0")
|
VERSION = os.environ.get("SU_VERSION", "0.3.1")
|
||||||
|
|
||||||
MODULES: list[Module] = []
|
MODULES: list[Module] = []
|
||||||
USER_MOD = APP / "modules"
|
USER_MOD = APP / "modules"
|
||||||
|
|
|
||||||
|
|
@ -759,7 +759,7 @@ tailwind.config = {
|
||||||
<script>
|
<script>
|
||||||
function app() {
|
function app() {
|
||||||
return {
|
return {
|
||||||
version: '0.3.0',
|
version: '0.3.1',
|
||||||
page: location.hash.slice(1) || 'dashboard',
|
page: location.hash.slice(1) || 'dashboard',
|
||||||
isMobile: window.innerWidth < 768,
|
isMobile: window.innerWidth < 768,
|
||||||
sidebarOpen: window.innerWidth >= 768 && localStorage.getItem('sidebar') !== 'closed',
|
sidebarOpen: window.innerWidth >= 768 && localStorage.getItem('sidebar') !== 'closed',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue