---
title: Domains
description: Configure domains for your Docker Compose application.
---

import { Callout } from "fumadocs-ui/components/callout";

When using Docker Compose, there are **two ways** to configure domains for your services:

## Method 1: Using Dokploy Domains (Recommended)

The easiest way to configure domains is using Dokploy's native domain management feature. This method allows you to configure domains directly through the Dokploy UI without manually editing your Docker Compose file.

<Callout type="info">
  **Recommended**: Since v0.7.0, Dokploy supports domains natively. You can configure your domains directly in the Dokploy UI through the **Domains** tab of your Docker Compose application. This is the simplest and most user-friendly approach.
</Callout>

To use this method:
1. Navigate to your Docker Compose application in Dokploy
2. Go to the **Domains** tab
3. Click **Add Domain** and configure your domain
4. Dokploy will automatically handle the routing configuration

### How It Works

At runtime, during the deployment phase, Dokploy automatically adds Traefik labels internally to your Docker Compose file. You don't need to manually add these labels - Dokploy handles this automatically based on the domains you configure in the UI.

**Example:**

Here's a default Docker Compose file:

```yaml
version: "3.8"

services:
  beszel:
    image: henrygd/beszel:0.10.2
    restart: unless-stopped
    ports:
      - 8090
    volumes:
      - beszel_data:/beszel_data
      - /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
  beszel_data: {}
```

**Preview Compose Feature:**

You can click the **Preview Compose** button to see the final Docker Compose file that will be executed. If you have at least one domain added, the preview will show the compose file with all the labels and network configurations automatically added.

Here's what the final compose file looks like when deployed (this example uses [Isolated Deployments](/docs/core/docker-compose/utilities#isolated-deployments)):

```yaml
version: "3.8"

services:
  beszel:
    image: henrygd/beszel:0.10.2
    restart: unless-stopped
    ports:
      - 8090
    volumes:
      - beszel_data:/beszel_data
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - a-beszel-a95pzl
    labels:
      - traefik.http.routers.a-beszel-a95pzl-715-web.rule=Host(`a-beszel-d073ee-31-220-108-27.traefik.me`)
      - traefik.http.routers.a-beszel-a95pzl-715-web.entrypoints=web
      - traefik.http.services.a-beszel-a95pzl-715-web.loadbalancer.server.port=8090
      - traefik.http.routers.a-beszel-a95pzl-715-web.service=a-beszel-a95pzl-715-web
      - traefik.enable=true

volumes:
  beszel_data: {}

networks:
  a-beszel-a95pzl:
    name: a-beszel-a95pzl
    external: true
```

**Important Notes:**

