Deploy Pre-built Images
Deploy applications using pre-built images from Docker Hub, GitHub Container Registry, or private registries. Skip the build step entirely.
When to Use Pre-built Images
- Deploying public applications (nginx, PostgreSQL, Redis)
- Using images built in CI/CD pipelines
- Deploying third-party services
- Images built externally or by another team
Public Images from Docker Hub
Single Service
Deploy a simple web server:
services:
web:
image: nginx:alpine
x-ports:
- www.example.com:80/https
uc deploy
That's it! No build step needed. Uncloud pulls the image directly from Docker Hub to your cluster machines.
Multiple Public Services
Deploy a complete application stack:
services:
web:
image: nginx:alpine
x-ports:
- www.example.com:80/https
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
db:
image: postgres:16-alpine
volumes:
- db-data:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_PASSWORD: ${DB_PASSWORD}
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
volumes:
db-data:
redis-data:
uc deploy
Images from Other Registries
GitHub Container Registry
Use images from GitHub:
services:
app:
image: ghcr.io/username/myapp:v1.2.3
x-ports:
- app.example.com:8000/https
Docker Hub with Username
Specify Docker Hub username explicitly:
services:
app:
image: username/myapp:latest
Custom Registry
Use any Docker registry:
services:
app:
image: registry.example.com/myapp:v2.0.0
Private Registries
Authenticate with Registry
Configure Docker authentication on your local machine:
# Docker Hub
docker login
# GitHub Container Registry
echo $GITHUB_TOKEN | docker login ghcr.io -u username --password-stdin
# Custom registry
docker login registry.example.com
Uncloud uses your local Docker credentials when pulling images.
Deploy from Private Registry
services:
app:
image: registry.example.com/private/myapp:latest
x-ports:
- app.example.com:8000/https
uc deploy
Note: Cluster machines must have access to the private registry. You can configure Docker credentials on each machine or use registry tokens.
Specific Image Versions
Semantic Versioning
Pin to specific versions for production:
services:
app:
image: myapp:1.2.3 # Specific version
db:
image: postgres:16.2-alpine # Specific minor version
redis:
image: redis:7-alpine # Major version with auto-updates
Tags and Digests
Use SHA256 digests for immutable deployments:
services:
app:
image: myapp@sha256:abcd1234... # Immutable reference
Get image digest:
docker pull myapp:1.2.3
docker inspect myapp:1.2.3 | grep Digest
Mixing Pre-built and Custom Images
Combine pre-built images with custom builds:
services:
# Custom application (built from source)
app:
build: .
image: myapp:latest
x-ports:
- app.example.com:8000/https
depends_on:
- db
- redis
# Pre-built database
db:
image: postgres:16-alpine
volumes:
- db-data:/var/lib/postgresql/data
# Pre-built cache
redis:
image: redis:7-alpine
volumes:
db-data:
Update Pre-built Services
Update to New Version
Change the image tag in compose.yaml:
services:
app:
image: myapp:1.2.4 # Updated from 1.2.3
Deploy the update:
uc deploy
Uncloud will:
- Pull the new image to cluster machines
- Create new containers with zero downtime
- Remove old containers
Pull Latest Version
If using :latest tag, force pull new image:
uc deploy --pull
This ensures the newest version is pulled even if :latest already exists on cluster machines.
Common Patterns
Development vs Production Images
Use environment-specific images:
services:
app:
image: myapp:${ENV_TAG:-dev} # Defaults to 'dev'
x-ports:
- app.example.com:8000/https
Deploy to production:
ENV_TAG=v1.2.3 uc deploy
Multi-architecture Images
Use multi-arch images for clusters with mixed CPU architectures:
services:
app:
image: myapp:latest # Must be multi-arch image
platform: linux/amd64 # Optional: force specific platform
Build multi-arch images:
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
Sidecar Patterns
Deploy application with sidecars:
services:
app:
image: myapp:latest
x-ports:
- app.example.com:8000/https
prometheus-exporter:
image: prom/node-exporter:latest
x-ports:
- metrics.example.com:9100/https
log-forwarder:
image: fluent/fluent-bit:latest
volumes:
- /var/log:/var/log:ro
Configuration Management
Environment Variables
Configure services with environment variables:
services:
app:
image: myapp:latest
environment:
DATABASE_URL: postgres://db:5432/myapp
REDIS_URL: redis://redis:6379
LOG_LEVEL: info
Config Files
Mount configuration files:
services:
nginx:
image: nginx:alpine
x-ports:
- www.example.com:80/https
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html:ro
Secrets
Pass secrets via environment variables:
services:
app:
image: myapp:latest
environment:
API_KEY: ${API_KEY}
DB_PASSWORD: ${DB_PASSWORD}
Load from .env file:
# .env
API_KEY=secret123
DB_PASSWORD=pass456
uc deploy
Troubleshooting
Image Pull Failures
If image pull fails:
Error: failed to pull image: repository not found
Check:
- Image name and tag are correct
- Image exists in the registry
- You're authenticated (for private images)
Test locally:
docker pull myapp:latest
Authentication Issues
For private registries:
Error: pull access denied
Ensure Docker is authenticated:
docker login registry.example.com
Verify credentials are saved:
cat ~/.docker/config.json
Wrong Architecture
If you see:
Error: exec format error
The image architecture doesn't match your machine. Use multi-arch images or specify platform:
services:
app:
image: myapp:latest
platform: linux/amd64
Image Updates Not Applied
If deploying :latest but not seeing updates:
# Force pull new image
uc deploy --pull
Or use specific version tags instead of :latest.
Next Steps
- Updating Services - Learn update strategies and rollback
- Building Images - Build your own images
- Pushing Images - Push to registries and cluster