| Age | Commit message (Collapse) | Author |
|
|
|
|
|
Prevents NFS-lock races during rolling updates. The hostPath PVs point at
an NFS-shared directory mounted on every r-node, so RWO is not actually
enforced across nodes — under the default RollingUpdate strategy the new
pod can start on a different node and grab the same data dir while the
old pod still holds file locks, producing errors like postgres'
"could not write to file postmaster.pid: Unknown error 512".
Applied to: immich-postgres, audiobookshelf, anki-sync-server, registry,
pkgrepo, player, wallabag, miniflux-postgres, opodsync, radicale,
kobo-sync-server, keybr, filebrowser, git-server, goprecords, jellyfin.
(syncthing and navidrome already had it.)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
|
OpenSSH refuses to load host keys from NFS for security reasons.
The solution is to store keys in persistent NFS (so they survive
restarts) but copy them to a local emptyDir at startup (so sshd
can read them).
This ensures:
- SSH host keys persist across pod restarts
- sshd can successfully load the keys from local storage
- Clients don't see "host key changed" warnings
Co-authored-by: Cursor <cursoragent@cursor.com>
|
|
The sshd_config file needs to be in the persistent SSH directory
for the git-server container to start properly. Added ConfigMap
and updated initContainer to copy it on first deployment.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
|
SSH host keys are now stored in persistent NFS storage instead of
ephemeral emptyDir. Keys are only generated once on first deployment,
preventing known_hosts updates on every pod restart.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
|
Add *.f3s.lan.buetow.org ingress resources for all services to enable
LAN access with TLS termination. This allows direct access from the
192.168.1.0/24 network through the FreeBSD CARP/relayd setup.
Services updated:
- argocd: argocd.f3s.lan.buetow.org
- cgit: cgit.f3s.lan.buetow.org
- grafana: grafana.f3s.lan.buetow.org
- anki-sync-server: anki.f3s.lan.buetow.org
- apache: f3s.lan.buetow.org, www.f3s.lan.buetow.org, standby.f3s.lan.buetow.org
- audiobookshelf: audiobookshelf.f3s.lan.buetow.org
- filebrowser: filebrowser.f3s.lan.buetow.org
- immich: immich.f3s.lan.buetow.org
- ipv6test: ipv6test.f3s.lan.buetow.org (+ ipv4/ipv6 subdomains)
- keybr: keybr.f3s.lan.buetow.org
- koreader-sync-server: koreader.f3s.lan.buetow.org
- miniflux: flux.f3s.lan.buetow.org
- opodsync: gpodder.f3s.lan.buetow.org
- radicale: radicale.f3s.lan.buetow.org
- syncthing: syncthing.f3s.lan.buetow.org
- tracing-demo: tracing-demo.f3s.lan.buetow.org
- wallabag: bag.f3s.lan.buetow.org
- webdav: webdav.f3s.lan.buetow.org
All LAN ingresses use:
- TLS with f3s-lan-tls certificate (cert-manager)
- Traefik entrypoints: web,websecure
- Same backend services as external ingresses
Also fixed koreader-sync-server ingress to use modern annotations.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
|
Changes:
- Mount PVC with subPath: repos in deployment
- Update cgit scan-path from /repos/repos to /repos
- Update git-http-backend GIT_PROJECT_ROOT to /repos
- Update all documentation to reflect simplified paths
This eliminates the redundant /repos/repos duplication and simplifies
all git URLs to ssh://git@r0:30022/repos/<repo>.git format.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
ArgoCD was experiencing 'early EOF' errors during git fetch operations.
Added fastcgi timeout settings to prevent connection closures:
- fastcgi_read_timeout: 300s (5 minutes)
- fastcgi_send_timeout: 300s (5 minutes)
- fastcgi_buffering: off (stream responses immediately)
This fixes: curl 18 transfer closed with outstanding read data remaining
|
|
Non-root container cannot write to /.gitconfig, setting HOME=/tmp
allows git to write config files
|
|
Fixes 'dubious ownership' error when git-http-backend runs as UID 33
accessing repository owned by UID 1001:33
|
|
git-http-backend is in the git-daemon package in Alpine, not the base git package
|
|
- New initContainer installs git and copies git-http-backend to shared /tmp volume
- Updated nginx config to use /tmp/git-http-backend
- Removed apk add from cgit container (was failing due to non-root user)
|
|
|
|
- Make /repos mount read-write on cgit container
- Set http.receivepack=true and http.uploadpack=true in git config
- Allows git clone/fetch/push via HTTP
- Fixes 403 Forbidden error from git-http-backend
|
|
- Copy /etc/nginx/fastcgi_params to /tmp/fastcgi_params
- Update include path to /tmp/fastcgi_params
- Fixes 'No such file or directory' error
|
|
- Use sed to insert git-http-backend location into default.conf
- Location must be inside server block, not separate file
- Fixes nginx config syntax error
|
|
|
|
- Install git package in cgit container
- Add nginx config for git-http-backend via fcgiwrap
- Supports git clone/fetch/pull over HTTP at /conf.git/ path
- cgit remains for web UI at /conf/ path
- Eliminates need for SSH and SSH agent sidecar
|
|
- Generate SSH host keys in initContainer with correct ownership
- Remove deprecated UsePrivilegeSeparation from sshd_config
- Fix NFS repository permissions (UID 1001, GID 33)
- Configure git shared repository mode
|
|
cgit doesn't need privilege escalation capabilities when running
as UID 33 with writable /tmp for runtime files.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
The fcgiwrap socket path is configured in /etc/nginx/conf.d/default.conf,
not cgit.conf. Copy conf.d directory to /tmp and update socket path there.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
- Mount emptyDir volume at /tmp for cgit runtime files
- Copy nginx.conf to /tmp and modify there (read-only /etc)
- Move nginx PID file to /tmp/nginx.pid
- Move fcgiwrap socket to /tmp/fcgiwrap.sock
- Update cgit.conf to use new socket location
Allows cgit to run as non-root (UID 33) without write access to /etc or /var.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
Changes:
- Set fsGroup: 33 at pod level for proper NFS group access
- Updated git user to UID 1001, GID 33 (www-data) to match NFS ownership
- Run git-server container as UID 1001:33 (non-root)
- Run cgit container as UID 33:33 (non-root)
- Disabled SSH privilege separation (UsePrivilegeSeparation no)
- Removed unnecessary capabilities (SETGID, SETUID, SYS_CHROOT)
This follows the same pattern as filebrowser and webdav services,
using security contexts instead of chown operations on NFS.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
Added virtual-root=/ to cgitrc to prevent duplicate path segments
in generated URLs. This fixes the "Invalid request" error when
clicking links in the cgit web interface.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
Repository is at /repos/repos/conf.git, so scan-path should be /repos/repos
to generate correct URLs in the web interface.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
SELinux prevents root from accessing 700 directories in some contexts.
Use 755 for directory and 644 for authorized_keys to allow access.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
The emptyDir needs to be writable for SSH to access authorized_keys.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
Remove extra .ssh directory creation in initContainer.
The emptyDir mount point itself is /home/git/.ssh.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
Copy authorized_keys from secret to emptyDir with git user ownership.
This allows SSH to read the keys for authentication.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
SSH privilege separation requires setgroups() and setuid() syscalls.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
- Enable SYS_CHROOT capability for git-server SSH to work in containers
- Configure ArgoCD repo-server to use SSH key for git-server access
- Set DEBUG3 logging in sshd for troubleshooting (temp)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
|
Nginx workers (running as user nginx) couldn't connect to fcgiwrap.sock
created by root. Add chmod 666 to make the socket world-accessible.
|
|
The cgit nginx default.conf listens on port 80, not 8080.
Update:
- Container port from 8080 to 80
- Service targetPort from 8080 to 80
|
|
Nginx workers need these capabilities to drop privileges.
Add SETGID and SETUID to allow nginx workers to start properly.
|
|
The fsGroup: 1000 was causing nginx workers to fail with setgid errors
even after removing 'user nginx;' directive. Since both containers run
as root, fsGroup is not needed for repo access.
|
|
When running as root with fsGroup, nginx workers fail trying to setgid.
Remove the 'user nginx;' directive from nginx.conf at startup using sed.
This allows nginx to run workers as root without permission errors.
|
|
Remove -u nginx -g nginx from spawn-fcgi command to run as root.
This avoids nginx worker process setgid permission errors.
|
|
The cgit image entrypoint always tries to chown /var/cache/cgit which
fails with permission errors. Override the entrypoint to directly:
1. Spawn fcgiwrap as nginx user
2. Start nginx in foreground
This skips the problematic chown/chmod and template substitution.
|
|
Instead of fighting permission issues with the cgit cache directory,
disable caching entirely by:
- Setting cache-size=0 in cgitrc
- Removing cgit-cache emptyDir volume and mounts
- Simplifying initContainer (only SSH keys setup needed)
cgit will work without caching, just slightly slower for large repos.
|
|
cgit image needs root to:
- Bind sockets with spawn-fcgi
- Run nginx master process
- Write to /var/run/nginx.pid
The initContainer already sets up cache dir with proper permissions.
|
|
The cgit entrypoint tries to write to /etc/cgitrc which is mounted
read-only from our ConfigMap. Set USE_CUSTOM_CONFIG=true to use our
custom cgitrc directly without template substitution.
|
|
The cgit image runs as nginx user (UID 101), not www-data (UID 33).
- Update initContainer to chown cache to 101:1000
- Update cgit securityContext to runAsUser: 101
|
|
Follow webdav/filebrowser pattern for proper permission handling:
- Add fsGroup: 1000 at pod level for git repo access
- Add initContainer to chown emptyDir volumes
- Run git-server as root (required for sshd)
- Run cgit as user 33 (www-data)
- Restore cgit-cache emptyDir volume with proper ownership
|
|
- Mount emptyDir for /etc/ssh to allow SSH host key generation
- Mount emptyDir for /var/cache/cgit to allow cache initialization
- Run both containers as root with proper capabilities
- Copy sshd_config at runtime from /tmp to /etc/ssh
- Add imagePullPolicy: Always to force image refresh
|
|
- Generate SSH host keys at runtime via entrypoint script
- Remove fsGroup security context to fix emptyDir permissions
- Allow cgit to initialize cache directory as root
|
|
- Remove unsupported UsePAM option from sshd_config
- Run cgit as root to allow cache directory initialization
- Add CHOWN and DAC_OVERRIDE capabilities for cgit
|
|
- Use registry.lan.buetow.org for deployment (internal DNS)
- Add emptyDir volume for cgit cache directory
- Add README.md with deployment and secret management instructions
This fixes image pull issues and cgit permission errors.
|
|
Deploy a self-hosted git repository solution to replace external Codeberg dependency.
Components:
- SSH git server: Alpine-based container with OpenSSH and git
- cgit web UI: Browse repositories at cgit.f3s.buetow.org
- Single pod design: git-server + cgit containers sharing storage
Infrastructure:
- Docker image in git-server/docker-image/ with Justfile build automation
- Helm chart in git-server/helm-chart/ for Kubernetes deployment
- 5Gi ReadWriteMany PVC for NFS-backed repository storage
- ClusterIP service for ArgoCD internal access
- NodePort 30022 for external SSH push access
- Traefik ingress for cgit web UI
ArgoCD Application manifest deployed to cicd namespace.
Note: SSH keys must be created as Kubernetes secrets manually, not in git.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|