Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dokploy/dokploy/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Dokploy provides comprehensive storage management through three mount types: volumes, bind mounts, and file mounts. These enable persistent data storage, configuration injection, and shared storage across containers.

Mount Types

Dokploy supports three types of mounts, each suited for different use cases:

Volume

Docker-managed named volumes for persistent data.Best for: Databases, uploads, application state

Bind Mount

Direct host filesystem paths mounted into containers.Best for: Development, logs, shared configs

File Mount

Individual configuration files injected from Dokploy.Best for: Config files, secrets, certificates

Supported Services

Mounts can be attached to any service type:
  • Applications
  • Compose services
  • PostgreSQL databases
  • MySQL databases
  • MariaDB databases
  • MongoDB databases
  • Redis instances

Creating Mounts

1

Navigate to service

Open your application or database service.
2

Access mounts section

Click on the Mounts or Storage tab.
3

Add mount

Click Add Mount and select the mount type.
4

Configure mount

Fill in the required fields based on mount type.
5

Save and redeploy

Save the configuration and restart the service for changes to take effect.

Volume Mounts

Docker volumes provide persistent storage managed by Docker.

Creating a Volume Mount

{
  type: "volume",
  volumeName: "postgres_data",
  mountPath: "/var/lib/postgresql/data",
  serviceType: "postgres",
  serviceId: "postgres-123"
}
Store database files persistently:
// PostgreSQL
{
  type: "volume",
  volumeName: "postgres_data",
  mountPath: "/var/lib/postgresql/data"
}

// MySQL
{
  type: "volume",
  volumeName: "mysql_data",
  mountPath: "/var/lib/mysql"
}

// MongoDB
{
  type: "volume",
  volumeName: "mongo_data",
  mountPath: "/data/db"
}

Volume Management

Volumes are Docker-managed and persist beyond container lifecycle:
# List volumes
docker volume ls

# Inspect volume
docker volume inspect postgres_data

# View volume location
docker volume inspect postgres_data | grep Mountpoint

# Backup volume
docker run --rm -v postgres_data:/data -v $(pwd):/backup \
  alpine tar czf /backup/postgres_data.tar.gz /data

# Restore volume
docker run --rm -v postgres_data:/data -v $(pwd):/backup \
  alpine tar xzf /backup/postgres_data.tar.gz -C /
Deleting a service does not automatically delete its volumes. Clean up unused volumes manually to free disk space.

Bind Mounts

Bind mounts link host filesystem paths directly into containers.

Creating a Bind Mount

{
  type: "bind",
  hostPath: "/opt/dokploy/app-data",
  mountPath: "/app/data",
  serviceType: "application",
  serviceId: "app-456"
}
Share config files across containers:
{
  type: "bind",
  hostPath: "/etc/dokploy/config",
  mountPath: "/app/config"
}

Bind Mount Permissions

Ensure proper permissions on host paths:
# Create directory with correct permissions
sudo mkdir -p /opt/dokploy/app-data
sudo chown -R 1000:1000 /opt/dokploy/app-data
sudo chmod 755 /opt/dokploy/app-data

# For restricted access
sudo chmod 700 /opt/dokploy/app-data
Containers typically run as UID 1000. Mismatched permissions cause access errors.

File Mounts

File mounts inject individual configuration files from Dokploy’s database into containers.

Creating a File Mount

{
  type: "file",
  filePath: "/app/config/production.json",
  content: JSON.stringify({
    database: {
      host: "postgres",
      port: 5432,
      name: "myapp"
    },
    api: {
      port: 8080,
      cors: ["https://example.com"]
    }
  }, null, 2),
  mountPath: "/app/config/production.json",
  serviceType: "application",
  serviceId: "app-789"
}
Application configuration file:
{
  type: "file",
  filePath: "/app/config.json",
  content: JSON.stringify({
    port: 3000,
    env: "production",
    features: {
      auth: true,
      analytics: true
    }
  }, null, 2),
  mountPath: "/app/config.json"
}

File Mount Behavior

File mounts are created as temporary files on the host and mounted into the container. They persist in Dokploy’s database but are regenerated on each deployment.

Use Cases by Service Type

// Persistent uploads
{
  type: "volume",
  volumeName: "app_uploads",
  mountPath: "/app/public/uploads"
}

// Application config
{
  type: "file",
  filePath: "/app/config/production.json",
  content: "{ ... }",
  mountPath: "/app/config/production.json"
}

