donnfelker/kamal-skills · Archived

servers

Define and structure the servers Kamal deploys to — a simple list of hosts, multiple custom roles (such as web and workers/job hosts), the primary role, tagged hosts, and per-role options. Use when the user says things like "add a workers role," "run background jobs on separate servers," "split web and job servers," "configure multiple servers," "set the primary role," "only some servers should run the proxy," or is editing the `servers:` block in `config/deploy.yml`. Covers the implicit `web` …

First seen Jul 6, 2026

Installation

$ npx skills add donnfelker/kamal-skills --skill servers

Summary

  • Define and structure the servers Kamal deploys to — a simple list of hosts, multiple custom roles (such as web and workers/job hosts), the primary role, tagged hosts, and per-role options.
  • Use when the user says things like "add a workers role," "run background jobs on separate servers," "split web and job servers," "configure multiple servers," "set the primary role," "only some servers should run the proxy," or is editing the `servers:` block in `config/deploy.yml`.
  • Covers the implicit `web` role, role-specific `hosts`, `cmd`, `options`, `logging`, `proxy`, `labels`, `env`, and `asset_path`, plus the root keys `primary_role` and `allow_empty_roles`.
  • For the overall config file, see config.
  • For tuning kamal-proxy, see proxy.
  • For tags and secret/clear env, see env.
  • For rollout order across hosts, see rollout.

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from donnfelker/kamal-skills · top by installs.

npx skills add donnfelker/kamal-skills

Browse all from donnfelker/kamal-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

License LICENSE
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0
More metadata
version
1.0.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 6,453 B
  • docs SUMMARY.md 837 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Servers and Roles

You are an expert in deploying applications with Kamal. Your goal here is to define the servers a deployment targets and split them into roles — web servers, job/worker hosts, and anything else — each configured for its job.

Kamal reads this from the servers: block in config/deploy.yml.

How servers and roles work

  • Servers are split into roles, and each role has its own configuration.
  • For simple deployments where every server is identical, you can skip roles entirely and give a plain list of servers. They are implicitly assigned to the web role.
  • For more complex deployments (for example, running job hosts), you define named roles and configure each one separately.
  • Kamal expects a web role to exist, unless you set a different primary_role in the root configuration.

Before you start

Read what the user already has before asking questions:

  • config/deploy.yml — the existing servers: block, and whether primaryrole or allowempty_roles are already set.
  • .kamal/secrets — if any role will reference secret env variables.

Then confirm: how many servers there are, which ones run the web app, and whether any run a separate workload (background jobs, schedulers, and so on).

Step 1: Start with a simple server list

If all servers are identical, just list them. They all join the web role automatically:

servers:
  - 172.0.0.1
  - 172.0.0.2
  - 172.0.0.3

This is the right starting point for most single-purpose apps.

Step 2: Tag hosts (optional)

Servers can be tagged, and tags are used to attach custom env variables to specific hosts:

servers:
  - 172.0.0.1
  - 172.0.0.2: experiments
  - 172.0.0.3: [ experiments, three ]

A host can carry a single tag or a list of tags. You then map each tag to extra env variables in the top-level env configuration — see the env skill.

Step 3: Split into roles

When some servers do a different job (commonly job/worker hosts), define named roles under servers:. Each role is a key with its own host list:

servers:
  web:
    - 172.1.0.1
    - 172.1.0.2: experiment1
    - 172.1.0.3: [ experiment1, experiment2 ]
  workers:
    - 172.1.0.4
    - 172.1.0.5

The most common split is web servers and job servers. The list form — hosts directly under the role name — is for roles that don't need any custom configuration. You can still tag hosts inside a role.

Step 4: Add per-role options

When a role needs options beyond its hosts, move the host list under a hosts: key and set the options alongside it:

servers:
  web:
    - 172.1.0.1
  workers:
    hosts:
      - 172.1.0.3
      - 172.1.0.4: experiment1
    cmd: "bin/jobs"
    stop_timeout: 30
    options:
      memory: 2g
      cpus: 4
    labels:
      my-label: workers
    asset_path: /public

A custom cmd runs in the container instead of the image default — here the workers role runs bin/jobs. Per-role settings overwrite the matching settings from the root configuration.

Per-role keys

Key Purpose
hosts The role's server list (use this form when the role has other options)
cmd Custom command to run in the container
proxy Enable, disable, or override the proxy for this role (see Step 6)
options Per-role container options, e.g. memory, cpus
logging Per-role Docker logging driver and options
labels Additional labels on the role's containers
env Env variables for this role (tags are not allowed under a role-specific env)
stop_timeout Per-role override of how long to wait for a container to stop
asset_path Asset path for asset bridging on this role

For the full per-role reference and the related root-level keys, see [references/role-options.md](references/role-options.md).

Step 5: Set the primary role

Kamal treats web as the primary role by default. If your deployment has no web role, set primary_role in the root configuration to one of your roles:

primary_role: workers

If you want to allow roles that have no servers, set allowemptyroles (defaults to false):

allow_empty_roles: true

Step 6: Control the proxy per role

By default, only the primary role uses the proxy (kamal-proxy, which runs on ports 80 and 443).

Disable on the primary role — set proxy: false:

servers:
  web:
    hosts:
      - 172.1.0.1
    proxy: false

Enable on a non-primary role — set proxy: true to inherit the root proxy configuration, or provide a map of options to override it:

servers:
  web:
    hosts:
      - 172.1.0.1
  web2:
    hosts:
      - 172.1.0.2
    proxy: true

For tuning kamal-proxy itself (hosts, SSL, healthcheck, ports), see the proxy skill.

Putting it together

A typical web + workers deployment:

service: myapp
image: my-image

servers:
  web:
    - 172.1.0.1
    - 172.1.0.2
  workers:
    hosts:
      - 172.1.0.3
    cmd: "bin/jobs"

The web role serves traffic through the proxy; the workers role runs bin/jobs with no proxy. Add per-role options only where a role actually needs them.

Related Skills

  • config: For the overall config/deploy.yml structure and root-level keys.
  • proxy: For enabling, disabling, and tuning kamal-proxy.
  • env: For mapping host tags to env variables and using secret/clear values.
  • rollout: For controlling how many hosts (and roles) boot at a time during a deploy.