Skip to main content
Configs allow you to mount configuration files into containers without baking them into images. Uncloud supports both file-based and inline configs.

Config types

File-based configs

Read config content from a file on the host:
services:
  web:
    image: nginx
    configs:
      - source: nginx-config
        target: /etc/nginx/nginx.conf
        mode: 0644

configs:
  nginx-config:
    file: ./nginx.conf  # Relative to compose.yaml
References: pkg/api/config.go:14-29

Inline configs

Define config content directly in compose.yaml:
services:
  app:
    image: myapp
    configs:
      - source: app-config
        target: /etc/app/config.json

configs:
  app-config:
    content: |
      {
        "environment": "production",
        "debug": false
      }
References: pkg/api/config.go:17-18

Config declaration

Declare configs at the top level:
configs:
  # File-based
  nginx-config:
    file: ./configs/nginx.conf
  
  # Inline
  app-settings:
    content: |
      key=value
      debug=false
Config files are read from the machine where you run uc deploy, not from target machines.

Mounting configs

Mount configs into containers using long syntax:
services:
  web:
    image: nginx
    configs:
      - source: nginx-config      # References config name
        target: /etc/nginx/nginx.conf  # Path in container
        mode: 0644                # File permissions (octal)
        uid: "101"                # File owner UID
        gid: "101"                # File group GID
Mount options:
  • source - Config name (required)
  • target - Absolute path in container (required)
  • mode - File permissions in octal (default: 0444 read-only)
  • uid - File owner user ID
  • gid - File group ID
References: pkg/api/config.go:45-100

Short syntax

Short syntax is not supported in Uncloud. Always use the long syntax shown above.

File permissions

Control config file permissions inside containers:
services:
  app:
    image: myapp
    configs:
      # Read-only for all users
      - source: public-config
        target: /etc/app/public.conf
        mode: 0444
      
      # Read-write for owner only
      - source: private-config
        target: /etc/app/private.conf
        mode: 0600
        uid: "1000"
        gid: "1000"

configs:
  public-config:
    content: "public data"
  private-config:
    content: "secret data"
References: pkg/api/config.go:54-56

User and group ownership

Set the owner of config files:
services:
  app:
    image: myapp
    user: "1000:1000"  # Container runs as this user
    configs:
      - source: app-config
        target: /etc/app/config.yaml
        uid: "1000"      # Match container user
        gid: "1000"      # Match container group
        mode: 0600

configs:
  app-config:
    file: ./config.yaml
uid and gid must be numeric strings, not usernames.
References: pkg/api/config.go:50-84

Creating directories

Configs can be mounted into non-existent directories:
services:
  app:
    image: myapp
    configs:
      # Uncloud creates /etc/app/subdir if needed
      - source: nested-config
        target: /etc/app/subdir/config.conf
        mode: 0644

configs:
  nested-config:
    content: "config data"
References: test/e2e/fixtures/compose-configs.yaml:14-17

Multiple configs

Mount multiple configs into the same service:
services:
  web:
    image: nginx
    configs:
      - source: nginx-main
        target: /etc/nginx/nginx.conf
      - source: nginx-site
        target: /etc/nginx/conf.d/default.conf
      - source: ssl-cert
        target: /etc/nginx/ssl/cert.pem
        mode: 0444
      - source: ssl-key
        target: /etc/nginx/ssl/key.pem
        mode: 0400

configs:
  nginx-main:
    file: ./nginx/nginx.conf
  nginx-site:
    file: ./nginx/site.conf
  ssl-cert:
    file: ./ssl/cert.pem
  ssl-key:
    file: ./ssl/key.pem

Sharing configs

Multiple services can use the same config:
services:
  web1:
    image: nginx
    configs:
      - source: shared-config
        target: /etc/app/config.conf

  web2:
    image: nginx
    configs:
      - source: shared-config
        target: /etc/app/config.conf

configs:
  shared-config:
    file: ./shared.conf

Common patterns

Application configuration

services:
  app:
    image: myapp
    configs:
      - source: app-config
        target: /etc/app/config.yaml
        mode: 0644

configs:
  app-config:
    file: ./config/production.yaml

Web server configuration

services:
  nginx:
    image: nginx:alpine
    configs:
      - source: nginx-conf
        target: /etc/nginx/nginx.conf
      - source: site-conf
        target: /etc/nginx/conf.d/default.conf

configs:
  nginx-conf:
    file: ./nginx/nginx.conf
  site-conf:
    file: ./nginx/site.conf

Database initialization

services:
  db:
    image: postgres:16
    configs:
      - source: db-init
        target: /docker-entrypoint-initdb.d/init.sql
        mode: 0644
    environment:
      - POSTGRES_PASSWORD=secret

configs:
  db-init:
    content: |
      CREATE DATABASE myapp;
      CREATE USER appuser WITH PASSWORD 'secret';
      GRANT ALL PRIVILEGES ON DATABASE myapp TO appuser;

Credentials and secrets

services:
  app:
    image: myapp
    configs:
      - source: api-key
        target: /run/secrets/api-key
        mode: 0400  # Read-only for owner
        uid: "1000"
        gid: "1000"
    user: "1000:1000"

configs:
  api-key:
    file: ./secrets/api-key.txt
Uncloud does not support Docker Swarm secrets. Use configs with restricted permissions for sensitive data, or use environment variables.

Limitations

External configs not supported

Uncloud does not support external configs:
configs:
  external-config:
    external: true  # Not supported
All configs must be defined with file or content. References: pkg/api/config.go:21-22

Short syntax not supported

You must use long syntax for config mounts:
# Not supported
services:
  app:
    configs:
      - my-config

# Supported
services:
  app:
    configs:
      - source: my-config
        target: /etc/app/config
References: website/docs/8-compose-file-reference/1-support-matrix.md:64

Complete example

services:
  web:
    image: nginx:alpine
    configs:
      # Main nginx configuration
      - source: nginx-config
        target: /etc/nginx/nginx.conf
        mode: 0644
      
      # Site configuration
      - source: site-config
        target: /etc/nginx/conf.d/default.conf
        mode: 0644
      
      # SSL certificate
      - source: ssl-cert
        target: /etc/nginx/ssl/cert.pem
        mode: 0444
      
      # SSL private key (restricted permissions)
      - source: ssl-key
        target: /etc/nginx/ssl/key.pem
        mode: 0400
        uid: "101"  # nginx user
        gid: "101"  # nginx group
    x-ports:
      - example.com:443/https

  app:
    image: myapp:latest
    configs:
      # Application settings
      - source: app-settings
        target: /etc/app/settings.json
        mode: 0644
      
      # Database credentials
      - source: db-credentials
        target: /run/secrets/db-creds
        mode: 0400
        uid: "1000"
        gid: "1000"
    user: "1000:1000"
    environment:
      - CONFIG_PATH=/etc/app/settings.json
      - DB_CREDS_PATH=/run/secrets/db-creds

configs:
  # File-based configs
  nginx-config:
    file: ./configs/nginx.conf
  site-config:
    file: ./configs/site.conf
  ssl-cert:
    file: ./ssl/cert.pem
  ssl-key:
    file: ./ssl/key.pem
  
  # Inline configs
  app-settings:
    content: |
      {
        "environment": "production",
        "log_level": "info",
        "features": {
          "auth": true,
          "debug": false
        }
      }
  
  db-credentials:
    content: |
      host=db
      port=5432
      database=myapp
      user=appuser
      password=secret

Build docs developers (and LLMs) love