// Build cache
{
  type: "volume",
  volumeName: "build_cache",
  mountPath: "/app/.next/cache"
}
// Database data
{
  type: "volume",
  volumeName: "postgres_data",
  mountPath: "/var/lib/postgresql/data"
}

// Custom postgresql.conf
{
  type: "file",
  filePath: "/etc/postgresql/postgresql.conf",
  content: `
max_connections = 200
shared_buffers = 256MB
`,
  mountPath: "/etc/postgresql/postgresql.conf"
}

// Backup scripts
{
  type: "bind",
  hostPath: "/opt/backup-scripts",
  mountPath: "/scripts"
}
// Persistent cache
{
  type: "volume",
  volumeName: "redis_data",
  mountPath: "/data"
}

// Custom redis.conf
{
  type: "file",
  filePath: "/usr/local/etc/redis/redis.conf",
  content: `
maxmemory 512mb
maxmemory-policy allkeys-lru
`,
  mountPath: "/usr/local/etc/redis/redis.conf"
}
// Shared data between services
{
  type: "volume",
  volumeName: "shared_data",
  mountPath: "/data",
  serviceType: "compose",
  serviceId: "compose-id"
}

// Service-specific config
{
  type: "file",
  filePath: "/app/service-config.yml",
  content: "... yaml content ...",
  mountPath: "/app/config.yml"
}

Inspecting Container Mounts

View active mounts in a running container:
# List all mounts
docker inspect <container-name> --format '{{json .Mounts}}' | jq

# Check specific mount
docker exec <container-name> ls -la /app/data

# Verify file content
docker exec <container-name> cat /app/config.json

API Query for Mounts

// Get named volumes from running container
POST /api/trpc/mount.allNamedByApplicationId
{
  applicationId: "app-123"
}

// Returns container mounts with type=volume and non-empty source

Best Practices

Use Volumes for Data

Always use named volumes for database data, user uploads, and any data that must persist.

Bind Mounts for Development

Use bind mounts during development for live reloading, but switch to volumes in production.

File Mounts for Secrets

Store sensitive configuration in file mounts rather than environment variables for better security.

Document Mount Requirements

Clearly document which mounts are required and their purpose in your deployment guide.

Volume Naming Convention

Use consistent naming:
// Good: Descriptive names
"postgres_data"
"app_uploads"
"redis_cache"

// Bad: Generic names
"data"
"vol1"
"storage"

Mount Path Best Practices

Always use absolute paths:
// Good
mountPath: "/app/data"

// Bad
mountPath: "data"
mountPath: "./data"

Troubleshooting

Symptoms: Container can’t read/write to mounted pathSolutions:
  1. Check host directory permissions for bind mounts
  2. Verify container runs as expected UID
  3. Use docker exec to check permissions inside container
# Check container user
docker exec <container> id

# Fix host permissions
sudo chown -R 1000:1000 /opt/dokploy/data
Symptoms: Mount path empty or not presentCheck:
  1. Service was restarted after adding mount
  2. Mount configuration saved correctly
  3. No typos in paths
# Verify mount exists
docker inspect <container> --format '{{json .Mounts}}' | jq
Symptoms: File exists but has incorrect contentSolutions:
  1. Update mount content in Dokploy
  2. Restart service to regenerate file
  3. Check for conflicting mounts at same path
# View current file content
docker exec <container> cat /app/config.json
Symptoms: Out of space errorsSolutions:
  1. Check disk usage: df -h
  2. Identify large volumes: docker system df -v
  3. Clean up: docker volume prune
  4. Expand disk or move volumes
# Find volume size
docker system df -v | grep <volume-name>

# Clean unused volumes
docker volume prune -f

API Reference

Manage mounts programmatically:
// Create mount
POST /api/trpc/mount.create
{
  serviceId: "app-123",
  serviceType: "application",
  type: "volume",
  volumeName: "app_data",
  mountPath: "/app/data"
}

// Update mount
POST /api/trpc/mount.update
{
  mountId: "mount-456",
  volumeName: "app_data_v2"
}

// Delete mount
POST /api/trpc/mount.remove
{
  mountId: "mount-456"
}

// List service mounts
POST /api/trpc/mount.listByServiceId
{
  serviceId: "app-123",
  serviceType: "application"
}
Mounts require service restart to take effect. Plan mount changes during maintenance windows.