使用Kamal2部署Ruby on Rails 8.0.0.pre2生产环境时容器健康检查失败及数据库连接问题求助
Kamal2部署Ruby on Rails 8.0.0.pre2生产环境时容器健康检查失败及数据库连接问题求助
我最近跟着官方指南用Kamal2部署Ruby on Rails 8.0.0.pre2的生产环境,执行kamal setup的时候,数据库附件和Kamal代理都顺利创建完成了,但最后在应用Docker容器的健康检查环节直接失败了,卡在这里一直过不去。
执行kamal setup的错误输出:
Releasing the deploy lock... Finished all in 90.4 seconds ERROR (SSHKit::Command::Failed): Exception while executing on host 192.168.xxx.xxx: docker exit status: 1 docker stdout: Nothing written docker stderr: Error: target failed to become healthy
查看部署日志后,发现核心问题是数据库连接失败:
2024-11-08T14:31:42.688568367Z Tasks: TOP => db:prepare 2024-11-08T14:31:42.688572580Z (See full trace by running task with --trace) 2024-11-08T14:31:44.208156934Z bin/rails aborted! 2024-11-08T14:31:44.208182929Z ActiveRecord::ConnectionNotEstablished: Can't connect to server on '127.0.0.1' (115) (ActiveRecord::ConnectionNotEstablished)
我已经在deploy.yml里明确配置了DB_HOST: app-db,同时database.yml里的主机配置是:
host: <%= ENV.fetch("DB_ HOST") { "127.0.0.1" } %>
看起来应用容器根本没用到我设置的app-db主机,反而默认用了127.0.0.1去连接,导致连不上附件的数据库服务。我怀疑是不是环境变量没正确注入,或者容器网络的配置有问题?
我的完整配置和容器状态信息:
deploy.yml 配置:
# Name of your application. Used to uniquely configure containers. service: app # Name of the container image. image: user/app # Deploy to these servers. servers: web: - 192.168.x.xxx # 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. # # Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption. proxy: ssl: false host: app.domain.local # Credentials for your image host. registry: # Specify the registry server, if you're not using Docker Hub # server: registry.digitalocean.com / ghcr.io / ... username: 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 # Set number of processes dedicated to Solid Queue (default: 1) # JOB_CONCURRENCY: 3 # Set number of cores available to the application on each server (default: 1). # WEB_CONCURRENCY: 2 # Match this to any external database server to configure Active Record correctly # Use app-db for a db accessory server on same machine via local kamal docker network. DB_HOST: app-db # Log everything from Rails RAILS_LOG_LEVEL: debug # Aliases are triggered with "bin/kamal <alias>". 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: - "app_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: 3.3.5 # 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:latest host: 192.168.x.xxx # Change to 3306 to expose port to the world instead of just local network. port: "127.0.0.1:3306:3306" env: clear: MYSQL_ROOT_HOST: '%' secret: - MYSQL_ROOT_PASSWORD files: # - config/mysql/production.cnf:/etc/mysql/my.cnf - db/production.sql:/docker-entrypoint-initdb.d/setup.sql directories: - data:/var/lib/mysql # redis: # image: redis:7.0 # host: 192.168.0.2 # port: 6379 # directories: # - data:/data
当前运行的容器状态:
root@app:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b3c70139a8a4 basecamp/kamal-proxy:v0.8.2 "kamal-proxy run" 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp kamal-proxy 709816c42ee7 mysql:latest "docker-entrypoint.s…" 2 hours ago Up 2 hours 127.0.0.1:3306->3306/tcp, 33060/tcp app-db
另外我突然发现,我的database.yml里写的是DB_ HOST(DB和HOST之间多了个空格),但deploy.yml里的环境变量是DB_HOST,这会不会是导致环境变量没被正确读取的关键问题?
有没有朋友遇到过类似的情况,或者能给我一些排查的方向?
备注:内容来源于stack exchange,提问作者prodigerati
相关产品推荐
相关产品推荐

