This commit is contained in:
pavel 2026-05-14 20:22:35 +02:00
commit 79b3c8d693
5 changed files with 6 additions and 30 deletions

View file

@ -9,7 +9,6 @@ AUTH_HEADER_EMAIL=X-authentik-email
FORGEJO_BASE_URL= FORGEJO_BASE_URL=
FORGEJO_TOKEN= FORGEJO_TOKEN=
FORGEJO_ORG= FORGEJO_ORG=
PROJECTS_ROOT=$HOME/projects/$app
CADDY_ROUTE_ENABLED=false CADDY_ROUTE_ENABLED=false
CADDY_ADMIN_URL=http://localhost:2019 CADDY_ADMIN_URL=http://localhost:2019
CADDY_SERVER_ID=srv0 CADDY_SERVER_ID=srv0

View file

@ -38,10 +38,6 @@ Important:
- `X-authentik-email` - `X-authentik-email`
- `FORGEJO_BASE_URL` + `FORGEJO_TOKEN` enable repository creation. - `FORGEJO_BASE_URL` + `FORGEJO_TOKEN` enable repository creation.
- `FORGEJO_ORG` switches creation from personal repos to org repos. - `FORGEJO_ORG` switches creation from personal repos to org repos.
- `PROJECTS_ROOT` supports templates:
- `$HOME` = workspace unix user home
- `$app` = project slug
- Example: `$HOME/projects/$app`
- `UNIX_SOCKET_PATH` enables unix socket listener in addition to `LISTEN_ADDR`. - `UNIX_SOCKET_PATH` enables unix socket listener in addition to `LISTEN_ADDR`.
- `CADDY_ROUTE_ENABLED=true` enables route provisioning. - `CADDY_ROUTE_ENABLED=true` enables route provisioning.
- `CADDY_ADMIN_URL` points to the Caddy Admin API (default `http://localhost:2019`). - `CADDY_ADMIN_URL` points to the Caddy Admin API (default `http://localhost:2019`).
@ -83,9 +79,9 @@ Route shape:
- If auto-provisioning cannot apply (for example external non-Forgejo repo), configure a webhook manually to call `webhook_url`. - If auto-provisioning cannot apply (for example external non-Forgejo repo), configure a webhook manually to call `webhook_url`.
- Deploy runs only when payload `ref` equals `refs/heads/main`. - Deploy runs only when payload `ref` equals `refs/heads/main`.
- Deploy behavior: - Deploy behavior:
1. Clone repo to `<PROJECTS_ROOT>/repo` if missing. 1. Clone repo to `~/projects/<app>/repo` if missing.
2. Otherwise `fetch origin main` and `reset --hard origin/main`. 2. Otherwise `fetch origin main` and `reset --hard origin/main`.
3. Build binary to `<PROJECTS_ROOT>/bin/app`. 3. Build binary to `~/projects/<app>/bin/app`.
4. Restart the project user service via `systemctl --user restart`. 4. Restart the project user service via `systemctl --user restart`.
Notes: Notes:
@ -105,8 +101,8 @@ Notes:
## Systemd ## Systemd
For each project in workspace `<ws>` owned by unix user `<unix_user>`, the app writes: For each project in workspace `<ws>` owned by unix user `<unix_user>`, the app writes:
- env file: `<PROJECTS_ROOT>/.env` - env file: `<unix-user-home>/projects/<app>/.env`
- binary path used by systemd: `<PROJECTS_ROOT>/bin/app` - binary path used by systemd: `<unix-user-home>/projects/<app>/bin/app`
- unit file: `<home-of-unix-user>/.config/systemd/user/projectmgr-<app-user>-<project>.service` - unit file: `<home-of-unix-user>/.config/systemd/user/projectmgr-<app-user>-<project>.service`
Then it attempts as that unix user: Then it attempts as that unix user:
@ -115,6 +111,6 @@ Then it attempts as that unix user:
The generated `.env` is synced from the project env-var configuration and always includes: The generated `.env` is synced from the project env-var configuration and always includes:
- `LISTEN_NETWORK=unix` - `LISTEN_NETWORK=unix`
- `LISTEN_ADDRESS=<PROJECTS_ROOT>/app.sock` - `LISTEN_ADDRESS=<unix-user-home>/projects/<app>/app.sock`
If user systemd is not available in the runtime environment, project creation still succeeds and unit files are still generated. If user systemd is not available in the runtime environment, project creation still succeeds and unit files are still generated.

