docker compose)pip install p4n4
p4n4 --version
p4n4 init my-project # IoT stack only (default)
p4n4 init my-project --layer iot,ai # multiple stacks
p4n4 init my-project --layer all # everything
The interactive wizard prompts for configuration (InfluxDB organisation, timezone, service passwords — leave blank to auto-generate). It then:
p4n4-iot, p4n4-ai)..env..p4n4.json project manifest.A single-layer project keeps the stack files at the project root:
my-project/
├── .p4n4.json
├── .env
├── docker-compose.yml
├── config/
└── scripts/
A multi-layer project gives each stack its own subdirectory, so the stacks run
as separate Compose projects (the AI stack attaches to the p4n4-net network that
the IoT stack creates):
my-project/
├── .p4n4.json ← manifest at the root, lists all layers
├── iot/
│ ├── docker-compose.yml
│ ├── .env
│ ├── config/
│ └── scripts/
└── ai/
├── docker-compose.yml
├── .env
├── config/
└── scripts/
Shared values such as INFLUXDB_TOKEN are written identically to every layer’s
.env, and p4n4 secret rotate keeps them in sync.
cd my-project
p4n4 up # all enabled stacks
p4n4 up iot # one stack only
With no argument, stacks start in dependency order:
iot — creates the p4n4-net Docker bridge network, starts Mosquitto and InfluxDB first.ai — attaches to p4n4-net.edge — attaches to p4n4-net.p4n4 down stops them in reverse order.
| Service | URL |
|---|---|
| Node-RED | http://localhost:1880 |
| Grafana | http://localhost:3000 |
| InfluxDB | http://localhost:8086 |
| n8n | http://localhost:5678 |
| Letta | http://localhost:8283 |
| Ollama | http://localhost:11434 |
p4n4 down