feat: add Gitea CI workflow and production Containerfile
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:
@@ -0,0 +1,9 @@
|
|||||||
|
.venv/
|
||||||
|
.git/
|
||||||
|
tests/
|
||||||
|
docs/
|
||||||
|
*.prof
|
||||||
|
*.egg-info/
|
||||||
|
__pycache__/
|
||||||
|
.gitea/
|
||||||
|
.pytest_cache/
|
||||||
@@ -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
|
||||||
@@ -8,6 +8,8 @@ ENV PYTHONUNBUFFERED=1 \
|
|||||||
PYTHONDONTWRITEBYTECODE=1 \
|
PYTHONDONTWRITEBYTECODE=1 \
|
||||||
PYTHONPATH=/app/src
|
PYTHONPATH=/app/src
|
||||||
|
|
||||||
|
COPY src/ /app/src/
|
||||||
|
|
||||||
EXPOSE 1080
|
EXPOSE 1080
|
||||||
STOPSIGNAL SIGTERM
|
STOPSIGNAL SIGTERM
|
||||||
|
|
||||||
|
|||||||
+6
-2
@@ -37,9 +37,13 @@ Client -------> s5p -------> Hop 1 -------> Hop 2 -------> Target
|
|||||||
| Local venv | `pip install -e .` then `s5p -c config/s5p.yaml` |
|
| Local venv | `pip install -e .` then `s5p -c config/s5p.yaml` |
|
||||||
| Container | `make build && make up` (Alpine, ~59MB) |
|
| 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.
|
`~/.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
|
## Dependencies
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,13 @@ make logs # podman-compose logs -f
|
|||||||
make down # podman-compose down
|
make down # podman-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
Source, config, and data are bind-mounted, not baked into the image.
|
Production images bake source into the image. Config and data are mounted
|
||||||
Pool state and profile output persist in `~/.cache/s5p/` (`/data` inside container).
|
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
|
## Configuration
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,8 @@
|
|||||||
- [x] Onion chain-only routing (.onion skips pool hops)
|
- [x] Onion chain-only routing (.onion skips pool hops)
|
||||||
- [x] Graceful shutdown timeout (fixes cProfile data dump)
|
- [x] Graceful shutdown timeout (fixes cProfile data dump)
|
||||||
|
|
||||||
|
- [x] Gitea CI workflow (lint + test + Harbor image push)
|
||||||
|
|
||||||
## Next
|
## Next
|
||||||
- [x] Integration tests with mock proxy server
|
- [x] Integration tests with mock proxy server
|
||||||
- [ ] SOCKS5 server-side authentication
|
- [ ] SOCKS5 server-side authentication
|
||||||
|
|||||||
+11
-1
@@ -30,7 +30,17 @@ make logs # podman-compose logs -f
|
|||||||
make down # podman-compose down
|
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
|
## Config
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -38,8 +38,9 @@ make build # podman-compose build
|
|||||||
make up # podman-compose up -d
|
make up # podman-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
The Alpine-based image (~59MB) contains only Python and PyYAML.
|
The Alpine-based image (~59MB) contains Python, PyYAML, and baked-in
|
||||||
Application source and config are bind-mounted at runtime.
|
source. Config is mounted at runtime. The compose.yaml volume mount
|
||||||
|
overrides source for local dev.
|
||||||
|
|
||||||
## Install Tor (optional)
|
## Install Tor (optional)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user