Skip to content
Deploying / Accessories

Accessories

Databases and caches Kamal runs alongside the app, with their own lifecycle and backups.

An accessory is a container Kamal runs alongside your app: a database or a cache, from a small catalog. Its generated password and connection URL become secrets the app reads.

The catalog

Kind Image Port Dump and restore
PostgreSQL postgres:18 5432 pg_dump / psql
MySQL mysql:8.4 3306 mysqldump / mysql
Redis redis:8 6379 none
Valkey valkey/valkey:8 6379 none

Caches have no dump command on purpose: an app rebuilds what they hold, and a backup of a cache is a backup of nothing.

Adding one

Environment → Accessories → Add. Pick a kind and a name. KamalCloud fills in the image, the port, the data directory and a health check from the catalog, and generates the passwords the image expects.

The secrets are named after the accessory, so two of a kind in one environment never share. An accessory named after its kind keeps the plain names – postgres gives you POSTGRES_PASSWORD and POSTGRES_URL. Anything else is prefixed: analytics gives you ANALYTICS_POSTGRES_PASSWORD and ANALYTICS_URL.

Where the image documents a name KamalCloud does not store under, Kamal’s CONTAINER_NAME:FILE_NAME form is used so the image keeps the name it documents.

Connecting from your app

The connection URL is a secret on the environment. Its host is the container’s name on the Kamal network, not an address – accessory ports are published on loopback only, so nothing outside the machine can reach them.

The URL is re-derived after every deploy, so renaming the service or changing the password keeps it correct.

Where it runs

An accessory runs on one machine: the one its config names. With several hosts in an environment, that is not necessarily the primary. KamalCloud treats this as a decision rather than a detail, because Kamal only knows the machine the config names – moving an accessory would leave its container and its data behind on the old one.

So the host is picked when the accessory is added and cannot be changed afterwards. To move one, remove it and add it again on the other machine.

Lifecycle

The accessory page has its own controls, separate from deploying the app:

  • Boot / Reboot — one button. The first time it boots the container from its config; after that it recreates it, which is what picks up a changed image or config
  • Start — start a stopped container
  • Stop — stop it, leaving the container and its data in place
  • Restart — stop and start it again, without recreating it
  • Delete — two ways, and you choose:
    • forget it — take it out of the config only. The container and its data are left running on the machine
    • remove it — run kamal accessory remove: container, image and data directory all go, and then the entry and its secrets

Each Kamal action is a deployment of its own kind, with its own log.

Configuration

Beyond the catalog defaults you can set:

  • Clear environment overrides — the user and database names, for instance. The connection URL follows them. These are fixed once the accessory has booted: the image reads them only while creating its data, so changing them later would change the URL and nothing else.
  • A config file — Postgres, MySQL, Redis and Valkey each take one, written into the container at the path that image reads. MySQL’s extends the packaged my.cnf rather than replacing it, so a stanza here cannot cost the image its own defaults.
  • An init script — SQL run on first boot, from the image’s own init directory.
  • CPU and memory limits
  • Health check timings — interval, timeout, retries, start period

Console

Each kind knows how to open its own client – psql, mysql, redis-cli, valkey-cli – with the right credentials already in the environment. See Logs and shell.

Backups

An accessory with a dump command can be backed up on a schedule to one or more buckets, restored from a backup, and downloaded. Postgres and MySQL can; Redis and Valkey cannot.

Importing one

The accessories page reads your repository’s deploy.yml and Dockerfile at the environment’s branch, to show what the app already declares and at which version, and reads the machine to show the state of each accessory’s container live. Adding one can start from what the repository pins rather than the catalog’s image.

An accessory KamalCloud finds during an import keeps the password its container already answers to. Its image and mount come off the container; its user and database are the catalog’s defaults until you set them.