Installation¶
This page documents supported ways to run proxbox-api.
Requirements¶
- Python 3.11+
uv(recommended) orpip- Network access to NetBox and Proxmox targets
Option 1: Docker (recommended for quick start)¶
All Docker images are Alpine-based (smaller footprint). Three variants are available:
| Variant | Tags | Description |
|---|---|---|
| Raw (default) | latest, <version> |
Pure uvicorn, HTTP only. Smallest image. |
| Nginx | latest-nginx, <version>-nginx |
nginx terminates HTTPS via mkcert; proxies to uvicorn. |
| Granian | latest-granian, <version>-granian |
Granian (Rust ASGI server) with native TLS via mkcert. |
Raw image — HTTP only (default)¶
Simplest option. No proxy in front, plain HTTP. Ideal for local development or behind your own reverse proxy.
docker pull emersonfelipesp/proxbox-api:latest
docker run -d -p 8000:8000 --name proxbox-api emersonfelipesp/proxbox-api:latest
Service URL:
Nginx image — HTTPS with mkcert¶
nginx terminates HTTPS using auto-generated mkcert certificates and proxies to uvicorn inside the container.
docker pull emersonfelipesp/proxbox-api:latest-nginx
docker run -d -p 8443:8000 --name proxbox-api-nginx \
emersonfelipesp/proxbox-api:latest-nginx
Service URL:
- https://127.0.0.1:8443 (self-signed, trusted on the container host)
Connecting netbox-proxbox to the nginx image¶
The nginx image is HTTPS-only — plain HTTP requests to the TLS port return a
JSON 400 body with {"error":"plain_http_on_https_port", ...} (rendered from
nginx's internal 497 code). When configuring the FastAPI Endpoint in the
NetBox netbox-proxbox plugin, set:
| Field | Value |
|---|---|
| Use HTTPS | ✓ enabled |
| Verify SSL | ✗ disabled (when using the bundled mkcert certificate) |
| Port | the host port mapped to container 8000 (typically 8800 or 8443) |
The Use HTTPS and Verify SSL toggles are independent in
netbox-proxbox >= 0.0.16 — see
issue #352 for
context. Earlier plugin releases couple the two flags, which makes the
nginx-image + self-signed-cert combination unreachable.
Granian image — HTTPS with mkcert (no nginx)¶
Granian is a Rust-based ASGI server with native TLS and HTTP/2. A single process handles everything — no nginx or supervisord required.
docker pull emersonfelipesp/proxbox-api:latest-granian
docker run -d -p 8443:8000 --name proxbox-api-granian \
emersonfelipesp/proxbox-api:latest-granian
Service URL:
Docker runtime environment variables¶
Common to all images (raw, nginx, granian):
| Variable | Default | Description |
|---|---|---|
PORT |
8000 |
Port the server listens on |
PROXBOX_BIND_HOST |
0.0.0.0 |
Address the server binds to. Set to :: for IPv4 + IPv6 dual-stack. Honored by the raw and granian images; the nginx image listens on both stacks unconditionally. |
mkcert-specific (only for the nginx and granian images):
| Variable | Default | Description |
|---|---|---|
MKCERT_CERT_DIR |
/certs |
Directory where certificates are stored |
MKCERT_EXTRA_NAMES |
— | Extra SANs (comma or space separated), e.g. proxbox.lan,10.0.0.5 |
CAROOT |
— | Mount a volume here to persist the local CA across restarts |
Example with extra SANs:
docker run -d -p 8443:8000 --name proxbox-api-tls \
-e MKCERT_EXTRA_NAMES='myhost.local,192.168.1.10' \
emersonfelipesp/proxbox-api:latest-nginx
Mounting custom certificates¶
Both the nginx and granian images detect pre-existing certificates at startup.
If cert.pem and key.pem are already present inside $MKCERT_CERT_DIR (default /certs),
mkcert generation is skipped entirely — the container uses those files as-is.
This lets you mount your own CA-signed, Let's Encrypt, or corporate certificates without
any special flags.
docker run -d -p 8443:8000 --name proxbox-api-nginx \
-v ./certs:/certs:ro \
emersonfelipesp/proxbox-api:latest-nginx
The ./certs directory must contain at minimum:
| File | Description |
|---|---|
cert.pem |
PEM-encoded certificate (may be a full chain) |
key.pem |
PEM-encoded private key (PKCS#1 or PKCS#8) |
Docker Compose example:
services:
proxbox-api:
image: emersonfelipesp/proxbox-api:latest-nginx
container_name: proxbox-api
restart: unless-stopped
ports:
- "8443:8000"
volumes:
- ./certs:/certs:ro
Granian image and PKCS#8 keys¶
Granian's TLS layer requires the private key in PKCS#8 format. The entrypoint handles this automatically:
- If
key-pkcs8.pemis present in the mounted directory → use it directly. - If
key-pkcs8.pemis absent and the directory is writable → convertkey.pemin place and writekey-pkcs8.pemthere. - If
key-pkcs8.pemis absent and the directory is read-only → convert and write to/tmp/key-pkcs8.pem(ephemeral; not persisted across container restarts).
To pre-convert your key and avoid the /tmp fallback:
Then mount the directory containing all three files (cert.pem, key.pem, key-pkcs8.pem).
Binding to IPv6 / dual-stack¶
To listen on both IPv4 and IPv6, set PROXBOX_BIND_HOST=:::
Docker Compose quoting caveat¶
In Compose environment: list-form, values are taken verbatim — the quotes are NOT stripped — so - PROXBOX_BIND_HOST="::" ends up as the literal 4-character string "::" inside the container, which used to crash binding with [Errno -2] Name does not resolve. The container now sanitizes surrounding quotes defensively, but the recommended forms are:
Build from source¶
git clone https://github.com/emersonfelipesp/proxbox-api.git
cd proxbox-api
docker build -t proxbox-api:raw . # raw (default)
docker build --target nginx -t proxbox-api:nginx . # nginx
docker build --target granian -t proxbox-api:granian . # granian
Option 2: PyPI¶
The package is published to PyPI as proxbox-api.
Or with uv:
Start the server:
Option 3: Local development from source¶
Clone repository:
Install runtime dependencies:
Or use uv:
Run API:
Alternative with uvicorn:
fastapi run does not expose TLS flags; for HTTPS from the app process, use uvicorn with --ssl-certfile / --ssl-keyfile below, or put nginx/Caddy in front (recommended for real certificates).
TLS without Docker¶
Local certificates (mkcert)¶
For trusted HTTPS on your own machine only:
mkcert -install
mkcert proxbox.backend.local localhost 127.0.0.1 ::1
uv run uvicorn proxbox_api.main:app --host 127.0.0.1 --port 8000 --reload \
--ssl-keyfile=./proxbox.backend.local+3-key.pem \
--ssl-certfile=./proxbox.backend.local+3.pem
Adjust file names to match what mkcert created.
Publicly trusted or corporate certificates¶
Recommended: terminate TLS in nginx or Caddy, run the API on HTTP on 127.0.0.1:8000:
Point the proxy at http://127.0.0.1:8000 and set ssl_certificate / ssl_certificate_key to your PEM paths (for Let's Encrypt: fullchain.pem and privkey.pem under /etc/letsencrypt/live/<domain>/). Set X-Forwarded-Proto and related headers so the app sees the original scheme. See the repository README for a complete nginx server example.
Direct uvicorn TLS (small deployments): use the full certificate chain as --ssl-certfile and the private key as --ssl-keyfile:
uv run uvicorn proxbox_api.main:app --host 0.0.0.0 --port 8443 \
--ssl-certfile=/etc/letsencrypt/live/api.example.com/fullchain.pem \
--ssl-keyfile=/etc/letsencrypt/live/api.example.com/privkey.pem
Ensure the process user can read those files, and renew/reload after certificate updates.
Verify installation¶
Open:
- Root: http://127.0.0.1:8000/
- Swagger: http://127.0.0.1:8000/docs
- ReDoc: http://127.0.0.1:8000/redoc