New webapp script following the two-file convention (ct/ + install/, sourcing the shared libs).
What it does
Creates an unprivileged Debian 12 LXC that serves a Next.js site and redeploys itself on every push, using a self-hosted Gitea Actions runner in host mode (deploy-as-code) instead of a webhook.
ct/webapp.sh — host side: creates the LXC (4 GB RAM, 30 GB disk), prompts for the Gitea instance URL, a runner registration token and the NEXT_PUBLIC_* values, pushes them into the container and bootstraps the installer. All env-overridable for non-interactive use.
install/webapp-install.sh — in-container: installs Node.js (NodeSource) + git/rsync/sudo, downloads & registers act_runner (host mode, runs as the unprivileged webapp user, polls Gitea outbound — no inbound port), writes /etc/webapp/env, and sets up two systemd units (webapp.service for next start, webapp-runner.service for the runner). A narrow sudoers rule lets the runner restart onlywebapp.service.
README.md — adds the webapp row to the scripts table.
The build/deploy logic itself lives in the website repo's .gitea/workflows/deploy.yml (separate PR in l.kirchner/Redesign-ad2b).
Design notes
No read token and no inbound port: the runner authenticates outbound; actions/checkout uses the per-job token.
Runner and service share the webapp user, so the workflow syncs into the live copy without privileges; only systemctl restart webapp.service is sudo-allowed.
NEXT_PUBLIC_* stay in /etc/webapp/env (sourced at build time) so the repo carries no environment-specific config.
act_runner pinned to 0.2.13, overridable via RUNNER_VERSION.
Validation
shellcheck clean (only the same SC2034/SC1090 as devpi.sh, from the curl-sourced libs), bash -n passes, sudoers format checked, workflow YAML parses.
Prerequisites (deploy time)
Actions enabled on the instance and the repo; a runner registration token; outbound HTTPS to the Gitea instance and to github.com (for actions/checkout).
New `webapp` script following the two-file convention (`ct/` + `install/`, sourcing the shared libs).
## What it does
Creates an unprivileged Debian 12 LXC that serves a Next.js site and redeploys itself on every push, using a self-hosted **Gitea Actions runner in host mode** (deploy-as-code) instead of a webhook.
- `ct/webapp.sh` — host side: creates the LXC (4 GB RAM, 30 GB disk), prompts for the Gitea instance URL, a **runner registration token** and the `NEXT_PUBLIC_*` values, pushes them into the container and bootstraps the installer. All env-overridable for non-interactive use.
- `install/webapp-install.sh` — in-container: installs Node.js (NodeSource) + `git`/`rsync`/`sudo`, downloads & registers `act_runner` (host mode, runs as the unprivileged `webapp` user, polls Gitea outbound — no inbound port), writes `/etc/webapp/env`, and sets up two systemd units (`webapp.service` for `next start`, `webapp-runner.service` for the runner). A narrow sudoers rule lets the runner restart **only** `webapp.service`.
- `README.md` — adds the `webapp` row to the scripts table.
The build/deploy logic itself lives in the website repo's `.gitea/workflows/deploy.yml` (separate PR in `l.kirchner/Redesign-ad2b`).
## Design notes
- No read token and no inbound port: the runner authenticates outbound; `actions/checkout` uses the per-job token.
- Runner and service share the `webapp` user, so the workflow syncs into the live copy without privileges; only `systemctl restart webapp.service` is sudo-allowed.
- `NEXT_PUBLIC_*` stay in `/etc/webapp/env` (sourced at build time) so the repo carries no environment-specific config.
- `act_runner` pinned to 0.2.13, overridable via `RUNNER_VERSION`.
## Validation
`shellcheck` clean (only the same `SC2034`/`SC1090` as `devpi.sh`, from the curl-sourced libs), `bash -n` passes, sudoers format checked, workflow YAML parses.
## Prerequisites (deploy time)
Actions enabled on the instance and the repo; a runner registration token; outbound HTTPS to the Gitea instance and to github.com (for `actions/checkout`).
Host-side script that creates an unprivileged Debian 12 LXC, installs
Node.js + act_runner in host mode, and registers it against the Gitea
instance. Deploy logic lives in the repo's .gitea/workflows/deploy.yml
(deploy-as-code); the runner polls outbound, so no inbound port.
Installs Node.js and act_runner in host mode, registers the runner as
the unprivileged webapp user, and wires up systemd units for the runner
and the next-start service. A narrow sudoers rule lets the runner restart
only webapp.service; the build/deploy itself is driven by the repo workflow.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
New
webappscript following the two-file convention (ct/+install/, sourcing the shared libs).What it does
Creates an unprivileged Debian 12 LXC that serves a Next.js site and redeploys itself on every push, using a self-hosted Gitea Actions runner in host mode (deploy-as-code) instead of a webhook.
ct/webapp.sh— host side: creates the LXC (4 GB RAM, 30 GB disk), prompts for the Gitea instance URL, a runner registration token and theNEXT_PUBLIC_*values, pushes them into the container and bootstraps the installer. All env-overridable for non-interactive use.install/webapp-install.sh— in-container: installs Node.js (NodeSource) +git/rsync/sudo, downloads & registersact_runner(host mode, runs as the unprivilegedwebappuser, polls Gitea outbound — no inbound port), writes/etc/webapp/env, and sets up two systemd units (webapp.servicefornext start,webapp-runner.servicefor the runner). A narrow sudoers rule lets the runner restart onlywebapp.service.README.md— adds thewebapprow to the scripts table.The build/deploy logic itself lives in the website repo's
.gitea/workflows/deploy.yml(separate PR inl.kirchner/Redesign-ad2b).Design notes
actions/checkoutuses the per-job token.webappuser, so the workflow syncs into the live copy without privileges; onlysystemctl restart webapp.serviceis sudo-allowed.NEXT_PUBLIC_*stay in/etc/webapp/env(sourced at build time) so the repo carries no environment-specific config.act_runnerpinned to 0.2.13, overridable viaRUNNER_VERSION.Validation
shellcheckclean (only the sameSC2034/SC1090asdevpi.sh, from the curl-sourced libs),bash -npasses, sudoers format checked, workflow YAML parses.Prerequisites (deploy time)
Actions enabled on the instance and the repo; a runner registration token; outbound HTTPS to the Gitea instance and to github.com (for
actions/checkout).