New docs/DEPLOY.md covering container image, compose config, volume mounts, host networking, operations, and troubleshooting. Updated README, INSTALL, CHEATSHEET, and DEBUG to reference it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.4 KiB
Podman Deployment
Overview
The bouncer runs in a rootless podman container with host networking. Source code and configuration are mounted as volumes -- the container image only contains Python and pip dependencies.
Container (bouncer)
|- python:3.12-slim + deps
|- /app/src <- ./src (read-only volume)
|- /data <- ./config (read-write volume)
Prerequisites
podmanandpodman-compose- SOCKS5 proxy reachable at
127.0.0.1:1080(host network)
Verify:
podman --version
podman-compose --version
ss -tlnp | grep 1080
Quick Start
cd ~/git/bouncer
# create config from template
cp config/bouncer.example.toml config/bouncer.toml
$EDITOR config/bouncer.toml
# build and start
make build
make up
# check logs
make logs
Container Image
The image installs only runtime dependencies. Source code is not baked in.
# build
podman build -t bouncer -f Containerfile .
# rebuild after dependency changes
podman build --no-cache -t bouncer -f Containerfile .
Containerfile
FROM python:3.12-slim
WORKDIR /app
RUN pip install --no-cache-dir \
"python-socks[asyncio]>=2.4" \
"aiosqlite>=0.19"
ENV PYTHONUNBUFFERED=1
ENV PYTHONPATH=/app/src
VOLUME /app/src
VOLUME /data
ENTRYPOINT ["python", "-m", "bouncer"]
CMD ["-c", "/data/bouncer.toml"]
Compose
services:
bouncer:
build:
context: .
dockerfile: Containerfile
container_name: bouncer
restart: unless-stopped
network_mode: host
logging:
driver: k8s-file
volumes:
- ./src:/app/src:Z,ro
- ./config:/data:Z
command: ["-c", "/data/bouncer.toml", "-v"]
Volume Mounts
| Host Path | Container Path | Mode | Purpose |
|---|---|---|---|
./src |
/app/src |
read-only | Python source code |
./config |
/data |
read-write | Config + SQLite backlog |
The :Z suffix applies the correct SELinux context for rootless podman.
Host Networking
network_mode: host is required because the bouncer needs access to:
127.0.0.1:1080-- SOCKS5 proxy (outbound IRC connections)127.0.0.1:6667-- client listen port (inbound IRC clients)
Log Driver
k8s-file is used instead of the default journald driver to ensure
podman logs works reliably in rootless mode.
Operations
Start / Stop / Restart
podman-compose up -d # start (detached)
podman-compose down # stop and remove
podman-compose restart # restart
Or with make targets:
make up # podman-compose up -d
make down # podman-compose down
Logs
podman logs -f bouncer # follow all logs
podman logs --tail 50 bouncer # last 50 lines
podman logs bouncer 2>&1 | grep -v aiosqlite # filter sqlite noise
podman logs bouncer 2>&1 | grep -E 'INFO|WARN' # important events only
Or:
make logs # podman logs -f bouncer
Status
podman ps --filter name=bouncer
podman inspect bouncer --format '{{.State.Status}}'
Shell Access
podman exec -it bouncer bash
podman exec bouncer python -c "import bouncer; print(bouncer.__version__)"
Inspect Backlog
The SQLite database is stored in the config volume:
sqlite3 config/bouncer.db "SELECT network, COUNT(*) FROM messages GROUP BY network;"
Updating
After pulling new code:
git pull
podman-compose down
podman-compose up -d
The image only needs rebuilding if dependencies change:
podman-compose down
make build
podman-compose up -d
Troubleshooting
Container exits immediately
Check logs for config or proxy errors:
podman logs bouncer
Common causes:
- Missing
config/bouncer.toml(not mounted) - SOCKS5 proxy not running on host
- Invalid TOML syntax
No log output
Verify PYTHONUNBUFFERED=1 is set in the Containerfile and the log driver
is k8s-file:
podman inspect bouncer --format '{{.HostConfig.LogConfig.Type}}'
Container can't reach SOCKS5 proxy
network_mode: host must be set. Verify the proxy is listening:
ss -tlnp | grep 1080
Permission denied on volumes
The :Z suffix handles SELinux relabeling. If issues persist:
podman unshare ls -la config/
Rebuild from scratch
podman-compose down
podman rmi bouncer
podman build --no-cache -t bouncer -f Containerfile .
podman-compose up -d