Covers tech stack, project structure, local development with nix develop and air live reload, environment variables, testing, container build, and deployment pointer to Talos repo manifests. Closes leeworks-agents/gitea-mobile#148 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4.0 KiB
Gitea Mobile
A mobile-first Progressive Web App (PWA) for managing Gitea issues and pull requests across multiple repositories and organizations from an iPhone. Built with Go, HTMX, and hand-rolled CSS -- no JavaScript frameworks, no build step, no node_modules.
Tech Stack
| Layer | Choice |
|---|---|
| Backend | Go + Gitea SDK (code.gitea.io/sdk/gitea) |
| Frontend | HTMX + Go html/template + hand-rolled CSS |
| Container | Multi-stage Dockerfile -> distroless (~15MB) |
| Deployment | Kustomize manifests + FluxCD GitOps |
Project Structure
/
├── cmd/server/main.go # entrypoint
├── internal/
│ ├── config/config.go # env-based configuration
│ ├── gitea/client.go # Gitea SDK wrapper / aggregation layer
│ ├── handlers/ # HTTP handlers (issues, PRs, triage, settings)
│ ├── auth/ # cookie-based token auth
│ ├── middleware/ # auth middleware, logging
│ └── templates/ # Go html/template files (for HTMX)
├── static/ # CSS, JS (htmx.min.js), icons, manifest
├── .gitea/workflows/build.yaml # CI pipeline (Gitea Actions)
├── Dockerfile
├── flake.nix # Nix dev shell with Go + air
└── go.mod
Local Development
Prerequisites
- Nix with flakes enabled, or Go 1.22+
- A Gitea instance with an API token
Quick Start
# Enter the Nix dev shell (provides Go, gopls, air)
nix develop
# Set required environment variables
export GITEA_URL=https://gitea.leeworks.dev
export SESSION_SECRET=$(openssl rand -hex 32)
# Optional: set a default API token
export GITEA_TOKEN=your-gitea-api-token
# Start the server with live reload
air
If you are not using Nix, install Go 1.22+ and air manually, then run the same commands above starting from the export lines.
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
GITEA_URL |
Yes | -- | Base URL of the Gitea instance |
SESSION_SECRET |
Yes | -- | HMAC key for signing session cookies (min 32 chars) |
GITEA_TOKEN |
No | -- | Default API token (users can set their own via the settings page) |
LISTEN_ADDR |
No | :8080 |
Server listen address |
Live Reload with Air
The dev shell includes air for automatic recompilation on file changes. Configuration is in .air.toml. Air watches .go and .html files under cmd/, internal/, and static/ and rebuilds/restarts the server automatically.
Running Tests
# Run all tests
go test ./...
# Run tests with race detection
go test -race ./...
Building the Container
# Build the Docker image
docker build -t gitea-mobile .
# Run locally
docker run -p 8080:8080 \
-e GITEA_URL=https://gitea.leeworks.dev \
-e SESSION_SECRET=$(openssl rand -hex 32) \
gitea-mobile
The Dockerfile uses a multi-stage build: Go binary compiled in an Alpine builder stage, then copied into a distroless image (~15MB final size).
Deployment
Kubernetes manifests for this app live in the Talos cluster repo under testing1/first-cluster/apps/gitea-mobile/. FluxCD syncs from that repo and handles automated image updates via ImagePolicy annotations.
Key deployment resources:
deployment.yaml-- Pod spec with health checksservice.yaml-- ClusterIP service on port 8080ingressroute.yaml-- Traefik IngressRoute forgitea-mobile.testing.leeworks.devkustomization.yaml-- Kustomize overlay
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Make your changes and add tests
- Run
go test -race ./...to verify - Commit with a clear message referencing the issue number
- Push to your fork and open a pull request
All PRs target the fork (leeworks-agents/gitea-mobile), not the upstream repo.