Learn how to deploy containerized services using uc run with images, ports, environment variables, and volumes
Deploy individual containerized services to your Uncloud cluster using the uc run command. This guide covers running services from container images with various configuration options.
Expose HTTP/HTTPS services via the Caddy reverse proxy:
# Publish port 8000 as HTTPS on app.example.comuc run -p app.example.com:8000/https myapp:latest# Publish port 80 as HTTPuc run -p example.com:80/http nginx# Multiple ports with different hostnamesuc run -p app.example.com:8000/https -p api.example.com:9000/https myapp:latest
Port format: [hostname:]container_port[/protocol]
hostname (optional): Domain name for accessing the service. If omitted and you have a cluster domain, uses <service-name>.<cluster-domain>
container_port: Port the container listens on
protocol (optional): http or https (default: https)
Caddy automatically obtains TLS certificates from Let’s Encrypt for HTTPS endpoints.
Bind ports directly to the host machine for non-HTTP services:
# Bind PostgreSQL port to localhost onlyuc run -p 127.0.0.1:5432:5432@host postgres:16# Bind DNS port on all interfaces (UDP)uc run -p 53:53/udp@host dnsmasq# Custom host portuc run -p 8080:80/tcp@host nginx
Port format: [host_ip:]host_port:container_port[/protocol]@host
host_ip (optional): IP address to bind to. If omitted, binds to all interfaces
host_port: Port on the host machine
container_port: Port inside the container
protocol (optional): tcp or udp (default: tcp)
Do not publish internal services like databases unless absolutely necessary. Services within the cluster can communicate using DNS names without publishing ports.
# Mount volume 'db-data' to /var/lib/postgresql/datauc run -v db-data:/var/lib/postgresql/data postgres:16# Read-only volumeuc run -v config:/etc/app:ro myapp:latest
Named volumes must be created before running the service. They persist even after the container is removed.
# Always pull latest versionuc run --pull always nginx:latest# Never pull, use local image onlyuc run --pull never myapp:local# Pull only if missing (default)uc run --pull missing nginx
service-name: Resolves to all healthy container IPs
service-name.internal: Same as above (explicit internal DNS)
Example:
# Deploy databaseuc run --name postgres -e POSTGRES_PASSWORD=secret postgres:16# Deploy app that connects to database using DNS nameuc run --name app \ -e DATABASE_URL=postgres://user:secret@postgres:5432/mydb \ myapp:latest
The app service connects to postgres using the hostname postgres, which resolves to the database container’s IP.