Skip to main content

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:

Build docs developers (and LLMs) love