【问题标题】:Docker Compose + Rails: best practice to migrate?Docker Compose + Rails:迁移的最佳实践?
【发布时间】:2023-03-25 15:18:01
【问题描述】:

我刚刚在Running a Rails Development Environment in Docker 上关注了这篇文章。好文章,效果很好。设置完所有内容后,我决定继续设置生产环境。

目标:

每次运行 docker 映像时,我都想rake db:create && rake db:migrate

问题:

如果我移动数据库创建和迁移步骤...

docker-compose run app rake db:create
docker-compose run app rake db:migrate

...进入 Dockerfile...

RUN rake db:create && rake db:migrate

...这将引发错误...

could not translate host name "postgres" to address: Name or service not known

...因为host 在我的database.yml...

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  timeout: 5000
  username: postgres
  host: postgres
  port: 5432

development:
  <<: *default
  database: rails_five_development

...设置为我的docker-compose.yml...中指定的postgres服务名称...

version: "2"
services:
  postgres:
    image: postgres:9.5
    ports:
      - "5432"
  app:
    build: .
    command: rails server -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    links:
      - postgres

...因为这是文章指出的推荐做法。

问题:

如何在每次运行 docker 映像时自动 rake db:create &amp;&amp; rake db:migrate

I am trying to achieve the same thing as in this question

【问题讨论】:

    标签: ruby-on-rails docker docker-compose dockerfile


    【解决方案1】:

    来自https://docs.docker.com/engine/reference/builder/#cmd

    如果您希望您的容器每次都运行相同的可执行文件,那么您应该考虑将 ENTRYPOINT 与 CMD 结合使用。请参阅入口点

    https://docs.docker.com/engine/reference/builder/#entrypoint

    tl;博士

    您可以在 app 下定义一个 entrypoint 并在那里定义一个 bash 文件:

    app:
      entrypoint: [bin/entry]
      ..
    

    bin/入口文件示例:

    #!/bin/bash
    set -e
    
    rake db:create
    rake db:migrate
    
    exec "$@"
    

    【讨论】:

    • 这个答案在docker-compose up --build 上效果很好,但是当我尝试做docker-compose run web rake console 时。它会抛出一个错误。 database "yc_development" is being accessed by other user
    【解决方案2】:

    如果迁移无法成功,此方法会创建数据库。它还避免了issue 因为留下了 pid 文件而无法启动服务器。将文件创建为app/lib/docker-entrypoint.sh

    #!/bin/sh
    # https://stackoverflow.com/a/38732187/1935918
    set -e
    
    if [ -f /app/tmp/pids/server.pid ]; then
      rm /app/tmp/pids/server.pid
    fi
    
    bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup
    
    exec bundle exec "$@"
    

    docker-compose.yml 然后包括:

    entrypoint: ["/app/lib/docker-entrypoint.sh"]
    command: ["rails","server","-b","0.0.0.0","-p","3000"]
    

    【讨论】:

    • 如果迁移因任何原因失败,数据库将被重建。不危险吗?
    • @masciugo 有效点。您是否能够找到一种方法来检查数据库是否已经存在?
    • 为什么要在容器中单独运行命令?
    【解决方案3】:

    我使用 Makefile:

    run:
        docker-compose up -d \
        && docker-compose run web rake db:create
    

    所以,现在当我想要docker-compose up 时,我只需要make run

    【讨论】:

    • 如何转义冒号?我得到以下make: *** No rule to make target 'create', needed by 'run'. Stop.
    • 如果 Makefile 格式正确,您不必担心转义任何冒号。尝试将它们全部放在一行docker-compose up -d &amp;&amp; docker-compose run web rake db:create 并确保使用制表符 (^I) 而不是空格
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2019-01-01
    • 2016-02-20
    • 1970-01-01
    • 2021-06-27
    • 2016-09-09
    相关资源
    最近更新 更多