You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:18:04