错误:在docker容器中导入Postgres数据库

时间:2016-12-30 11:20:03

标签: ruby-on-rails bash postgresql docker docker-compose

我在docker容器中的rails应用程序上运行ruby。我想在postgres容器中创建然后恢复数据库转储。 但是我

以下是我目前所做的事情:

1)/docker-entrypoint-initdb.d文件夹中添加了bash脚本。脚本只是创建数据库:

psql -U docker -d postgres -c 'create database dbname;'

结果:已创建数据库但rails服务器已退出,代码为0.错误:web_1 exited with code 0

2)添加了在docker-compose up之前执行的脚本。

# Run docker db container
echo "Running db container"
docker-compose run -d db

# Sleep for 10 sec so that container have time to run
echo "Sleep for 10 sec"
sleep 10

echo 'Copying db_dump.gz to db container'
docker cp db_dump/db_dump.gz $(docker-compose ps -q db):/

# Create database `dbname`
echo 'Creating database `dbname`'
docker exec -i $(docker-compose ps -q db) psql -U docker -d postgres -c 'create database dbname;'

echo 'importing database `dbname`'
docker exec -i $(docker-compose ps -q db) bash -c "gunzip -c /db_dump.gz | psql -U postgres dbname"

结果:数据库创建和恢复数据。但是使用docker-compose up运行Web应用程序服务器时会运行另一个容器。

docker--compose.yml

version: '2'

services:

  db:
    image: postgres

    environment:
      - POSTGRES_PASSWORD=docker
      - POSTGRES_USER=docker

  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0' -d
    image: uname/application
    links:
      - db
    ports:
      - "3000:3000"
    depends_on:
      - db
    tty: true

有人可以帮助创建和导入数据库吗?

修改

我通过在POSTGRES_DB=db_name文件中添加docker-compose.yml环境变量尝试了另一种方法,以便创建数据库并在运行应用程序(docker-compose up)之后,我和#39 ; ll导入数据库。但是收到错误:web_1 exited with code 0

我很困惑为什么我会收到此错误(在第一种和第三种方法中),似乎在docker-compose文件中出现了混乱。

4 个答案:

答案 0 :(得分:5)

设置数据库转储装载

您需要将转储装入容器,以便可以访问它。在docker-compose.yml:

中有类似的东西
db:
  volumes:
    - './db_dump:/db_dump'

创建一个名为db_dump的本地目录,并将db_dump.gz文件放在那里。

启动数据库容器

在环境中使用POSTGRES_DB(如您在问题中所提到的)自动创建数据库。单独启动db,不使用rails服务器。

docker-compose up -d db

导入数据

等待几秒钟以使数据库可用。然后,导入您的数据。

docker-compose exec db gunzip /db_dump/db_dump.gz
docker-compose exec db psql -U postgres -d dbname -f /db_dump/db_dump.gz
docker-compose exec db rm -f /db_dump/db_dump.gz

您也可以创建一个脚本来执行此导入,将其粘贴到您的图像中,然后使用单个docker-compose命令来调用它。或者你可以让你的入口点脚本检查转储文件是否存在,如果存在,解压缩并导入它......无论你需要做什么。

启动rails服务器

docker-compose up -d web

自动化

如果您是手动执行此操作以准备新设置,那么您就完成了。如果您需要将其自动化为工具链,则可以在脚本中执行此操作。只需单独启动容器,在两者之间进行数据库导入,然后使用sleep来弥补任何启动延迟。

答案 1 :(得分:2)

web_1 exited with code 0

您是否尝试过检查web_1容器的日志? docker-compose logs web

我强烈建议您不要初始化数据库容器手动,在启动容器的过程中自动生成。

查看the entrypoint of postgres,我们可以将db_dump.gz放入容器的/docker-entrypoint-initdb.d/目录中,它将自动执行,因此docker-compose.yml可以是:

db:
  volumes:
    - './initdb.d:/docker-entrypoint-initdb.d'

db_dump.gz放入本地计算机上的./initdb.d

答案 2 :(得分:1)

使用命令时 docker-compose run -d db

你运行一个单独的容器,这意味着你正在运行3个容器,其中1是应用程序2是dbs。使用上述命令运行的容器将不是服务的一部分。 compose正在使用单独的db。

因此,不要运行docker-compose up -d db运行docker-compose up -d并继续使用您的脚本

答案 3 :(得分:1)

我通过为db容器添加container_name来实现它。我的db容器名称不同(app_name_db_1),我正在连接到名为db的容器。

在提供经过硬编码的container_namedb)之后,它就会正常运行。