Documentation Index
Fetch the complete documentation index at: https://mintlify.com/psviderski/uncloud/llms.txt
Use this file to discover all available pages before exploring further.
The services section defines the containers that make up your application. Each service runs one or more containers across your cluster.
Service definition
A basic service requires at minimum an image:
services:
web:
image: nginx:alpine
Image and build
Using an image
Specify a container image from a registry:
services:
web:
image: nginx:1.25-alpine
pull_policy: always # always, missing, or never
Pull policies:
always - Always pull the image from the registry
missing - Pull only if not available locally (default)
never - Never pull, use only local images
Building images
Build images from source during deployment:
services:
api:
build:
context: ./api
dockerfile: Dockerfile
args:
- VERSION=1.0
References: pkg/client/compose/service.go:18-145
Command and entrypoint
Override the image’s default command and entrypoint:
services:
worker:
image: python:3.11
entrypoint: ["/usr/local/bin/python"]
command: ["worker.py", "--mode", "production"]
Environment variables
Set environment variables for containers:
services:
app:
image: myapp
environment:
- NODE_ENV=production
- API_KEY=secret
- DEBUG=false
env_file:
- .env
- .env.production
Variables in env_file are read from the local filesystem where you run uc deploy.
References: pkg/api/service.go:249-250, pkg/client/compose/service.go:36-44
Ports and networking
HTTP/HTTPS ports with x-ports
Publish HTTP/HTTPS services via Uncloud’s Caddy reverse proxy:
services:
web:
image: nginx
x-ports:
# HTTPS with automatic TLS
- example.com:80/https
# HTTP without TLS
- 8080:80/http
# Just container port (uses cluster domain)
- 80/https
Format: [hostname:][published_port:]container_port/protocol
When you specify a hostname, Uncloud automatically obtains a TLS certificate via Let’s Encrypt.
TCP/UDP ports with host mode
Bind TCP/UDP ports directly to host machines:
services:
database:
image: postgres:16
x-ports:
- 5432:5432/tcp@host
- 0.0.0.0:5432:5432/tcp@host # Bind to specific IP
Format: [host_ip:]host_port:container_port/protocol@host
Custom Caddy configuration
For advanced routing, use x-caddy instead of x-ports:
services:
app:
image: myapp
x-caddy: |
app.example.com {
reverse_proxy {{ upstreams 8080 }}
# Custom path routing
handle /api/* {
reverse_proxy {{ upstreams 8081 }}
}
}
x-ports and x-caddy are mutually exclusive for ingress ports. You can use host mode ports (@host) with either.
References: pkg/api/port.go:20-82, pkg/api/service.go:55-70
Volumes
Mount volumes into containers:
services:
app:
image: myapp
volumes:
# Named volume
- app-data:/data
# Bind mount (read-only)
- ./config.json:/etc/app/config.json:ro
# Long syntax with options
- type: volume
source: app-data
target: /data
volume:
nocopy: true
# Tmpfs (in-memory)
- type: tmpfs
target: /tmp
tmpfs:
size: 10485760 # 10MB
volumes:
app-data:
See Volumes for detailed volume configuration.
References: pkg/client/compose/service.go:257-293
Configs
Mount configuration files into containers:
services:
web:
image: nginx
configs:
- source: nginx-config
target: /etc/nginx/nginx.conf
mode: 0644
configs:
nginx-config:
file: ./nginx.conf
See Configs for details.
Health checks
Define container health checks:
services:
api:
image: myapi
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
start_interval: 5s
Health check options:
test - Command to run (formats: ["CMD", args...] or ["CMD-SHELL", "command"])
interval - Time between checks (default: 30s)
timeout - How long to wait for check
retries - Consecutive failures before unhealthy
start_period - Grace period before retries count
start_interval - Interval during start period
References: pkg/api/service.go:414-432, pkg/client/compose/service.go:147-173
Capabilities
Add or drop Linux capabilities:
services:
net-admin:
image: myapp
cap_add:
- NET_ADMIN
- SYS_TIME
cap_drop:
- ALL
References: pkg/api/service.go:241-243
User
Run containers as a specific user:
services:
app:
image: myapp
user: "1000:1000" # user:group or UID:GID
References: pkg/api/service.go:269
Privileged mode
Run containers with extended privileges:
services:
docker:
image: docker:dind
privileged: true
Privileged mode is a security risk. Only use when absolutely necessary.
References: pkg/api/service.go:260
Init process
Run an init process inside the container:
services:
app:
image: myapp
init: true
References: pkg/api/service.go:256
Logging
Configure container logging:
services:
app:
image: myapp
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
Default driver is local if not specified.
References: pkg/api/service.go:257-258
Sysctls
Set namespaced kernel parameters:
services:
app:
image: myapp
sysctls:
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
References: pkg/api/service.go:266-267
Devices
Mount host devices into containers:
services:
usb-app:
image: myapp
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0:rw"
- "/dev/sda:/dev/xvda"
References: pkg/client/compose/service.go:186-196
GPUs
Access GPU devices:
services:
ml-worker:
image: tensorflow/tensorflow:latest-gpu
gpus: all
Or for specific GPUs:
services:
ml-worker:
image: ml-app
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
References: pkg/client/compose/service.go:204-226
Stop grace period
Configure how long to wait after SIGTERM before SIGKILL:
services:
app:
image: myapp
stop_grace_period: 30s
Default is 10 seconds.
References: pkg/api/service.go:72-74
Deploy section
Configure deployment behavior:
services:
web:
image: nginx
deploy:
mode: replicated
replicas: 3
update_config:
order: start-first
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
memory: 256M
See Deploy for complete deployment configuration.
Complete example
services:
web:
image: nginx:alpine
x-ports:
- example.com:80/https
volumes:
- web-content:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/nginx.conf:ro
environment:
- BACKEND_URL=http://api:8080
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost"]
interval: 30s
timeout: 5s
retries: 3
deploy:
replicas: 2
update_config:
order: start-first
resources:
limits:
cpus: '0.25'
memory: 128M
api:
build: ./api
environment:
- DATABASE_URL=postgres://db:5432/myapp
volumes:
- api-logs:/var/log/api
user: "1000:1000"
deploy:
replicas: 3
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
memory: 512M
db:
image: postgres:16
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=myapp
- POSTGRES_PASSWORD=secret
stop_grace_period: 60s
deploy:
replicas: 1
volumes:
web-content:
api-logs:
db-data: