A production-ready IP Address Management (IPAM) tool with a FastAPI backend, SQLite persistence, and a dark-themed TailwindCSS dashboard. Automatically allocates subnets, detects gaps, avoids reserved ranges, and supports multiple independent network pools.
10.0.0.0/8, 172.19.0.0/16, 192.168.0.0/16) from the UI./30 through /24).docker-compose network snippet.POST /api/pools, POST /api/subnets/allocate, DELETE /api/subnets/{id}) are protected by X-API-Key header. Read-only endpoints (GET /api/subnets, GET /api/pools, GET /api/subnets/fragmentation) are open.docker run -d \
-p 8000:8000 \
-v ipam_data:/app \
--name ipam \
your-dockerhub-username/ipam-engine
Open http://localhost:8000 in your browser.
# clone or copy the project files
cd ipam-app
docker compose up -d
pip install fastapi uvicorn sqlalchemy aiosqlite
python -m uvicorn main:app --host 0.0.0.0 --port 8000
http://localhost:8000..ipam_key in the app directory.
cat /path/to/app/.ipam_key
10.0.0.0/8).Mutating endpoints require an X-API-Key header. The key is auto-generated on first run (see .ipam_key file or server logs) or set via the IPAM_ADMIN_KEY environment variable.
| Method | Path | Auth | Description |
|---|---|---|---|
GET | / | No | Serves the dashboard UI |
GET | /api/pools | No | List all network pools |
POST | /api/pools | Yes | Create a new network pool |
DELETE | /api/pools/{id} | Yes | Delete an empty pool |
GET | /api/subnets | No | List subnets (optional ?pool_id= filter) |
POST | /api/subnets/allocate | Yes | Allocate a new subnet |
DELETE | /api/subnets/{id} | Yes | Release a subnet |
GET | /api/subnets/fragmentation | No | Pool utilization & gap report (?pool_id= required) |
curl -X POST http://localhost:8000/api/pools \
-H "Content-Type: application/json" \
-H "X-API-Key: $(cat .ipam_key)" \
-d '{"pool_name":"Production","base_cidr":"10.0.0.0/8","reserved_blocks":"10.0.0.0/24,10.0.1.0/24"}'
curl -X POST http://localhost:8000/api/subnets/allocate \
-H "Content-Type: application/json" \
-H "X-API-Key: $(cat .ipam_key)" \
-d '{"pool_id":1,"project_name":"Web Stack","required_hosts":6}'
curl -X DELETE http://localhost:8000/api/subnets/1 \
-H "X-API-Key: $(cat .ipam_key)"
| Variable | Default | Description |
|---|---|---|
IPAM_ADMIN_KEY | Auto-generated (256-bit) | Primary API key for admin access |
IPAM_CI_KEY | None | Secondary API key for CI/CD pipelines |
If neither variable is set, a random key is generated on first run and persisted to .ipam_key.
docker build -t ipam-engine .
docker tag ipam-engine your-dockerhub-username/ipam-engine:latest
docker login
docker push your-dockerhub-username/ipam-engine:latest
docker pull your-dockerhub-username/ipam-engine:latest
docker run -d \
-p 8000:8000 \
-v /path/on/host:/app \
-e IPAM_ADMIN_KEY=my-secret-key \
--name ipam \
your-dockerhub-username/ipam-engine
The SQLite database (ipam_prod.db) and API key file (.ipam_key) are stored in the application directory. To persist data across container restarts, mount a host directory to /app:
docker run -d -p 8000:8000 -v /my/data/dir:/app ipam-engine
With docker-compose, the ipam_data named volume is used by default. You can switch to a bind mount by editing docker-compose.yml:
volumes:
- /my/data/dir:/app
ipam-app/
āāā main.py # FastAPI application
āāā index.html # Dashboard UI (TailwindCSS, offline)
āāā Dockerfile # Production Docker build
āāā docker-compose.yml # Docker Compose configuration
āāā requirements.txt # Python dependencies
āāā README.md # This file
āāā static/
āāā tailwind.js # TailwindCSS (local, no CDN)
Browser (index.html)
ā
ā¼
FastAPI (main.py)
ā
āāā GET /api/pools ā List pools
āāā POST /api/pools [auth] ā Create pool
āāā GET /api/subnets ā List subnets
āāā POST /api/subnets/allocate [auth] ā Allocate subnet
āāā DELETE /api/subnets/{id} [auth] ā Release subnet
āāā GET /api/subnets/fragmentation ā Pool utilization
ā
ā¼
SQLite (ipam_prod.db)
āāā network_pools ā Pool definitions
āāā subnets ā Allocated subnets linked to pools via pool_id
The allocation engine uses Python's built-in ipaddress module. When a subnet is requested:
hosts[0] = gateway, hosts[1] = first usable container IP.MIT
Content type
Image
Digest
sha256:0dad55a41ā¦
Size
60.4 MB
Last updated
2 months ago
docker pull certyiknofetch/netops