# Network and routing policy

## Choose the deployment mode first

Do not apply one Compose pattern to every Coolify resource.

| Mode | Public-network configuration | Traefik labels |
| --- | --- | --- |
| Coolify-managed application | Assign the resource to the Destination whose Docker network is `coolify`; do not add a repository network block for proxy reachability. | Prefer Coolify-generated labels; edit only when a documented customization is required. |
| Docker Compose build pack | Let Coolify create/attach its managed network and proxy. If `coolify` is the intended destination, verify that destination in Coolify. Avoid repository-defined custom networks. | Prefer domain configuration and Coolify-generated routing. |
| Raw Compose | Reference the existing Docker network with `external: true` and `name: coolify`; attach each public service explicitly. | Define complete routing labels. Add `traefik.docker.network=coolify` when the service has multiple networks. |
| Self-managed Compose outside Coolify magic | Treat `coolify` as an existing external proxy network and keep a separate private network where needed. | Define and verify routers, services, middlewares, TLS, and the selected network. |

Current Coolify documentation warns that custom networks in a managed Docker Compose build-pack deployment can cause intermittent 504s: Coolify attaches the container to its managed network, while Traefik may randomly select an address on another network. Traefik's Docker provider documentation independently requires an explicit `traefik.docker.network` selection when a container has several networks. Reconcile these facts by deciding the deployment mode before editing.

## Raw Compose pattern

Use this pattern only for Raw Compose or an explicitly self-managed stack:

```yaml
services:
  web:
    image: ghcr.io/example/web:immutable-tag
    networks:
      - public
      - private
    labels:
      traefik.enable: "true"
      traefik.docker.network: "coolify"
      traefik.http.routers.web.rule: "Host(`app.example.com`)"
      traefik.http.routers.web.entrypoints: "https"
      traefik.http.routers.web.tls: "true"
      traefik.http.routers.web.tls.certresolver: "letsencrypt"
      traefik.http.routers.web.service: "web"
      traefik.http.services.web.loadbalancer.server.port: "3000"

  db:
    image: postgres:18
    networks:
      - private

networks:
  public:
    external: true
    name: coolify
  private:
    internal: true
```

Use unique router, service, and middleware names per deployment. Do not copy placeholder domains, ports, certificate resolvers, or image tags into a fix without checking the running proxy configuration.

## Runtime checks

Run read-only checks before proposing a network mutation:

```bash
docker network inspect coolify
docker inspect <traefik-container> --format '{{json .NetworkSettings.Networks}}'
docker inspect <app-container> --format '{{json .NetworkSettings.Networks}}'
docker inspect <app-container> --format '{{json .Config.Labels}}'
```

Confirm:

- the network exists and its driver matches standalone Docker versus Swarm;
- the proxy and application are both attached;
- the label value uses the effective Docker network name `coolify`, not merely a Compose alias;
- Traefik's service port equals the application's listening container port;
- no database or cache was accidentally attached to the public network or published on a host port.

## Symptom map

| Symptom | Check first |
| --- | --- |
| Intermittent 504 after redeploy | Multiple app networks and missing/wrong `traefik.docker.network`; managed build pack with repository-defined custom networks. |
| Stable 502 | Wrong load-balancer port, connection refusal, TLS-to-backend mismatch, or app listening only on loopback. |
| 404 from Traefik | Router rule not loaded/matched, wrong entrypoint, `traefik.enable`, provider constraints, or hostname mismatch. |
| 503 / no available server | Empty/unhealthy backend set, stopped container, failing healthcheck, or service association mismatch. |
| Certificate failure | DNS target, port 80/443 reachability, ACME resolver/challenge, rate limit, or certificate storage permissions. |
| Works by host port but not domain | Proxy network, router, service port, or middleware problem; do not keep the host port as the fix. |

## Safety rules

- Do not run `docker network rm`, `docker system prune`, volume removal, or forced container recreation as a diagnostic shortcut.
- Do not expose Docker's socket or store credentials in Traefik labels.
- Do not modify Coolify's generated proxy configuration without a backup and explicit production authorization.
- For Compose label values containing `$`, account for Compose interpolation and Coolify's documented escaping behavior.
