【问题标题】:Cannot start dockerized rails application when pulling it from Docker Hub从 Docker Hub 拉取 dockerized rails 应用程序时无法启动它
【发布时间】:2021-01-22 03:41:48
【问题描述】:

我对一个在本地机器上完美运行的 rails 应用程序进行了 docker 化。我将我的 Github Actions 配置为将应用程序推送到 Docker Hub 上的私有映像中,当我尝试在本地或另一台机器上拉取并运行它时,它会拉取映像但容器随后退出,因为 Rails 失败并出现以下错误:

app  | rm: cannot remove 'tmp/pids/server.pid': No such file or directory
app  | => Booting Puma
app  | => Rails 6.0.3.3 application starting in development 
app  | => Run `rails server --help` for more startup options
app  | Exiting
app  | (erb):9:in `<main>': Cannot load database configuration: (NoMethodError)
app  | undefined method `[]' for nil:NilClass
app  |   from /usr/local/lib/ruby/2.7.0/erb.rb:905:in `eval'
app  |   from /usr/local/lib/ruby/2.7.0/erb.rb:905:in `result'
app  |   from /usr/local/bundle/gems/railties-6.0.3.3/lib/rails/application/configuration.rb:228:in `database_configuration'

我注释掉了rm 命令和bin/rails 命令,看看我是否可以让容器保持运行并在控制台中进行调试,但我没有机会。

通过搜索其他 SO 问题,我想我的 ENV 或 database.yml 一般肯定有问题,但我不明白为什么当我不从 Docker Hub 提取图像时它运行完美。不应该以任何一种方式解析凭据吗?每个环境都有单独的凭据文件中的凭据。

这是我的代码:

docker-compose.yml

version: '3'

volumes:
  db_data:
    driver: local
  app_data:
    driver: local

services:
  # database container
  postgres:
    image: postgres
    volumes:
      - app_data:/var/lib/postgresql/data
    ports:
      - 5439:5432
    environment:
      POSTGRES_DB: $DATABASE_NAME
      POSTGRES_USER: $DATABASE_USER
      POSTGRES_PASSWORD: $DATABASE_PASSWORD
    command: ["postgres", "-c", "log_statement=all"]
    restart: always

  backend:
    build: ./server
    volumes:
      - ./server:/var/workdir
    ports:
      - "3009:3000"
    depends_on:
      - postgres

Dockerfile

FROM ruby:2.7.1

WORKDIR /var/workdir
COPY . /var/workdir

# Install NodeJS and Yarn.
RUN curl https://deb.nodesource.com/setup_12.x | bash
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -y nodejs yarn

RUN yarn install --check-files

RUN bundle install

ENV PORT 3000
EXPOSE $PORT
CMD /var/workdir/entrypoint.sh

entrypoint.sh

#!/bin/bash

rm tmp/pids/server.pid

bin/rails db:create
bin/rails db:migrate

bin/rails server -b 0.0.0.0 -p $PORT

config/database.yml

# PostgreSQL. Versions 9.3 and up are supported.

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: postgres
  port: 5432
  database: <%= Rails.application.credentials.database[:name] %>
  username: <%= Rails.application.credentials.database[:username] %>
  password: <%= Rails.application.credentials.database[:password] %>

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

.github/workflows/main.yml

name: App

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
jobs:
  build:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres
        env:
          POSTGRES_DB: ${{ secrets.DATABASE_NAME }}
          POSTGRES_USER: ${{ secrets.DATABASE_USER }}
          POSTGRES_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
        ports:
          - 5439:5432
        # needed because the postgres container does not provide a healthcheck
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
      - name: Install PostgreSQL package
        run: |
          sudo apt-get -yqq install libpq-dev
      - name: Install yarn
        run: yarn install --check-files
      - uses: actions/setup-node@v1
        with:
          node-version: '12.13.0'
      - name: Setup Ruby
        uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.7.1
      - name: Ruby gem cache
        uses: actions/cache@v2
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-gems-
      - name: Build and create DB
        env:
          RAILS_ENV: test
          RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
        run: |
          cd server
          gem install bundler
          bundle config path vendor/bundle
          bundle install --jobs 4 --retry 3
          bin/rails db:setup
  deploy:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/checkout@v2
      - name: Docker login
        run: docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
      - name: Build
        run: docker build -t app ./server
      - name: Tags
        run: |
          docker tag app ${{ secrets.DOCKER_USER }}/app
          docker tag app ${{ secrets.DOCKER_USER }}/app:latest
      - name: Push
        run: |
          docker push ${{ secrets.DOCKER_USER }}/app
          docker push ${{ secrets.DOCKER_USER }}/app:latest

更新: 通过将 master.key 作为机密添加到 Github Actions,管道中的错误为:

rails aborted!
ActiveSupport::MessageEncryptor::InvalidMessage: Cannot load database configuration:
ActiveSupport::MessageEncryptor::InvalidMessage
(...)
Caused by:
OpenSSL::Cipher::CipherError:

当我将 test.key 添加为机密时,会返回原始错误。

这是我在本地创建的 docker-compose.yml,用于从 Docker Hub 获取和运行映像:

version: '3'

services:
  app:
    image: user/app:latest

我替换了这个问题的所有用户和 repo 名称。

【问题讨论】:

  • 您永远不会真正在本地构建和使用映像。您将卷映射到主机上,如果有不同之处,它不会“保留”在图像中。可能是图像需要重建和重新推送。我建议在本地测试时从 docker-compose.yml 中删除卷映射。
  • 我现在正在尝试在 Github 操作中捆绑和构建(请参阅更新的 main.yml),但我现在在管道中遇到了同样的错误。
  • 但您之前是否尝试过让它在本地机器上运行?
  • 它在开发中运行良好。带有 Rails 和 Postgres 的容器已启动并运行且可访问。我刚刚找到 this guide 为构建过程添加秘密,也许这就是我出错的地方
  • 在您删除了我在另一条评论中所写的卷之后?

标签: ruby-on-rails docker docker-compose github-actions dockerhub


【解决方案1】:

我很确定(但不是 100%)您的项目没有凭据文件。它应该在这里:

your_app/config/master.key

运行此命令时会生成该文件:

EDITOR=vim bundle exec rails credentials:edit

该文件用于解密您的 credentials.yml.enc 文件,其中存储了 secret_key_base(当然还有您的凭据)。
在服务器配置期间,我在secret_key_base 丢失时看到了同样的错误,这是因为我忘记创建将解密我的凭据文件的master.key。

很抱歉没有给你一个真正的答案,但更多的是一个你可以这样看一个。

【讨论】:

  • 我已将 master.key 文件添加到 Github 操作的机密中,并尝试在 main.yml 中调用它,如下所示:RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} 每个环境我也有单独的凭据。是否有特殊的语法来包含它们?
  • 抱歉,我对 Github 操作无能为力 :(
  • 我在这里找到了环境凭据的语法:blog.saeloun.com/2019/10/10/… 我希望它们不是 Heroku 独有的
猜你喜欢
  • 2017-11-28
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多