简体   繁体   English

Docker Compose + Rails:迁移的最佳实践?

[英]Docker Compose + Rails: best practice to migrate?

I just followed this article on Running a Rails Development Environment in Docker . 我刚刚阅读了有关在Docker中运行Rails开发环境的这篇文章。 Good article, works great. 好文章,效果很好。 After setting everything up, I decided to go on and set up a production environment. 设置完所有后,我决定继续设置生产环境。

GOAL: 目标:

I want to rake db:create && rake db:migrate every time my docker image is run. 我想在每次运行docker镜像时rake db:create && rake db:migrate

PROBLEM: 问题:

If I move the database creation and migrations steps... 如果我移动数据库创建和迁移步骤...

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

...into the Dockerfile... ...进入Dockerfile ...

RUN rake db:create && rake db:migrate

...that will throw an error... ......会引发错误......

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

...because the host in my database.yml ... ...因为我的database.ymlhost ...

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

development:
  <<: *default
  database: rails_five_development

...is set to the postgres service name specified in my docker-compose.yml ... ...设置为我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

...since that is the recommended practice as pointed by the article. ......因为这是文章指出的推荐做法。

QUESTION: 题:

How can I automatically rake db:create && rake db:migrate every time my docker image is run? 每次运行docker镜像时,如何自动执行rake db:create && rake db:migrate

I am trying to achieve the same thing as in this question 我试图在这个问题上实现同样的目的

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

If you would like your container to run the same executable every time, then you should consider using ENTRYPOINT in combination with CMD. 如果您希望容器每次都运行相同的可执行文件,那么您应该考虑将ENTRYPOINT与CMD结合使用。 See ENTRYPOINT 请参阅ENTRYPOINT

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

tl;dr TL;博士

You could define an entrypoint under app and define a bash file there: 您可以在app下定义一个entrypoint在那里定义一个bash文件:

app:
  entrypoint: [bin/entry]
  ..

bin/entry file example: bin / entry文件示例:

#!/bin/bash
set -e

rake db:create
rake db:migrate

exec "$@"

This approach creates the database if the migration is not able to succeed. 如果迁移无法成功,此方法将创建数据库。 It also avoids the issue of being unable to start the server because a pid file was left behind. 它还避免了因为丢失了pid文件而无法启动服务器的问题 Create the file as app/lib/docker-entrypoint.sh . 将文件创建为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 "$@"

The docker-compose.yml then includes: docker-compose.yml然后包括:

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

I use a Makefile: 我使用Makefile:

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

So, now when I wanna docker-compose up I just do make run instead. 所以,现在当我想要docker-compose updocker-compose up我只是做了make run

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM