Updating Services
Learn how to update running services with zero downtime, rollback changes, and handle different update scenarios.
Basic Update Workflow
The standard update process is simple:
# Make changes to your code or compose.yaml
vim src/app.py
# Deploy updates
uc deploy
Uncloud automatically:
- Rebuilds changed services (if using
build) - Creates new containers
- Waits for new containers to be healthy
- Switches traffic
- Removes old containers
Zero downtime guaranteed for services with multiple replicas.
Update Strategies
Rolling Updates (Default)
Uncloud uses rolling updates by default. New containers are created before old ones are removed:
services:
web:
build: .
deploy:
replicas: 3
uc deploy
Update sequence:
- Create web-4 (new version)
- Wait for web-4 to be healthy
- Remove web-1 (old version)
- Create web-5
- Remove web-2
- Create web-6
- Remove web-3
Traffic is always served during updates.
Force Recreate
Force recreation of all containers even if configuration hasn't changed:
uc deploy --recreate
When to use:
- Configuration changed outside of compose.yaml
- Container is in an unhealthy state
- You want to pull the latest
:latestimage
Update Specific Services
Update only changed services:
# Update only web service
uc deploy web
# Update web and API
uc deploy web api
Other services remain untouched.
Code Updates
Update Application Code
# Edit your code
vim src/handler.py
# Deploy the updated code
uc deploy
Uncloud rebuilds the image with your changes and deploys it.
Skip Rebuild
If you've already built the image separately:
# Build image
uc build
# Deploy without rebuilding
uc deploy --no-build
Configuration Updates
Update Environment Variables
Change environment variables in compose.yaml:
services:
web:
image: myapp:latest
environment:
LOG_LEVEL: debug # Changed from 'info'
NEW_FEATURE: enabled # Added new variable
uc deploy
Containers are recreated with new environment variables.
Update Resource Limits
services:
web:
image: myapp:latest
deploy:
resources:
limits:
cpus: '2' # Increased from '1'
memory: 2G # Increased from 1G
uc deploy
Update Ports
services:
web:
image: myapp:latest
x-ports:
- app.example.com:8000/https
- www.app.example.com:8000/https # Added new domain
uc deploy
Caddy configuration is updated automatically.
Scaling Updates
Scale Replicas
Increase or decrease the number of replicas:
services:
web:
image: myapp:latest
deploy:
replicas: 5 # Scaled from 3
uc deploy
Or use the dedicated scale command:
uc scale web 5
Scale Down
Reduce replicas:
uc scale web 1
Excess containers are removed gracefully.
Image Updates
Update Image Version
Change the image tag in compose.yaml:
services:
web:
image: myapp:v1.2.4 # Updated from v1.2.3
uc deploy
Update from Registry
For pre-built images, ensure new version is pulled:
uc deploy --pull
Forces pulling the latest image from the registry even if a local version exists.
Rollback Strategies
Rollback to Previous Version
If you need to rollback:
Option 1: Change image tag
services:
web:
image: myapp:v1.2.3 # Back to previous version
uc deploy
Option 2: Revert code and rebuild
# Revert to previous commit
git revert HEAD
# Rebuild and deploy
uc deploy
Option 3: Deploy old image directly
# List services to see old images
uc ps
# Update compose.yaml to use old image tag
# Then deploy
uc deploy
Keep Previous Images
Tag images with versions for easy rollback:
services:
web:
build: .
image: myapp:${VERSION:-latest}
# Deploy version 1.2.4
VERSION=v1.2.4 uc deploy
# Rollback to 1.2.3
VERSION=v1.2.3 uc deploy
Health Checks and Updates
Define Health Checks
Add health checks to ensure safe updates:
services:
web:
image: myapp:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
During updates, Uncloud waits for health checks to pass before switching traffic.
Update with Health Check Failures
If new containers fail health checks:
- Old containers keep running
- New containers are marked unhealthy
- Traffic stays on old containers
- Check logs:
docker logs <container-id> - Fix the issue and redeploy
Volume Updates
Update Volume Mounts
Add or change volume mounts:
services:
web:
image: myapp:latest
volumes:
- ./data:/app/data
- ./logs:/app/logs # Added new volume
uc deploy
Note: Containers are recreated when volumes change.
Persistent Data
Data in named volumes persists across updates:
services:
db:
image: postgres:16
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data: # Data survives container updates
Updating the db service doesn't affect data in db-data volume.
Compose File Updates
Update compose.yaml Structure
You can freely update your compose.yaml:
- Add new services
- Remove services
- Rename services (creates new service, old one stays)
- Change service dependencies
services:
web:
image: myapp:latest
# Added new service
worker:
image: myapp:latest
command: python -m celery worker
uc deploy
New services are created, existing services are updated if changed.
Remove Services
To remove a service, delete it from compose.yaml and use uc rm:
# Remove from compose.yaml
# Then remove from cluster
uc rm old-service
Update Automation
Automated Updates
For production deployments:
# Non-interactive deployment
uc deploy --yes
Or set environment variable:
export UNCLOUD_AUTO_CONFIRM=true
uc deploy
Pre-deployment Checks
Preview changes before applying:
# Shows deployment plan without executing
uc deploy
# Review the plan
# Type 'yes' to proceed or 'no' to cancel
Multi-service Updates
Update All Services
# Make changes to multiple services
vim frontend/src/app.js
vim api/src/handler.py
# Deploy all changes
uc deploy
Both services are rebuilt and updated.
Sequential Updates
Update services one at a time:
# Update database first
uc deploy db
# Then update API
uc deploy api
# Finally update frontend
uc deploy frontend
Dependency-aware Updates
Update with dependencies:
# Update API and all its dependencies
uc deploy api --deps
Troubleshooting Updates
Update Stuck or Slow
If updates seem slow:
- Check build progress (if building)
- Check image push progress
- Check container health:
docker ps - Review logs:
docker logs <container-id>
Containers Not Starting
Check container logs:
# List containers
uc ps
# View logs
docker logs <container-id>
Common issues:
- Port conflicts
- Missing environment variables
- Configuration errors
- Failed health checks
Old Containers Still Running
Verify the deployment completed:
uc ps
Look for containers with old image tags or older creation times.
Force cleanup:
uc deploy --recreate
Changes Not Reflected
Ensure you're rebuilding:
# Force rebuild without cache
uc build --no-cache
# Deploy
uc deploy
Or combine:
uc deploy --no-cache
Best Practices
- Tag images with versions for easy rollback
- Use health checks to ensure safe updates
- Test in staging before production updates
- Keep old images for quick rollback
- Update one service at a time for complex apps
- Monitor logs during updates
- Use replicas > 1 for zero-downtime updates
Next Steps
- Building Images - Learn when to use separate build step
- Build Options - Optimize rebuilds with caching
- Deploy from Dockerfile - Learn the basics of building and deploying