Networking Model
Stackpad uses project-scoped Docker networks to provide private communication between services with automatic DNS discovery. This page explains the networking model in detail.
Project networks
Every project gets its own isolated Docker network. All services in the project are attached to this network and can reach each other using their service name as a hostname.
Project: "my-app"├── Network: my-app-production│ ├── web → reachable at "web:3000"│ ├── postgres → reachable at "postgres:5432"│ └── redis → reachable at "redis:6379"DNS discovery
Docker’s built-in DNS resolves service names to container IP addresses within the project network. This means:
postgresresolves to the PostgreSQL container’s IPredisresolves to the Redis container’s IPapiresolves to another web service’s IP
No hardcoded IPs, no service discovery tools, no configuration — just use the name.
Network isolation
Each project’s network is completely isolated:
- Services in Project A cannot reach services in Project B
postgresin Project A resolves to a different container thanpostgresin Project B- No cross-project DNS resolution is possible
This isolation is enforced at the Docker network level and provides security without configuration.
External access
Web services
Web services (type web) are exposed externally via Caddy:
Internet → Caddy (HTTPS) → Compute Node → ContainerEach web service gets a URL at project.org.stackpad.eu, and optionally custom domains.
Internal services
Database, cache, and generic service types are not exposed externally by default. They are only accessible from within the project’s private network. This is a security best practice — your database should never be directly accessible from the internet.
Traffic flow
A request to your Stackpad app follows this path:
- DNS —
project.org.stackpad.euresolves to the control node IP - Caddy — accepts the HTTPS connection, terminates TLS
- Reverse proxy — Caddy routes to the correct compute node based on the hostname
- Container — the request reaches your application
For internal service-to-service communication:
- DNS —
postgresresolves to the container IP via Docker DNS - Direct — traffic flows directly between containers on the project network
Internal traffic never leaves the compute node (if both services are on the same node) or travels over the private WireGuard network (if on different nodes).
Environment networks
Each environment gets its own network. If your project has production and staging environments, they have separate networks with separate containers:
my-app-production— production servicesmy-app-staging— staging services
Services in different environments cannot communicate with each other.
What’s next?
- Connecting services — practical guide to connecting services
- Architecture — overall platform architecture
- Security — container isolation and security profiles