feat: add Gitea CI workflow and production Containerfile
Some checks failed
ci / test (push) Failing after 18s
ci / build (push) Has been skipped

Bake source into the image (COPY src/) so production containers
run without volume mounts. CI pipeline runs ruff + pytest then
builds and pushes harbor.mymx.me/s5p/s5p:latest on push to main.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-21 17:18:14 +01:00
parent fa3621806d
commit 8c99544e34
8 changed files with 71 additions and 7 deletions

9
.containerignore Normal file
View File

@@ -0,0 +1,9 @@
.venv/
.git/
tests/
docs/
*.prof
*.egg-info/
__pycache__/
.gitea/
.pytest_cache/

31
.gitea/workflows/ci.yaml Normal file
View File

@@ -0,0 +1,31 @@
name: ci
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
container:
image: python:3.13-slim
steps:
- uses: actions/checkout@v4
- run: pip install pyyaml ruff pytest
- run: ruff check src/ tests/
- run: PYTHONPATH=src pytest tests/ -v
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
docker login harbor.mymx.me \
-u "${{ secrets.HARBOR_USER }}" \
-p "${{ secrets.HARBOR_PASS }}"
- run: |
docker build \
-t harbor.mymx.me/s5p/s5p:latest \
-f Containerfile .
- run: docker push harbor.mymx.me/s5p/s5p:latest

View File

@@ -8,6 +8,8 @@ ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONPATH=/app/src
COPY src/ /app/src/
EXPOSE 1080
STOPSIGNAL SIGTERM

View File

@@ -37,9 +37,13 @@ Client -------> s5p -------> Hop 1 -------> Hop 2 -------> Target
| Local venv | `pip install -e .` then `s5p -c config/s5p.yaml` |
| Container | `make build && make up` (Alpine, ~59MB) |
Container mounts `./src` and `./config/s5p.yaml` read-only, plus
Production images bake source into the image via `COPY src/ /app/src/`.
Config and data are mounted at runtime: `./config/s5p.yaml` (ro) and
`~/.cache/s5p` as `/data` for pool state and profile output.
No application code is baked into the image.
The compose.yaml volume mount overrides source for local dev.
CI pushes `harbor.mymx.me/s5p/s5p:latest` on every push to `main`
(lint + tests must pass first).
## Dependencies

View File

@@ -57,8 +57,13 @@ make logs # podman-compose logs -f
make down # podman-compose down
```
Source, config, and data are bind-mounted, not baked into the image.
Pool state and profile output persist in `~/.cache/s5p/` (`/data` inside container).
Production images bake source into the image. Config and data are mounted
at runtime. Pool state and profile output persist in `~/.cache/s5p/`
(`/data` inside container). The compose.yaml volume mount overrides
source for local dev.
CI (Gitea Actions) runs lint + tests on push to `main`, then builds and
pushes `harbor.mymx.me/s5p/s5p:latest`.
## Configuration

View File

@@ -65,6 +65,8 @@
- [x] Onion chain-only routing (.onion skips pool hops)
- [x] Graceful shutdown timeout (fixes cProfile data dump)
- [x] Gitea CI workflow (lint + test + Harbor image push)
## Next
- [x] Integration tests with mock proxy server
- [ ] SOCKS5 server-side authentication

View File

@@ -30,7 +30,17 @@ make logs # podman-compose logs -f
make down # podman-compose down
```
Volumes: `./src` (ro), `./config/s5p.yaml` (ro), `~/.cache/s5p``/data` (pool state + profiles)
Volumes: `./config/s5p.yaml` (ro), `~/.cache/s5p``/data` (pool state + profiles)
Dev override: compose.yaml mounts `./src` (ro) over the baked-in source.
## CI
Gitea Actions runs on push to `main`:
1. `ruff check` + `pytest` in `python:3.13-slim`
2. Build + push `harbor.mymx.me/s5p/s5p:latest`
Secrets: `HARBOR_USER` / `HARBOR_PASS` (configured in Gitea repo settings).
## Config

View File

@@ -38,8 +38,9 @@ make build # podman-compose build
make up # podman-compose up -d
```
The Alpine-based image (~59MB) contains only Python and PyYAML.
Application source and config are bind-mounted at runtime.
The Alpine-based image (~59MB) contains Python, PyYAML, and baked-in
source. Config is mounted at runtime. The compose.yaml volume mount
overrides source for local dev.
## Install Tor (optional)