Notes to self

Running multiple apps on a single server with Kamal 2

Kamal 2 finally brings the most requested feature to reality and allows people to run multiple applications simultaneously on a single server. Here’s how.

The Kamal way

Kamal is an application-centric deploy tool rather than a small PaaS. And this hasn’t changed with the new version 2. But what does it even mean?

Let’s look at a typical config/deploy.yml to run a generic application:

# config/deploy.yml
service: [APP_NAME]

image: [DOCKER_REGISTRY]/[APP_NAME]

servers:
  web:
    - 165.22.71.211
  job:
    hosts:
      - 165.22.71.211
    cmd: bin/jobs

proxy:
  ssl: true
  host: [APP_DOMAIN]

registry:
  username: [DOCKER_REGISTRY]

  # Always use an access token rather than real password when possible.
  password:
    - KAMAL_REGISTRY_PASSWORD

env:
  ...

As you can notice the configuration describes only one particular service. And this hasn’t changed. Applications still have their own configuration. The only thing that changed is the possibility to share their servers.

Kamal Proxy

Kamal 2 adds support for multiple apps with the new Kamal Proxy. The new proxy registers new deployments for services and handles their gapless switchover.

The only thing Kamal Proxy needs to know is the host (domain) of the service so it can route the traffic to the service web containers. This is done with the following Kamal configuration:

# config/deploy.yml
...

proxy:
  ssl: true
  host: [APP_DOMAIN]

The extra ssl option let’s us also request automatic SSL/TLS certificates via Let’s Encrypt.

There will only be one instance of Kamal Proxy running on a given server, installed by the first deployed application.

Multiple apps

Let’s say we want to deploy three different application on the same server for a local dealership. The main app, API server, and their marketing website. Then we need three different configurations, one for each app.

The main app will run on app.dealership.com:

# dealership/config/deploy.yml
service: dealership

image: [DOCKER_REGISTRY]/dealership

servers:
  web:
    - 165.22.71.211
  job:
    hosts:
      - 165.22.71.211
    cmd: bin/jobs

proxy:
  ssl: true
  host: app.dealership.com

registry:
  ...

env:
  ...

The API service will run on api.dealership.com:

# dealership-api/config/deploy.yml
service: api

image: [DOCKER_REGISTRY]/dealership-api

servers:
  web:
    - 165.22.71.211

proxy:
  ssl: true
  host: api.dealership.com

registry:
  ...

env:
  ...

And the marketing website will be accesible from the main domain as well as www.dealership.com:

# marketing/config/deploy.yml
service: marketing

image: [DOCKER_REGISTRY]/dealership-web

servers:
  web:
    - 165.22.71.211

proxy:
  ssl: true
  host: "dealership.com,www.dealership.com"

registry:
  ...

env:
  ...

Kamal cannot do redirects right now, so the auto redirect from www to non-www variant has to be done on the application side. Also any accessory that needs to expose an HTTP endpoint should actually be another app like these three.

To deploy them we would run kamal setup for each. The first one will install Docker, set up the kamal network, and make sure kamal-proxy is running. The other two would safely skip these steps and deploy to existing proxy.

dealeship$ kamal setup
dealeship-api$ kamal setup
marketing$ kamal setup

Debugging

If we want to check what apps should Kamal Proxy be running, we can do so on the server with kamal-proxy list:

$ ssh [USER]@[SERVER]
# docker exec kamal-proxy kamal-proxy list
Service          Host                 Target           State    TLS
dealership    	 dealearship.com      cde2433e86d6:80  running  yes
dealership-api   api.dealearship.com  82361b53174f:80  running  yes
...

We’ll get what hosts and revisions are running for each deployed service as well as their status.

This is not exposed directly to Kamal but we can fix it with an alias:

# config/deploy.yml
...
aliases:
  ...
  apps: server exec docker exec kamal-proxy kamal-proxy list

Now running kamal apps gives us a nice rundown of what’s running which is pretty sweet.

Check out my book
Learn how to use Kamal to deploy your web applications with Kamal Handbook. Visualize Kamal's concepts, understand Kamal's configuration, and deploy practical life examples.
by Josef Strzibny
RSS