Skip to content

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:

  • postgres resolves to the PostgreSQL container’s IP
  • redis resolves to the Redis container’s IP
  • api resolves 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
  • postgres in Project A resolves to a different container than postgres in 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 → Container

Each 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:

  1. DNSproject.org.stackpad.eu resolves to the control node IP
  2. Caddy — accepts the HTTPS connection, terminates TLS
  3. Reverse proxy — Caddy routes to the correct compute node based on the hostname
  4. Container — the request reaches your application

For internal service-to-service communication:

  1. DNSpostgres resolves to the container IP via Docker DNS
  2. 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 services
  • my-app-staging — staging services

Services in different environments cannot communicate with each other.

What’s next?