View file

@ -8,7 +8,6 @@ import (
) )
func loadConfig() (Config, error) { func loadConfig() (Config, error) {
projectRoot := strings.TrimSpace(getenv("PROJECTS_ROOT", "$HOME/projects/$app"))
cfg := Config{ cfg := Config{
DatabaseURL: getenv("DATABASE_URL", "postgres://postgres:postgres@localhost:5432/box?sslmode=disable"), DatabaseURL: getenv("DATABASE_URL", "postgres://postgres:postgres@localhost:5432/box?sslmode=disable"),
ListenAddr: getenv("LISTEN_ADDR", ":8080"), ListenAddr: getenv("LISTEN_ADDR", ":8080"),
@ -21,7 +20,6 @@ func loadConfig() (Config, error) {
ForgejoBaseURL: strings.TrimRight(getenv("FORGEJO_BASE_URL", ""), "/"), ForgejoBaseURL: strings.TrimRight(getenv("FORGEJO_BASE_URL", ""), "/"),
ForgejoToken: getenv("FORGEJO_TOKEN", ""), ForgejoToken: getenv("FORGEJO_TOKEN", ""),
ForgejoOrg: getenv("FORGEJO_ORG", ""), ForgejoOrg: getenv("FORGEJO_ORG", ""),
ProjectRoot: projectRoot,
CaddyAdminURL: strings.TrimRight(getenv("CADDY_ADMIN_URL", "http://localhost:2019"), "/"), CaddyAdminURL: strings.TrimRight(getenv("CADDY_ADMIN_URL", "http://localhost:2019"), "/"),
CaddyServerID: getenv("CADDY_SERVER_ID", "srv0"), CaddyServerID: getenv("CADDY_SERVER_ID", "srv0"),
CaddyDomainSuffix: getenv("CADDY_DOMAIN_SUFFIX", ""), CaddyDomainSuffix: getenv("CADDY_DOMAIN_SUFFIX", ""),

View file

@ -2,7 +2,6 @@ package app
import ( import (
"path/filepath" "path/filepath"
"strings"
) )
func (a *App) projectDirFor(p Project) (string, error) { func (a *App) projectDirFor(p Project) (string, error) {
@ -10,20 +9,5 @@ func (a *App) projectDirFor(p Project) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
tpl := strings.TrimSpace(a.cfg.ProjectRoot) return filepath.Clean(filepath.Join(homeDir, "projects", p.Slug)), nil
if tpl == "" {
tpl = "$HOME/projects/$app"
}
path := tpl
path = strings.ReplaceAll(path, "${HOME}", homeDir)
path = strings.ReplaceAll(path, "$HOME", homeDir)
path = strings.ReplaceAll(path, "${app}", p.Slug)
path = strings.ReplaceAll(path, "$app", p.Slug)
if strings.HasPrefix(path, "~/") {
path = filepath.Join(homeDir, strings.TrimPrefix(path, "~/"))
}
if !filepath.IsAbs(path) {
path = filepath.Join(homeDir, path)
}
return filepath.Clean(path), nil
} }

View file

@ -17,7 +17,6 @@ type Config struct {
ForgejoBaseURL string ForgejoBaseURL string
ForgejoToken string ForgejoToken string
ForgejoOrg string ForgejoOrg string
ProjectRoot string
CaddyAdminURL string CaddyAdminURL string
CaddyServerID string CaddyServerID string
CaddyDomainSuffix string CaddyDomainSuffix string