Skip to content

Commit f82fb44

Browse files
committed
Add Docker deployment section to README
1 parent 42f7194 commit f82fb44

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ docker build -t postalcode2nuts .
3232
docker run -p 8000:8000 postalcode2nuts
3333
```
3434

35+
See [Docker deployment](#docker-deployment) below for persistent volumes and production configuration.
36+
3537
## Endpoints
3638

3739
| Endpoint | Description |
@@ -413,6 +415,77 @@ Changing the `PC2NUTS_EXTRA_SOURCES` list invalidates the SQLite cache automatic
413415
- **Rate limiting:** Limits are per-client IP (`X-Forwarded-For` aware). Behind a reverse proxy, ensure the proxy sets this header correctly.
414416
- **Access logging:** Every request is logged with client IP, method, path, status code, and duration. Set `PC2NUTS_ACCESS_LOG_FILE` to write to a rotating file instead of stderr.
415417

418+
## Docker deployment
419+
420+
### Build
421+
422+
```bash
423+
docker build -t postalcode2nuts .
424+
```
425+
426+
### Basic run
427+
428+
```bash
429+
docker run -p 8000:8000 postalcode2nuts
430+
```
431+
432+
On first start the service downloads TERCET data for all 34 countries (~2-5 minutes depending on network). After that it caches everything in a SQLite database for instant restarts.
433+
434+
### Persistent data volume
435+
436+
Without a volume, the cache is lost when the container stops and TERCET data must be re-downloaded on every restart. Add a named volume to keep the cache:
437+
438+
```bash
439+
docker run -p 8000:8000 -v postalcode2nuts-data:/app/data postalcode2nuts
440+
```
441+
442+
### Production example
443+
444+
```bash
445+
docker run -d --name postalcode2nuts \
446+
-p 8000:8000 \
447+
-v postalcode2nuts-data:/app/data \
448+
-e PC2NUTS_DOCS_ENABLED=false \
449+
-e PC2NUTS_CORS_ORIGINS=https://mysite.com \
450+
-e PC2NUTS_RATE_LIMIT=100/minute \
451+
-e PC2NUTS_ACCESS_LOG_FILE=/app/data/access.log \
452+
postalcode2nuts
453+
```
454+
455+
This disables Swagger UI, restricts CORS to a single origin, increases the rate limit, and writes access logs to a rotating file inside the persistent volume.
456+
457+
### Docker Compose
458+
459+
```yaml
460+
services:
461+
postalcode2nuts:
462+
build: .
463+
ports:
464+
- "8000:8000"
465+
volumes:
466+
- postalcode2nuts-data:/app/data
467+
environment:
468+
- PC2NUTS_DOCS_ENABLED=false
469+
- PC2NUTS_CORS_ORIGINS=https://mysite.com
470+
- PC2NUTS_ACCESS_LOG_FILE=/app/data/access.log
471+
restart: unless-stopped
472+
473+
volumes:
474+
postalcode2nuts-data:
475+
```
476+
477+
### What's in the image
478+
479+
| Item | Details |
480+
|------|---------|
481+
| Base image | `python:3.12-slim` |
482+
| User | `appuser` (non-root) |
483+
| Dependencies | Pinned via `requirements.lock` |
484+
| Estimates CSV | Included (`tests/tercet_missing_codes.csv`) |
485+
| Health check | Built-in (`/health`, 30s interval, 120s start period) |
486+
| Port | 8000 |
487+
| Volume | `/app/data` (SQLite cache + downloaded ZIPs) |
488+
416489
## Project structure
417490

418491
```

0 commit comments

Comments
 (0)