Overview
Dokploy supports connecting to Docker container registries to pull base images and push built application images. Configure multiple registries for different purposes.
Registry Types
Dokploy supports two types of container registries:
Registry type
cloud - Cloud-hosted registry (Docker Hub, GitHub Container Registry, etc.)
selfHosted - Self-hosted registry
Configuration
Basic Settings
Display name for the registry
Registry URL # Docker Hub
https://index.docker.io/v1/
# GitHub Container Registry
ghcr.io
# Google Container Registry
gcr.io
# Self-hosted
registry.example.com:5000
Registry username or access key # Docker Hub
dockerhubuser
# GitHub Container Registry
github-username
# AWS ECR
AWS
Registry password, access token, or secret Store passwords securely. Never commit them to version control.
Prefix for image names (useful for namespacing) # Docker Hub namespace
mycompany/
# GitHub Container Registry
ghcr.io/myorg/
# AWS ECR
123456789.dkr.ecr.us-east-1.amazonaws.com/
Popular Registries
Docker Hub
The default public container registry.
curl -X POST https://your-domain.com/api/trpc/registry.create \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryName": "Docker Hub",
"registryUrl": "https://index.docker.io/v1/",
"username": "dockerhubuser",
"password": "dockerhub-token",
"registryType": "cloud",
"imagePrefix": "mycompany/"
}'
Creating Docker Hub Token
Log in to Docker Hub
Go to Account Settings > Security
Click “New Access Token”
Give it a description and set permissions
Copy the token (shown only once)
GitHub Container Registry (GHCR)
Store container images alongside your GitHub repositories.
curl -X POST https://your-domain.com/api/trpc/registry.create \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryName": "GitHub Container Registry",
"registryUrl": "ghcr.io",
"username": "github-username",
"password": "ghp_xxxxxxxxxxxxxxxxxxxx",
"registryType": "cloud",
"imagePrefix": "ghcr.io/myorg/"
}'
Creating GitHub Token
Go to GitHub Settings > Developer settings > Personal access tokens
Generate new token (classic)
Select scopes:
write:packages - Upload packages
read:packages - Download packages
delete:packages - Delete packages (optional)
Copy the token
AWS Elastic Container Registry (ECR)
Amazon’s container registry service.
# First, get authentication token
aws ecr get-login-password --region us-east-1
# Then create registry
curl -X POST https://your-domain.com/api/trpc/registry.create \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryName": "AWS ECR",
"registryUrl": "123456789.dkr.ecr.us-east-1.amazonaws.com",
"username": "AWS",
"password": "<ecr-token>",
"registryType": "cloud",
"imagePrefix": "123456789.dkr.ecr.us-east-1.amazonaws.com/"
}'
AWS ECR tokens expire after 12 hours. Consider using an IAM role or automated token refresh.
Google Container Registry (GCR)
Google Cloud’s container registry.
curl -X POST https://your-domain.com/api/trpc/registry.create \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryName": "Google Container Registry",
"registryUrl": "gcr.io",
"username": "_json_key",
"password": "<service-account-json>",
"registryType": "cloud",
"imagePrefix": "gcr.io/my-project/"
}'
Azure Container Registry (ACR)
Microsoft Azure’s container registry.
curl -X POST https://your-domain.com/api/trpc/registry.create \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryName": "Azure Container Registry",
"registryUrl": "myregistry.azurecr.io",
"username": "myregistry",
"password": "<acr-password>",
"registryType": "cloud"
}'
Self-Hosted Registry
Connect to your own Docker registry.
curl -X POST https://your-domain.com/api/trpc/registry.create \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryName": "Self-Hosted Registry",
"registryUrl": "registry.example.com:5000",
"username": "admin",
"password": "registry-password",
"registryType": "selfHosted"
}'
Testing Registry Connection
Before using a registry, test the connection:
Test Before Creating
curl -X POST https://your-domain.com/api/trpc/registry.testRegistry \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryUrl": "ghcr.io",
"username": "github-user",
"password": "ghp_xxxxxxxxxxxx",
"registryType": "cloud"
}'
Test Existing Registry
curl -X POST https://your-domain.com/api/trpc/registry.testRegistryById \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryId": "registry-123"
}'
Successful test response:
Managing Registries
List All Registries
curl https://your-domain.com/api/trpc/registry.all \
-H "x-api-key: your-api-key"
Response:
[
{
"registryId" : "registry-123" ,
"registryName" : "Docker Hub" ,
"registryUrl" : "https://index.docker.io/v1/" ,
"username" : "dockerhubuser" ,
"imagePrefix" : "mycompany/" ,
"registryType" : "cloud" ,
"createdAt" : "2024-01-15T10:30:00.000Z" ,
"organizationId" : "org-123"
}
]
Passwords are not returned in list responses for security.
Get Single Registry
curl https://your-domain.com/api/trpc/registry.one \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"registryId": "registry-123"}'
Update Registry
curl -X POST https://your-domain.com/api/trpc/registry.update \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryId": "registry-123",
"registryName": "Docker Hub Production",
"username": "newusername",
"password": "newpassword"
}'
Delete Registry
curl -X POST https://your-domain.com/api/trpc/registry.remove \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"registryId": "registry-123"}'
Deleting a registry may affect applications that use it for pulling base images or pushing built images.
Using Registries
For Pulling Images
When deploying applications, Dokploy can pull base images from configured registries:
# docker-compose.yml
services :
app :
image : mycompany/myapp:latest # Pulled from Docker Hub registry
For Pushing Built Images
After building an application, Dokploy can push the image to a registry:
{
"applicationId" : "app-123" ,
"buildRegistryId" : "registry-123" , // Registry to push to
"registryId" : "registry-456" // Registry to pull from
}
Rollback Registry
Store previous image versions for rollbacks:
{
"applicationId" : "app-123" ,
"rollbackRegistryId" : "registry-789" // Registry for rollback images
}
Server-Specific Registries
For multi-server deployments, specify which server to test against:
curl -X POST https://your-domain.com/api/trpc/registry.testRegistry \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"registryUrl": "registry.example.com",
"username": "admin",
"password": "password",
"serverId": "server-123"
}'
Authentication Methods
Username/Password
Basic authentication with username and password:
docker login registry.example.com -u username -p password
Access Tokens
Many registries use personal access tokens:
# Docker Hub
docker login -u username -p dckr_pat_xxxxxxxxxxxx
# GitHub
docker login ghcr.io -u username -p ghp_xxxxxxxxxxxx
Service Accounts
Cloud providers often use JSON key files:
# GCR with service account
cat keyfile.json | docker login -u _json_key --password-stdin gcr.io
Security Best Practices
Credential Management
Rotate Regularly : Change registry passwords every 90 days
Least Privilege : Grant only necessary permissions
Separate Credentials : Use different credentials for dev/prod
Token Expiration : Use short-lived tokens when possible
Registry Security
Private Registries : Use private registries for proprietary images
Image Scanning : Enable vulnerability scanning
Image Signing : Sign images for authenticity
Access Logs : Monitor registry access logs
Network Security
HTTPS Only : Always use HTTPS for registry URLs
VPC/Private Network : Use private networks when possible
Firewall Rules : Restrict registry access by IP
Rate Limiting : Implement rate limits to prevent abuse
Troubleshooting
Connection Issues
Verify username and password are correct
Check if credentials have expired
Ensure registry URL is correct
Confirm registry is accessible from server
Verify write permissions
Check disk space on server
Ensure image name matches registry prefix
Confirm network connectivity
Verify read permissions
Check if image exists in registry
Ensure correct image name and tag
Confirm credentials are valid
Common Errors
# Error: unauthorized
# Solution: Check credentials are correct and have proper permissions
# Error: dial tcp: lookup registry.example.com: no such host
# Solution: Verify registry URL is correct and DNS is working
# Error: x509: certificate signed by unknown authority
# Solution: Add registry's CA certificate to trusted certificates
Database Schema
Registry configuration is stored in the registry table:
{
registryId : string ; // Unique identifier
registryName : string ; // Display name
imagePrefix : string ; // Optional prefix for images
username : string ; // Registry username
password : string ; // Registry password (encrypted)
registryUrl : string ; // Registry URL
createdAt : string ; // Creation timestamp
registryType : "cloud" | "selfHosted" ;
organizationId : string ; // Owner organization
}
API Reference
Endpoint Method Description /api/trpc/registry.createPOST Create new registry /api/trpc/registry.allGET List all registries /api/trpc/registry.oneGET Get single registry /api/trpc/registry.updatePOST Update registry /api/trpc/registry.removePOST Delete registry /api/trpc/registry.testRegistryPOST Test connection /api/trpc/registry.testRegistryByIdPOST Test existing registry
Example: Complete Workflow
// 1. Create registry
const registry = await fetch ( 'https://dokploy.example.com/api/trpc/registry.create' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'x-api-key' : process . env . API_KEY
},
body: JSON . stringify ({
registryName: 'Docker Hub Production' ,
registryUrl: 'https://index.docker.io/v1/' ,
username: 'mycompany' ,
password: process . env . DOCKER_HUB_TOKEN ,
registryType: 'cloud' ,
imagePrefix: 'mycompany/'
})
});
// 2. Test registry
await fetch ( 'https://dokploy.example.com/api/trpc/registry.testRegistryById' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'x-api-key' : process . env . API_KEY
},
body: JSON . stringify ({
registryId: registry . registryId
})
});
// 3. Use in application
await createApplication ({
name: 'My App' ,
registryId: registry . registryId , // Pull from this registry
buildRegistryId: registry . registryId , // Push to this registry
// ... other config
});
// 4. Build and push
await deployApplication ( 'app-123' );
// Image is built and pushed to mycompany/my-app:latest