Web Analytics Made Easy - Statcounter

Deploy Multiple Rails Apps on a Single Server with Kamal 1

Deploy multiple Rails apps on a single server with Kamal 1: Configure Traefik and all accessories in a single deploy.yml file & use a private Docker bridge network

Here's one way to deploy multiple Rails Application (and their back service: Database, Redis) on a Single Server:

What is Kamal?

Kamal-deploy  is a lightweight, Rub-based deployment tool, designed to simplify process of deploying and managing Dockerized Rails application. It streamlines server setup, configuration and deployment with minimal overhead.

Kamal automates comon Devops tasks, allowing developers to forcus more on building applications and less on infrastructure management.

Why Kamal 1 and how about Kamal 2?

At the time I'm writing this tutorial, DHH & his team is deveploment Kamal version with built-in feature to support deployment multiple apps on same server & replaced Traefik with Kamal Proxy

Pre-requisities

Solution

For deployment multiple Rails apps on single server with Kamal 1, Let try the solution bellow:

  • Config Traefik and Accessories on a single deploy.yml file ( on a single app)
  • Use private docker bridge to communicate between application and traefik, accessories

Configuration

1. Docker private network

Create a new docker network on server before deployment

docker network create private_nw

Notes: You can create and use multiple Docker networks, assigning each application its own network to achieve better isolation and improve security.

2. Traefik and Accessories

Configure Traefik and Accessories in a single deploy.yml file. Place all accessories in this file and ensure they are connected to the Docker network created earlier.

# config/deploy.yml
accessories:
  redis:
    image: redis:alpine
    hosts:
      - 192.168.10.12
    options:
      network: "private_nw"
# Configure custom arguments for Traefik
traefik:
  options:
    publish:
      - 443:443
    volume:
      - "/letsencrypt/acme.json:/letsencrypt/acme.json"
    network: "private_nw"
  args:
    api.dashboard: true
    entryPoints.web.address: ":80"
    entryPoints.websecure.address: ":443"
    entryPoints.web.http.redirections.entryPoint.to: websecure
    entryPoints.web.http.redirections.entryPoint.scheme: https
    entryPoints.web.http.redirections.entrypoint.permanent: true
    certificatesResolvers.letsencrypt.acme.email: "email@example.com"
    certificatesResolvers.letsencrypt.acme.storage: "/letsencrypt/acme.json" 
    certificatesResolvers.letsencrypt.acme.httpchallenge: true
    certificatesResolvers.letsencrypt.acme.httpchallenge.entrypoint: web
# ....
Kamal config.yml, treafik & accessory

3. Application

With the deploy.yml file for each Rails application, configure your application, build, and other sections without duplicating the Traefik and accessories configurations across multiple files.

Example:

  • For Application 1, include the full configuration: server, accessories, traefik, etc.
  • For Application 2, omit the accessories and traefik sections, as they are already handled by the first configuration.
# appication
# config/deploy.yml
service: app1
servers:
  web:
    hosts:
      - 192.168.10.12
    labels:
      traefik.enable: true
      traefik.http.routers.app1-web.rule: Host(`app1.example.com`)
      traefik.http.routers.app1-web.entrypoints: websecure
      traefik.http.routers.app1-web.tls: true
      traefik.http.routers.app1.tls.certresolver: letsencrypt
    options:
      network: "private_nw"

volumes:
  - /local/storage/path:/rails/storage
# ... other config section except accessories & traefik
Kamal config.yml on each application

Deployment command

On application 1 ( full configuration)

kamal envify
kamal env push
kamal accessory boot all
kamal traefik boot
kamal deploy
On application 1 ( full configuration)

On other application

kamal envify
kamal env push
kamal deploy
## Go back to application 1
kamal treafik reboot -y #if need