- Python 33.9%
- CSS 33.2%
- HTML 24.8%
- Dockerfile 8.1%
|
All checks were successful
Deploy / deploy (push) Successful in 5s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| static | ||
| templates | ||
| .dockerignore | ||
| .gitignore | ||
| app.py | ||
| Caddyfile.example | ||
| compose.yaml | ||
| Dockerfile | ||
| hashpw.py | ||
| LICENSE | ||
| README.md | ||
| requirements.txt | ||
| services.yaml | ||
hrones-net
Homepage of the hrones net — a small Flask app that lists links to services. Public services are always visible; private ones (Jellyfin, etc.) appear only after logging in.
The app listens on 127.0.0.1:8010; put Caddy in front of it for TLS (see
Caddyfile.example). If PASSWORD_HASH is empty, login is
disabled and only public services show.
Continuous deployment
.forgejo/workflows/deploy.yml re-deploys on
every push to main: a self-hosted Forgejo runner on the Pi fetches the new
commit and runs docker compose up -d --build. One-time setup on the Pi:
-
Clone to the deploy directory CI keeps in sync. The runner must be able to
git fetchit non-interactively, so embed a read-scoped Forgejo access token (User Settings → Applications → Generate Token) in the remote — or use the plain URL if the repo is public:mkdir -p ~/docker && git clone \ https://matt:<TOKEN>@git.hrones.net/matt/hrones-net.git ~/docker/hrones-net -
Let the runner deploy. Its user must be in the
dockergroup and able to write~/docker/hrones-net; Docker + the compose plugin must be installed. -
Add the app secrets in Forgejo → repo → Settings → Actions → Secrets:
SECRET_KEY—openssl rand -hex 32PASSWORD_HASH— build once and run the helper, then paste the output:cd ~/docker/hrones-net && docker compose build docker compose run --rm web python hashpw.py
-
Point the workflow at your runner.
runs-onis alreadyhostandDEPLOY_DIRis/home/matt/docker/hrones-netindeploy.yml— adjust if yours differ. Push tomainto trigger a deploy. -
Front it with Caddy (Caddyfile.example) for TLS.
The push that first adds this workflow runs it immediately — it will fail until steps 1–3 are done. That's expected.
Run manually
Without CI, on the Pi (secrets via the shell — never an .env file, since the
$ in a pbkdf2 hash gets mangled by env-file parsing):
export SECRET_KEY="$(openssl rand -hex 32)"
export PASSWORD_HASH='pbkdf2:sha256:...' # from `python hashpw.py`
docker compose up -d
Develop (local)
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python hashpw.py # prints a PASSWORD_HASH value
export PASSWORD_HASH='pbkdf2:sha256:...'
python app.py # http://localhost:5050
Adding services
Edit services.yaml. Entries under public: are always
visible; entries under private: require login. Each entry takes name,
url, and optional description and icon (emoji). Changes are picked up
on the next page load — no restart needed.