- If you don't add any domains through the UI and don't use [Isolated Deployments](/docs/core/docker-compose/utilities#isolated-deployments), your application will be deployed exactly as you specified in your original Docker Compose file - no labels or network modifications will be added.
- If you're not using [Isolated Deployments](/docs/core/docker-compose/utilities#isolated-deployments), Dokploy will add the `dokploy-network` to the service you selected, however you need to add `dokploy-network` to the other services to maintain connectivity.
- The Preview Compose button is useful for verifying how Dokploy will modify your compose file before deployment.
- All label generation and network configuration is handled automatically by Dokploy based on your domain settings.

For detailed instructions on using Dokploy's domain management, see the [Domains guide](/docs/core/domains).

## Method 2: Manual Configuration (Advanced)

If you prefer to configure domains manually using Traefik labels in your Docker Compose file, you can do so by following the steps below. This method gives you more control but requires manual configuration.

<Callout type="warn">
  Manual configuration is more complex and requires editing your Docker Compose file. We recommend using Method 1 (Dokploy Domains) unless you have specific requirements that need manual Traefik label configuration.
</Callout>

### Manual Configuration Steps

Key Steps for manual configuration:

1. Add the service to the `dokploy-network`.
2. Use Traefik labels to configure routing.

### Example Scenario

Let's consider an application with three components: a frontend, a backend, and a database. We'll start with a basic Docker Compose file and then enhance it with manual domain configuration.

```yaml
version: "3.8"

services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    volumes:
      - ./frontend:/app
    ports:
      - "3000:3000"
    depends_on:
      - backend

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    volumes:
      - ./backend:/app
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgres://postgres:password@database:5432/mydatabase
    depends_on:
      - database

  database:
    image: postgres:13
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydatabase
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:
```

### Step 1: Add the Network

First, we'll add the dokploy-network to our services:

<Callout type="info">
  **Tip**: If you prefer to isolate all services and avoid adding them to the `dokploy-network`, you can use the **Isolated Deployments** feature. This feature isolates all services and eliminates the need to manually add them to the dokploy-network. See the [Isolated Deployments guide](/docs/core/docker-compose/utilities#isolated-deployments) for more information.
</Callout>

```yaml
version: "3.8"

services:
  frontend:
    # ... (previous configuration)
    networks:
      - dokploy-network

  backend:
    # ... (previous configuration)
    networks:
      - dokploy-network

  database:
    # ... (previous configuration)
    networks:
      - dokploy-network

volumes:
  db-data:

networks:
  dokploy-network:
    external: true
```

### Step 2: Configuring Traefik Labels

Now, let's add Traefik labels to route domains to our services. We'll focus on the frontend and backend services:

<Callout type="warn">
  **Important for Docker Stack**: If you're using **Docker Stack** (Docker Swarm mode), the Traefik labels must be placed in the `deploy.labels` section instead of directly in the `labels` section. See the Docker Stack example below.
</Callout>

```yaml
version: "3.8"

services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    volumes:
      - ./frontend:/app
    expose:
      - 3000
    depends_on:
      - backend
    networks:
      - dokploy-network
    labels:
      - traefik.enable=true
      - traefik.http.routers.frontend-app.rule=Host(`frontend.dokploy.com`)
      - traefik.http.routers.frontend-app.entrypoints=web
      - traefik.http.services.frontend-app.loadbalancer.server.port=3000

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    volumes:
      - ./backend:/app
    expose:
      - 5000
    environment:
      - DATABASE_URL=postgres://postgres:password@database:5432/mydatabase
    depends_on:
      - database
    networks:
      - dokploy-network
    labels:
      - traefik.enable=true
      - traefik.http.routers.backend-app.rule=Host(`backend.dokploy.com`)
      - traefik.http.routers.backend-app.entrypoints=web
      - traefik.http.services.backend-app.loadbalancer.server.port=5000

  database:
    # ... (same as before)

volumes:
  db-data:

networks:
  dokploy-network:
    external: true
```

### Understanding Traefik Labels

1. `traefik.enable=true` Enables Traefik routing for the service.
2. `traefik.http.routers.<UNIQUE-RULE>.rule=Host('your-domain.dokploy.com')` Specifies the domain for the service
3. `traefik.http.routers.<UNIQUE-RULE>.entrypoints=web` Sets the service to be accessible via HTTP.
4. `traefik.http.services.<UNIQUE-RULE>.loadbalancer.server.port=3000` Specifies the port your service is using internally.

**Note**: Replace `<UNIQUE-RULE>` with a unique identifier for each service (e.g., frontend-app, backend-app, etc.).

#### Docker Stack Configuration

When using **Docker Stack** (Docker Swarm mode), labels must be placed under the `deploy.labels` section. Additionally, Docker Stack does not support the `build` directive, so you must use pre-built images from a registry:

<Callout type="warn">
  **Important**: Docker Stack does not support the `build` directive. You must build your images separately and push them to a Docker registry, then reference them using the `image:` directive.
</Callout>

```yaml
version: "3.8"

services:
  frontend:
    image: your-registry.com/frontend:latest  # Pre-built image from registry
    volumes:
      - ./frontend:/app
    expose:
      - 3000
    networks:
      - dokploy-network
    deploy:
      labels:
        - traefik.enable=true
        - traefik.http.routers.frontend-app.rule=Host(`frontend.dokploy.com`)
        - traefik.http.routers.frontend-app.entrypoints=web
        - traefik.http.services.frontend-app.loadbalancer.server.port=3000

  backend:
    image: your-registry.com/backend:latest  # Pre-built image from registry
    volumes:
      - ./backend:/app
    expose:
      - 5000
    networks:
      - dokploy-network
    deploy:
      labels:
        - traefik.enable=true
        - traefik.http.routers.backend-app.rule=Host(`backend.dokploy.com`)
        - traefik.http.routers.backend-app.entrypoints=web
        - traefik.http.services.backend-app.loadbalancer.server.port=5000

networks:
  dokploy-network:
    external: true
```

<Callout type="info">
  The key differences for **Docker Stack** are:
  1. Labels must be nested under `deploy.labels` (not directly under `labels`)
  2. You must use `image:` with a pre-built image from a registry (Docker Stack does not support `build`)
  3. Build your images separately and push them to a registry before deploying with Docker Stack
</Callout>

### Important Considerations

1. **Port Exposure**: Use `expose` instead of `ports` to limit port access to the container network, avoiding exposure to the host machine.
2. **DNS Configuration**: Ensure you create `A` records pointing to your domain in your DNS Provider Settings.
3. **HTTPS**: For HTTPS, you can use Let's Encrypt or other SSL/TLS certificates.
4. **Isolated Deployments**: As an alternative to manually adding services to `dokploy-network`, you can use the [Isolated Deployments](/docs/core/docker-compose/utilities#isolated-deployments) feature, which automatically isolates all services and handles networking configuration for you.

### Deployment

With these manual configurations in place, you're now ready to deploy your application using Docker Compose. This setup should be sufficient to get your services up and running with custom domain routing through Traefik.

<Callout type="info">
  Remember: For most use cases, we recommend using **Method 1 (Dokploy Domains)** as it's simpler and doesn't require manual Docker Compose file editing. See the [Domains guide](/docs/core/domains) for more information.
</Callout>

If you have any further questions or need assistance, join our [Discord server](https://discord.com/invite/2tBnJ3jDJc) and we'll be happy to help.
