Skip to content

feat: add Gitea Docker registry deployment with user provisioning (#142)#149

Open
t0kubetsu wants to merge 3 commits into
mainfrom
feature/gitea-registry-bootstrap
Open

feat: add Gitea Docker registry deployment with user provisioning (#142)#149
t0kubetsu wants to merge 3 commits into
mainfrom
feature/gitea-registry-bootstrap

Conversation

@t0kubetsu
Copy link
Copy Markdown

Summary

Closes #142

  • Deploy a standalone Gitea instance configured as an OCI Docker/Container registry with the Packages feature enabled (GITEA__packages__ENABLED=true)
  • Automated user provisioning via a provisioner sidecar (admin + regular users, SSH keys via REST API)
  • Personal access token generation (registry-token) for every provisioned user, written to a named volume at /tokens/tokens.txt and retrievable via make tokens

Changes

  • Dockerfile — two-stage build: golang:alpine builder installs yq + jq; gitea/gitea:latest runtime copies tools and provisioning scripts; ENTRYPOINT is /provisioning/init.sh
  • compose.yml — three services: db (postgres:16-alpine), gitea (gitea/gitea:latest with GITEA__packages__ENABLED=true), provisioner (build: .); adds gitea-registry-tokens:/tokens volume for token output
  • provisioning/init.sh — POSIX sh script: waits up to 180 s for Gitea health, idempotency stamp guard, creates admin/regular users via gitea CLI, injects SSH keys via REST API, generates registry tokens via REST API and writes to /tokens/tokens.txt
  • provisioning/users.yml — declarative user manifest (admins[] + users[] with username, email, password, ssh_keys[])
  • config/app.ini — reference-only app.ini (NOT mounted; settings applied via env vars)
  • .env.example — template for all required env vars with placeholder values
  • Makefile — mirrors #141 reference pattern; adds tokens target (docker exec gitea-registry-provisioner cat /tokens/tokens.txt)
  • .dockerignore — excludes .env, key/cert files, README from build context
  • README.md — Quick Start, Makefile targets, user declaration, SSH key format, Docker registry usage (login/push/pull), token retrieval, env vars table, troubleshooting

Design Notes

  • Base images: golang:alpine (builder) and gitea/gitea:latest (runtime) — matches the official Gitea Dockerfile pattern and the #141 reference implementation exactly
  • Packages / OCI registry: enabled exclusively via GITEA__packages__ENABLED=true env var; no app.ini mount required
  • Token storage: uses a dedicated named volume gitea-registry-tokens so tokens persist after the provisioner container exits and are accessible via make tokens
  • Idempotency: stamp file at /data/gitea/.provisioned prevents double-provisioning on stack restart
  • JSON safety: all REST API payloads built with jq -n to prevent injection via crafted SSH key strings or usernames

Testing

  • make build-up completes without error
  • Gitea UI accessible at http://localhost:3000
  • make tokens outputs a username:sha1token line for each user
  • docker login localhost:3000 -u trainee01 -p TOKEN succeeds
  • docker push localhost:3000/trainee01/myimage:latest succeeds
  • make reprovision exits immediately (idempotency guard)
  • make down && make up does not re-create users (stamp still present)

Related Issues

t0kubetsu added 2 commits May 11, 2026 15:42
Deploy a standalone Gitea instance configured as an OCI Docker registry,
with automated user/SSH-key provisioning and personal access token generation
for docker login. Two-stage build (golang:alpine builder, gitea/gitea:latest
runtime) matches the #141 reference pattern.
…149)

- Fix make tokens: use docker run against named volume (docker exec fails on stopped container)
- Fix term-debug-build: guard against missing debug service
- Fix yq: explicitly install mikefarah/yq v4.44.1 via wget
- Fix SSH port: SSH_LISTEN_PORT=22 + SSH_PORT advertises correct host-mapped port
- Fix silent CLI errors: capture stderr, distinguish already-exists from real failures
- Fix make clean: scope to project containers only (no system-wide prune)
- Require POSTGRES_PASSWORD to be set explicitly (no weak default)
@t0kubetsu
Copy link
Copy Markdown
Author

t0kubetsu commented May 11, 2026

Code review — fixes applied

Fix commit: 5a0f085

Critical fixes applied

Finding Fix
make tokens used docker exec on a stopped container Replaced with docker run --rm -v gitea-registry-tokens:/tokens alpine cat /tokens/tokens.txt
term-debug-build referenced commented-out debug service Now prints a clear instruction to uncomment the service first
apk add yq installs kislyuk/yq (Python) on some Alpine versions Replaced with explicit wget of mikefarah/yq v4.44.1
SSH clone URLs advertised port 22 while host exposes 2222 Split into SSH_LISTEN_PORT=22 (container) + SSH_PORT=${SSH_PORT:-2222} (advertised)
2>/dev/null silently hid all gitea admin user create errors Stderr captured; already exists → warn+skip, any other error → fail+exit
make clean ran docker system prune -a system-wide Replaced with docker compose down -v --rmi all
POSTGRES_PASSWORD had weak gitea default fallback Changed to :? syntax — Compose fails loudly if unset

Open medium/low items (not blocking merge for a lab environment)

  • Unpinned gitea/gitea:latest tag — pin to a semver when you need reproducibility
  • users.yml placeholder SSH keys fail silently with a misleading "may already exist" message — consider improving the warning
  • start_period missing from PostgreSQL healthcheck (add start_period: 20s to avoid false-unhealthy on cold pull)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Deploy a standalone Gitea instance as a Docker registry (with UI)

1 participant