I'm not able to complete a production deployment with Kamal 2 and Ruby on Rails 8.0.2. using the video at https://kamal-deploy.org
When I run kamal setup, it produces:
ERROR Failed to boot web on [URL]
INFO First web container is unhealthy on [URL], not booting any other roles
Unable to find any info on why this might be, and, finally, at the conclusion of the deployment script
Finished all in 78.8 seconds
ERROR (SSHKit::Command::Failed): Exception while executing on host [URL]: docker exit status: 1
docker stdout: Nothing written
docker stderr: Error: target failed to become healthy within configured timeout (30s)
On the server:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc0885bc70ed basecamp/kamal-proxy:v0.9.0 "kamal-proxy run" 4 hours ago Up 4 hours 0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp kamal-proxy
At the moment, the domain is setup on DigitalOcean with an A record. That's it. Does it need more?
My deploy file is:
# Name of your application. Used to uniquely configure containers.
service: [SERVICE]
# Name of the container image.
image: [DOCKER USER]/[SERVICE]
# Deploy to these servers.
servers:
web:
- [URL]
# 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.
#
# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption.
proxy:
ssl: true
host: [URL]
# Credentials for your image host.
registry:
# Specify the registry server, if you're not using Docker Hub
# server: registry.digitalocean.com / ghcr.io / ...
username: [DOCKER USER]
# Always use an access token rather than real password when possible.
password:
- KAMAL_REGISTRY_PASSWORD
# Inject ENV variables into containers (secrets come from .kamal/secrets).
env:
secret:
- RAILS_MASTER_KEY
- MYSQL_ROOT_PASSWORD
clear:
# Run the Solid Queue Supervisor inside the web server's Puma process to do jobs.
# When you start using multiple servers, you should split out job processing to a dedicated machine.
SOLID_QUEUE_IN_PUMA: true
DB_HOST: [SERVICE]-db
# Log everything from Rails
RAILS_LOG_LEVEL: debug
# Aliases are triggered with "bin/kamal ". You can overwrite arguments on invocation:
# "bin/kamal logs -r job" will tail logs from the first server in the job section.
aliases:
console: app exec --interactive --reuse "bin/rails console"
shell: app exec --interactive --reuse "bash"
logs: app logs -f
dbc: app exec --interactive --reuse "bin/rails dbconsole"
# Use a persistent storage volume for sqlite database files and local Active Storage files.
# Recommended to change this to a mounted volume path that is backed up off server.
volumes:
- "[SERVICE]_storage:/rails/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: /rails/public/assets
# Configure the image builder.
builder:
arch: amd64
# # Build image via remote server (useful for faster amd64 builds on arm64 computers)
# remote: ssh://docker@docker-builder-server
#
# # Pass arguments and secrets to the Docker build process
# args:
# RUBY_VERSION: ruby-3.4.7
# secrets:
# - GITHUB_TOKEN
# - RAILS_MASTER_KEY
# Use a different ssh user than root
# ssh:
# user: app
# Use accessory services (secrets come from .kamal/secrets).
accessories:
db:
image: mysql:8.0
host: [URL]
port: "127.0.0.1:3306:3306"
env:
clear:
MYSQL_ROOT_HOST: '%'
secret:
- MYSQL_ROOT_PASSWORD
files:
- db/production.sql:/docker-entrypoint-initdb.d/setup.sql
directories:
- data:/var/lib/mysql