我正在尝试设置一个 PostgreSQL 容器(https://hub.docker.com/_/postgres/)。我有一些来自当前 PostgreSQL 实例的数据。我从
/var/lib/postgresql/data
复制了它,并希望将其设置为 PostgreSQL 容器的卷。
我来自 docker-compose.yml 文件中有关 PostgreSQL 的部分:
db:
image: postgres:9.4
ports:
- 5432:5432
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
PGDATA : /var/lib/postgresql/data
volumes:
- /projects/own/docker_php/pgdata:/var/lib/postgresql/data
当我创建 docker-compose up 时,我收到以下消息:
db_1 | initdb: directory "/var/lib/postgresql/data" exists but is not empty
db_1 | If you want to create a new database system, either remove or empty
db_1 | the directory "/var/lib/postgresql/data" or run initdb
db_1 | with an argument other than "/var/lib/postgresql/data".
我尝试从容器创建自己的映像,所以我的 Dockerfile 是:
FROM postgres:9.4
COPY pgdata /var/lib/postgresql/data
但是我遇到了同样的错误,我做错了什么?
我使用
pg_dumpall
获得了 SQL 转储,并将其放入 /docker-entrypoint-initdb.d
中,但每次我执行 docker-compose up
时都会执行此文件。
为了以 irakli 的答案为基础,这里有一个更新的解决方案:
volumes
部分version: '2'
services:
postgres9:
image: postgres:9.4
expose:
- 5432
volumes:
- data:/var/lib/postgresql/data
volumes:
data: {}
启动Postgres数据库服务器:
$ docker-compose up
显示数据库中的所有表。在另一个终端中,与容器的 Postgres 对话:
$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
它不会显示任何内容,因为数据库是空白的。 创建一个表:
$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'create table beer()'
列出新创建的表:
$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
--------+-----------+-------+-------------------+--------------------------
public | beer | table | |
耶! 我们现在已经使用共享存储卷启动了 Postgres 数据库,并在其中存储了一些数据。下一步是检查服务器停止后数据是否确实保留。
现在,杀死 Postgres 服务器容器:
$ docker-compose stop
再次启动Postgres容器:
$ docker-compose up
我们期望数据库服务器会重新使用存储,因此我们非常重要的数据仍然存在。 检查:
$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
--------+-----------+-------+-------------------+--------------------------
public | beer | table | |
我们已成功使用新型 Docker Compose 文件通过外部数据卷运行 Postgres 数据库,并检查它是否能保证我们的数据安全无虞。
首先,进行备份,将我们的数据存储在主机上:
$ docker exec -it $(docker-compose ps -q postgres9 ) pg_dump -Upostgres > backup.sql
从访客数据库中提取我们的数据:
$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'drop table beer'
将我们的备份(存储在主机上)恢复到 Postgres 容器中。
注意:使用“exec -i”,不要“-it”,否则你会得到“输入设备不是TTY”错误。
$ docker exec -i $(docker-compose ps -q postgres9 ) psql -Upostgres < backup.sql
列出表以验证恢复是否有效:
$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
--------+-----------+-------+-------------------+--------------------------
public | beer | table | |
总而言之,我们已经验证了我们可以启动数据库,重启后数据仍然存在,并且我们可以从主机将备份恢复到其中。
谢谢托马斯!
PostgreSQL 映像似乎在安装卷时出现问题。 FWIW,这可能更多是 PostgreSQL 问题而不是 Docker 问题,但这并不重要,因为无论如何,安装磁盘并不是持久数据库文件的推荐方法。
您应该创建仅包含数据的 Docker 容器。像这样:
postgres9:
image: postgres:9.4
ports:
- 5432:5432
volumes_from:
- pg_data
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
PGDATA : /var/lib/postgresql/data/pgdata
pg_data:
image: alpine:latest
volumes:
- /var/lib/postgresql/data/pgdata
command: "true"
我测试过并且工作正常。您可以在此处阅读有关纯数据容器的更多信息:为什么 Docker 数据容器(卷!)很好
至于:如何导入初始数据,您可以:
docker cp
,进入设置的仅数据容器,或者从现有
dumped.sql
文件恢复数据。
创建你的 Dockerfile
version: "3"
services:
postgres:
image: postgres
container_name: postgres
environment:
POSTGRES_DB: YOUR_DATABASE
POSTGRES_USER: your_username_if_needed
POSTGRES_PASSWORD: your_password_if_needed
expose:
- 5432
volumes:
- data:/var/lib/postgresql/data
volumes:
data: {}
启动它并杀死它
docker-compose up
然后docker-compose stop
然后从转储中迁移数据。
docker exec -i YOUR_CONTAINER_NAME psql -U your_username_if_needed -W -d YOUR_DATABASE < your_dump.sql
-W
仅当您设置密码时才需要。
您现在应该看到控制台正在执行复制。
完成后你就可以出发了
docker-compose up