From 0e34848a8096d2e202adb7ba7be0723386240510 Mon Sep 17 00:00:00 2001 From: Mark James Date: Tue, 29 Apr 2025 20:21:16 +1000 Subject: [PATCH 1/6] Improve docs and key order. --- lib/kamal/cli/templates/deploy.yml | 249 ++++++++++++++++++++--------- 1 file changed, 174 insertions(+), 75 deletions(-) diff --git a/lib/kamal/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index 89c7a7c3f..ce79cdb01 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -1,101 +1,200 @@ -# Name of your application. Used to uniquely configure containers. -service: my-app - -# Name of the container image. -image: my-user/my-app +# This YAML file is used by Kamal to configure its deployment of this web-app to one or more servers by building +# a Docker image of the app container via a Dockerfile and a clone of the app-code repository, pushing +# this image to an image repository, then deploying this image to the configured servers, along with any accessory +# images configured here (such as a database), and an optional Kamal-Proxy container to act as the single web +# listener and optional single SSL (https) processor and certificate manager, which then transfers unencrypted +# HTTP to and from web-app containers. +# +# This file is similar to a Docker Compose YAML file, but does not currently support interpolation of +# environment variables. YAML anchors (&anchor) and aliases (*anchor) are however available to reduce +# duplication, although aliases must substitute for a whole config value rather than a sub-string of such. +# +# All available configuration settings beyond those in this example are described at +# https://kamal-deploy.org/docs/configuration/overview/ -# Deploy to these servers. -servers: - web: - - 192.168.0.1 - # job: - # hosts: - # - 192.168.0.1 - # cmd: bin/jobs -# Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server. -# Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer. +# The name of your application. +# This is only directly used to uniquely name the web-app image/container and its accessory containers. # -# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption. -proxy: - ssl: true - host: app.example.com - # Proxy connects to your container on port 80 by default. - # app_port: 3000 +service: my-app &service -# Credentials for your image host. -registry: - # Specify the registry server, if you're not using Docker Hub - # server: registry.digitalocean.com / ghcr.io / ... - username: my-user - # Always use an access token rather than real password (pulled from .kamal/secrets). - password: - - KAMAL_REGISTRY_PASSWORD - -# Configure builder setup. +# Configure the web-app container builder. By default, building is done on the local machine, +# but remote building is supported. +# +# See https://kamal-deploy.org/docs/configuration/builder-examples/ for more information. +# builder: + # The CPU architecture of the server to which the app is being deployed. Emulation allows it to be + # different to the architecture of the build host. arch: amd64 + # Pass in additional build args needed for your Dockerfile. - # args: - # RUBY_VERSION: <%= ENV["RBENV_VERSION"] || ENV["rvm_ruby_string"] || "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" %> + #args: + # RUBY_VERSION: <%= ENV["RBENV_VERSION"] || ENV["rvm_ruby_string"] || "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" %> -# Inject ENV variables into containers (secrets come from .kamal/secrets). -# -# env: -# clear: -# DB_HOST: 192.168.0.2 -# secret: -# - RAILS_MASTER_KEY -# Aliases are triggered with "bin/kamal ". You can overwrite arguments on invocation: -# "bin/kamal app logs -r job" will tail logs from the first server in the job section. +# Inject environment variables into the web-app container. +# Secret variables are the names of variables set in .kamal/secrets. +# Both clear and secret variables are made available to any erb-file parsed during app start-up. # -# aliases: -# shell: app exec --interactive --reuse "bash" - -# Use a different ssh user than root +#env: +# clear: +# DB_USER: *service +# DB_NAME_PREFIX: *service +# +# # A web-app DB_HOST variable can be set here to the name of the database accessory container, which by default + # is the service name set above, hyphenated with the database accessory YAML key set below + # (e.g. my-app-db or my-app-postgres). If this is done, the app and the database containers will communicate + # through the Docker private-IP network, and there is no need to expose the database to either the host + # or the world by setting its accessory port below. +# # Alternatively, this variable can be set to an IP address or hostname. +# # Or instead of using a variable, the database hostname can be set directly in the web-app. +# DB_HOST: my-app-db # -# ssh: -# user: app +# secret: +# - DB_USER_PASSWORD +# - RAILS_MASTER_KEY -# Use a persistent storage volume. + +# Map one or more persistent storage volumes between a web-app container path and the host filesystem. +# The host filesytem path before the colon can either be an absolute path or a volume identifier, +# the latter form being mapped to the /var/lib/docker/volumes/ host path. # -# volumes: -# - "app_storage:/app/storage" +#volumes: +# - "app_storage:/app/storage" + # Bridge fingerprinted assets, like JS and CSS, between versions to avoid # hitting 404 on in-flight requests. Combines all files from new and old # version inside the asset_path. # -# asset_path: /app/public/assets +#asset_path: /app/public/assets -# Configure rolling deploys by setting a wait time between batches of restarts. + +# The registry that will host the built web-app Docker image. # -# boot: -# limit: 10 # Can also specify as a percentage of total hosts, such as "25%" -# wait: 2 - -# Use accessory services (secrets come from .kamal/secrets). -# -# accessories: -# db: -# image: mysql:8.0 -# host: 192.168.0.2 -# port: 3306 -# env: -# clear: -# MYSQL_ROOT_HOST: '%' -# secret: -# - MYSQL_ROOT_PASSWORD +registry: + # Specify the hostname of the registry, only necessary if not Docker Hub. + #server: registry.digitalocean.com / ghcr.io / my-harbor-hostname[:port] / ... + + username: my-registry-username + + # The name of the environment variable that holds the password for the above registry username, + # as set in .kamal/secrets. If supported by your registry, it's safer to use an access token + # rather than a password. + password: + - KAMAL_REGISTRY_PASSWORD + + +# The name of the web-app container image. +# If a third-party container image registry is being used (as configured above), this is usually of the form +# /. For the self-hosted Harbor registry, this will instead +# be /. The second part of this value will usually be automatically created, +# and so could be named after the service above. +# +image: my-user/my-app + + +# Use a different ssh user than root on the server to which you are deploying. +# +#ssh: +# user: app + + +# Deploy to the servers with the given IP addresses or hostnames. ssh must be able to connect to +# the given addresss or hostname with the user set above through a server-deployed private key and a +# local ssh Host config section for the given address or hostname. +# +servers: + web: + - &web-server + # job: + # hosts: + # - *web-server + # cmd: bin/jobs + + +# Add one or more accessory services. +# +#accessories: +# db: +# # The Docker Hub tagged public image for this accessory. +# # Another registry can instead be used: see https://kamal-deploy.org/docs/configuration/accessories/ +# image: mysql:8.0 +# +# # The public address or hostname where this accessory should be deployed. +# host: *web-server +# +# # The port that will be opened and published for this accessory. +# # If not set, no port will be opened nor published. +# # A setting of "::" will expose the accessory to the given + # external IP and port. For example, "127.0.0.1:3306:3306" will only expose the accessory to the host. +# # A numeric-only setting is equivalent to "0.0.0.0::", exposing the accessory to all + # IP addresses unless blocked by another firewall. +# # Whatever the setting, communication is available on the Docker private IP network via the accessory + # container name (my-app-db in this example). +# port: 3306 +# +# # The web-app environment variables above are not propagated to accessories. +# env: +# clear: +# MYSQL_ROOT_HOST: '%' +# # As set in .kamal/secrets. +# secret: +# - MYSQL_ROOT_PASSWORD +# +# # List any files from the dev repository that you wish copied into a path of this accessory container +# # for initialization, etc. The format is :. +# # Such a file can be an erb file that will be parsed using only the clear environment +# # variables defined above. Secret variables are however made available to script files. # files: # - config/mysql/production.cnf:/etc/mysql/my.cnf # - db/production.sql:/docker-entrypoint-initdb.d/setup.sql +# +# # Link host directories with accessory container absolute paths to persist data over accessory + # container lifetimes. Host directories are created if absent. # directories: +# # If not an absolute path, the key part of the value below uses the host directory +# # ~// # - data:/var/lib/mysql -# redis: -# image: valkey/valkey:8 -# host: 192.168.0.2 -# port: 6379 -# directories: -# - data:/data +# +# redis: +# image: valkey/valkey:8 +# host: *web-server +# port: 6379 +# directories: +# - data:/data + + +# Configure the Kamal Proxy container, which supports both name-based virtual servers, +# by routing hostnames to web-apps, and encryption/decryption for the https protocol, +# including automatically-updated TLS certificates. The proxy will either be deployed to the first +# listed web-server or no websevvers ("proxy: false"). Ensure you terminate SSL at your load balancer. +# +proxy: + # If this host field is absent the proxy will route all hostnames to this web-app; + # a string will route a single name; or a YAML array of hostnames can be routed. + # These routes will be added to a proxy that is already routing other web-apps. + host: app.example.com + + # Setting this "true" enables both https processing and auto-certification via Let's Encrypt of all listed hostnames. + # If using Cloudflare, set the encryption mode in its SSL/TLS setting to "Full" to enable CF-to-app encryption. + ssl: true + + # The proxy connects to web-app containers on port 80 by default. + #app_port: 3000 + + +# Configure rolling deploys by setting a wait time between batches of restarts. +# +#boot: +# limit: 10 # Can also specify as a percentage of total hosts, such as "25%" +# wait: 2 + + +# Aliases are triggered with "bin/kamal ". You can overwrite arguments on invocation: +# "bin/kamal app logs -r job" will tail logs from the first server in the job section. +# +#aliases: +# shell: app exec --interactive --reuse "bash" From b8823e584fbe29b6a3ded60640a0c0d32ab80bed Mon Sep 17 00:00:00 2001 From: Mark James Date: Wed, 30 Apr 2025 02:25:12 +1000 Subject: [PATCH 2/6] Add missing leading comment hashes. --- lib/kamal/cli/templates/deploy.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/kamal/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index ce79cdb01..e4581f10c 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -44,10 +44,10 @@ builder: # DB_NAME_PREFIX: *service # # # A web-app DB_HOST variable can be set here to the name of the database accessory container, which by default - # is the service name set above, hyphenated with the database accessory YAML key set below - # (e.g. my-app-db or my-app-postgres). If this is done, the app and the database containers will communicate - # through the Docker private-IP network, and there is no need to expose the database to either the host - # or the world by setting its accessory port below. +# # is the service name set above, hyphenated with the database accessory YAML key set below +# # (e.g. my-app-db or my-app-postgres). If this is done, the app and the database containers will communicate +# # through the Docker private-IP network, and there is no need to expose the database to either the host +# # or the world by setting its accessory port below. # # Alternatively, this variable can be set to an IP address or hostname. # # Or instead of using a variable, the database hostname can be set directly in the web-app. # DB_HOST: my-app-db @@ -129,11 +129,11 @@ servers: # # The port that will be opened and published for this accessory. # # If not set, no port will be opened nor published. # # A setting of "::" will expose the accessory to the given - # external IP and port. For example, "127.0.0.1:3306:3306" will only expose the accessory to the host. +# # external IP and port. For example, "127.0.0.1:3306:3306" will only expose the accessory to the host. # # A numeric-only setting is equivalent to "0.0.0.0::", exposing the accessory to all - # IP addresses unless blocked by another firewall. +# # IP addresses unless blocked by another firewall. # # Whatever the setting, communication is available on the Docker private IP network via the accessory - # container name (my-app-db in this example). +# # container name (my-app-db in this example). # port: 3306 # # # The web-app environment variables above are not propagated to accessories. @@ -152,8 +152,8 @@ servers: # - config/mysql/production.cnf:/etc/mysql/my.cnf # - db/production.sql:/docker-entrypoint-initdb.d/setup.sql # -# # Link host directories with accessory container absolute paths to persist data over accessory - # container lifetimes. Host directories are created if absent. +# # Link host directories with accessory container absolute paths to persist data across accessory +# # container lifetimes. Host directories are created if absent. # directories: # # If not an absolute path, the key part of the value below uses the host directory # # ~// From 9af1e8d9e77e8a580a9a67b3c1cc3b54a4ff19e0 Mon Sep 17 00:00:00 2001 From: Mark James Date: Wed, 30 Apr 2025 02:34:05 +1000 Subject: [PATCH 3/6] Emphasise that the DB_HOST variable name is not special. --- lib/kamal/cli/templates/deploy.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/kamal/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index e4581f10c..d4fe65510 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -43,11 +43,11 @@ builder: # DB_USER: *service # DB_NAME_PREFIX: *service # -# # A web-app DB_HOST variable can be set here to the name of the database accessory container, which by default -# # is the service name set above, hyphenated with the database accessory YAML key set below -# # (e.g. my-app-db or my-app-postgres). If this is done, the app and the database containers will communicate -# # through the Docker private-IP network, and there is no need to expose the database to either the host -# # or the world by setting its accessory port below. +# # A web-app DB_HOST variable (or a variable with a different name) could be set here to the name of the +# # database accessory container, which by default is the service name set above, hyphenated with the +# # database accessory YAML key set below (e.g. my-app-db or my-app-postgres). +# # If this is done, the app and the database containers will communicate through the Docker private-IP network, +# # and there is no need to expose the database to either the host or the world by setting its accessory port below. # # Alternatively, this variable can be set to an IP address or hostname. # # Or instead of using a variable, the database hostname can be set directly in the web-app. # DB_HOST: my-app-db From abf1cc351cd8aa48f72ecaf348f51632dd0113de Mon Sep 17 00:00:00 2001 From: Mark James Date: Wed, 30 Apr 2025 02:46:55 +1000 Subject: [PATCH 4/6] Emphasise that DB_HOST only works if used by the web-app. --- lib/kamal/cli/templates/deploy.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/kamal/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index d4fe65510..84721b346 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -46,8 +46,9 @@ builder: # # A web-app DB_HOST variable (or a variable with a different name) could be set here to the name of the # # database accessory container, which by default is the service name set above, hyphenated with the # # database accessory YAML key set below (e.g. my-app-db or my-app-postgres). -# # If this is done, the app and the database containers will communicate through the Docker private-IP network, -# # and there is no need to expose the database to either the host or the world by setting its accessory port below. +# # If this variable is used by the web-app, the app and the database containers will communicate through +# # the Docker private-IP network, and there is no need to expose the database to either the host or the world +# # by setting its accessory port below. # # Alternatively, this variable can be set to an IP address or hostname. # # Or instead of using a variable, the database hostname can be set directly in the web-app. # DB_HOST: my-app-db From 26c92be3eda7a72f0f2d0939cf1d22f3253d1db6 Mon Sep 17 00:00:00 2001 From: Mark James Date: Wed, 30 Apr 2025 12:16:35 +1000 Subject: [PATCH 5/6] State that the app repo clone is local --- lib/kamal/cli/templates/deploy.yml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/kamal/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index 84721b346..4bab32404 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -1,9 +1,9 @@ # This YAML file is used by Kamal to configure its deployment of this web-app to one or more servers by building -# a Docker image of the app container via a Dockerfile and a clone of the app-code repository, pushing -# this image to an image repository, then deploying this image to the configured servers, along with any accessory -# images configured here (such as a database), and an optional Kamal-Proxy container to act as the single web -# listener and optional single SSL (https) processor and certificate manager, which then transfers unencrypted -# HTTP to and from web-app containers. +# a Docker image of the app container via a Dockerfile and a local clone of the app-code repository (changes don't +# need to be first pushed to any remote), pushing this image to an image repository, then deploying this image +# to the configured servers, along with any accessory images configured here (such as a database), and an optional +# Kamal-Proxy container to act as the single web listener and optional single SSL (https) processor and +# certificate manager, which then transfers unencrypted HTTP to and from web-app containers. # # This file is similar to a Docker Compose YAML file, but does not currently support interpolation of # environment variables. YAML anchors (&anchor) and aliases (*anchor) are however available to reduce @@ -14,7 +14,8 @@ # The name of your application. -# This is only directly used to uniquely name the web-app image/container and its accessory containers. +# This is only directly used to uniquely prefix the name of the web-app image/container +# and its accessory containers. # service: my-app &service @@ -46,9 +47,9 @@ builder: # # A web-app DB_HOST variable (or a variable with a different name) could be set here to the name of the # # database accessory container, which by default is the service name set above, hyphenated with the # # database accessory YAML key set below (e.g. my-app-db or my-app-postgres). -# # If this variable is used by the web-app, the app and the database containers will communicate through -# # the Docker private-IP network, and there is no need to expose the database to either the host or the world -# # by setting its accessory port below. +# # If such a variable setting is used by the web-app, the app and the database containers will communicate +# # through the Docker private-IP network, and there is no need to expose the database to either +# # the host or the world by setting its accessory port below. # # Alternatively, this variable can be set to an IP address or hostname. # # Or instead of using a variable, the database hostname can be set directly in the web-app. # DB_HOST: my-app-db @@ -60,15 +61,15 @@ builder: # Map one or more persistent storage volumes between a web-app container path and the host filesystem. # The host filesytem path before the colon can either be an absolute path or a volume identifier, -# the latter form being mapped to the /var/lib/docker/volumes/ host path. +# the latter form being mapped to the /var/lib/docker/volumes//_data host path. # #volumes: # - "app_storage:/app/storage" # Bridge fingerprinted assets, like JS and CSS, between versions to avoid -# hitting 404 on in-flight requests. Combines all files from new and old -# version inside the asset_path. +# hitting 404 on in-flight requests. Combines all files from the new and old +# versions inside the asset_path. # #asset_path: /app/public/assets @@ -134,7 +135,7 @@ servers: # # A numeric-only setting is equivalent to "0.0.0.0::", exposing the accessory to all # # IP addresses unless blocked by another firewall. # # Whatever the setting, communication is available on the Docker private IP network via the accessory -# # container name (my-app-db in this example). +# # container name - (my-app-db in this example). # port: 3306 # # # The web-app environment variables above are not propagated to accessories. From 621862a50583b8fa7ffa1d4540e4a4147d242dec Mon Sep 17 00:00:00 2001 From: Mark James Date: Wed, 30 Apr 2025 20:56:53 +1000 Subject: [PATCH 6/6] Break up the introductory one-sentance paragraph --- lib/kamal/cli/templates/deploy.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/kamal/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index 4bab32404..e79c9d597 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -1,9 +1,10 @@ -# This YAML file is used by Kamal to configure its deployment of this web-app to one or more servers by building -# a Docker image of the app container via a Dockerfile and a local clone of the app-code repository (changes don't -# need to be first pushed to any remote), pushing this image to an image repository, then deploying this image -# to the configured servers, along with any accessory images configured here (such as a database), and an optional -# Kamal-Proxy container to act as the single web listener and optional single SSL (https) processor and -# certificate manager, which then transfers unencrypted HTTP to and from web-app containers. +# This YAML file is used by Kamal to configure its deployment of this web-app to one or more servers. +# Kamal builds a Docker image of the app itself via a Dockerfile and a local clone of the app-code repository +# (changes don't need to be first pushed to any remote), then pushes this image to the image repository +# configured here. Kamal then deploys the web-app image it built to the list of servers given here. +# Kamal can also deploy optional accessory images configured here (such as a database), +# plus an optional Kamal-Proxy container to act as the single web listener and optional single SSL (https) +# processor and certificate manager, which then transfers unencrypted HTTP to and from the web-app containers. # # This file is similar to a Docker Compose YAML file, but does not currently support interpolation of # environment variables. YAML anchors (&anchor) and aliases (*anchor) are however available to reduce