Docker-compose v3无法持久化Postgres数据库 [英] Docker-compose v3 not persisting postgres database

查看:158
本文介绍了Docker-compose v3无法持久化Postgres数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在关闭并重新启动docker-compose v3容器后,我很难保留postgres数据.这似乎是一个普遍的问题,但是经过大量搜索之后,我仍然找不到能够解决问题的解决方案.

I'm having difficulty persisting postgres data after a docker-compose v3 container is brought down and restarted. This seems to be a common problem, but after a lot of searching I have not been able to find a solution that works.

我的问题类似于此处:如何使用卷将数据持久化到dockerized postgres数据库中,但是该解决方案不起作用-因此请不要关闭.我将逐步完成下面的所有步骤来复制问题.

My question is similar to here: How to persist data in a dockerized postgres database using volumes, but the solution does not work - so please don't close. I'm going to walk through all the steps below to replicate the problem.

这是我的docker-compose文件:

Here is my docker-compose file:

version: "3"  
services:  
  db:
    image: postgres:latest
    environment:
      POSTGRES_DB: zennify
      POSTGRES_USER: patientplatypus
      POSTGRES_PASSWORD: SUPERSECRETPASSWORD
    volumes:
      - pgdata:/var/lib/postgresql/data:rw
    ports:
      - 5432:5432
  app:
    build: .
    command: ["go", "run", "main.go"]
    ports:
      - 8081:8081
    depends_on:
      - db
    links:
      - db
volumes: 
  pgdata:

这是我调出并写入数据库后的终端输出:

Here is the terminal output after I bring it up and write to my database:

patientplatypus:~/Documents/zennify.me/backend:08:54:03$docker-compose up
Starting backend_db_1 ... done
Starting backend_app_1 ... done
Attaching to backend_db_1, backend_app_1
db_1   | 2018-08-19 13:54:53.661 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1   | 2018-08-19 13:54:53.661 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db_1   | 2018-08-19 13:54:53.664 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1   | 2018-08-19 13:54:53.692 UTC [24] LOG:  database system was shut down at 2018-08-19 13:54:03 UTC
db_1   | 2018-08-19 13:54:53.712 UTC [1] LOG:  database system is ready to accept connections
app_1  | db init successful
app_1  | create_userinfo_table started
app_1  | create_userinfo_table finished
app_1  | inside RegisterUser in Golang
app_1  | here is the users email:
app_1  | %s pwoiioieind@gmail.com
app_1  | here is the users password:
app_1  | %s ANOTHERSECRETPASSWORD
app_1  | value of randSeq,  7NLHzuVRuTSxYZyNP6MxPqdvS0qy1L6k
app_1  | search_userinfo_table started
app_1  | value of OKtoAdd, %t true
app_1  | last inserted id = 1 //I inserted in database!
app_1  | value of initUserRet,  added

我还可以在另一个终端选项卡中连接到postgres,并使用psql -h 0.0.0.0 -p 5432 -U patientplatypus zennify验证数据库是否已正确写入.这是userinfo表的输出:

I can also connect to postgres in another terminal tab and verify that the database was written to correctly using psql -h 0.0.0.0 -p 5432 -U patientplatypus zennify. Here is the output of the userinfo table:

zennify=# TABLE userinfo
;
         email         |                           password                           |            regstring             | regbool | uid 
-----------------------+--------------------------------------------------------------+----------------------------------+---------+-----
 pwoiioieind@gmail.com | $2a$14$u.mNBrITUJaVjly15BOV9.Q9XmELYRjYQbhEUi8i4vLWtOr9QnXJ6 | r33ik3Jtf0m9U3zBRelFoWyYzpQp7KzR | f       |   1
(1 row)

所以一旦写入数据库就行了!

So writing to the database once works!

如何

现在让我们执行以下操作:

Let's now do the following:

$docker-compose stop
backend_app_1 exited with code 2
db_1   | 2018-08-19 13:55:51.585 UTC [1] LOG:  received smart shutdown request
db_1   | 2018-08-19 13:55:51.589 UTC [1] LOG:  worker process: logical replication launcher (PID 30) exited with exit code 1
db_1   | 2018-08-19 13:55:51.589 UTC [25] LOG:  shutting down
db_1   | 2018-08-19 13:55:51.609 UTC [1] LOG:  database system is shut down
backend_db_1 exited with code 0

通过使用docker-compose stop而不是docker-compose down来阅读有关此主题的其他线程,应保留本地数据库.但是,如果我再次使用docker-compose up,然后又没有向数据库中写入新值,只需在postgres中查询表,则该表为空:

From reading the other threads on this topic using docker-compose stop as opposed to docker-compose down should persist the local database. However, if I again use docker-compose up and then, without writing a new value to the database simply query the table in postgres it is empty:

zennify=# TABLE userinfo;
 email | password | regstring | regbool | uid 
-------+----------+-----------+---------+-----
(0 rows)

我以为我可能已经在初始化步骤中覆盖了我的代码中的表,但是我只有(golang片段):

I had thought that I may have been overwriting the table in my code on the initialization step, but I only have (golang snippet):

_, err2 := db.Exec("CREATE TABLE IF NOT EXISTS userinfo(email varchar(40) NOT NULL, password varchar(240) NOT NULL, regString  varchar(32) NOT NULL, regBool bool NOT NULL, uid serial NOT NULL);")

当然,只有以前没有创建过的表才应该创建.

Which should, of course, only create the table if it has not been previously created.

有人对出什么问题有任何建议吗?据我所知,这一定是docker-compose的问题,而不是我的代码.感谢您的帮助!

Does anyone have any suggestions on what is going wrong? As far as I can tell this has to be a problem with docker-compose and not my code. Thanks for the help!

我研究了使用docker版本2并遵循本文中显示的格式( Docker通过使用以下撰写来撰写不持久化数据):

I've looked into using version 2 of docker and following the format shown in this post (Docker compose not persisting data) by using the following compose:

version: "2"  
services:  
  app:
    build: .
    command: ["go", "run", "main.go"]
    ports:
      - "8081:8081"
    depends_on:
      - db
    links:
      - db
  db:
    image: postgres:latest
    environment:
      POSTGRES_DB: zennify
      POSTGRES_USER: patientplatypus
      POSTGRES_PASSWORD: SUPERSECRETPASSWORD
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data/
volumes:
  pgdata: {}

再次不幸的是,我遇到了同样的问题-数据可以写入,但在两次关机之间不会持久存在.

Unfortunately again I get the same problem - the data can be written but does not persist between shutdowns.

编辑

简要说明一下,使用docker-compose up实例化服务然后依赖docker-compose stopdocker-compose start不会对数据的持久性产生实质性影响.重启后仍然无法持续.

Just a quick note that using docker-compose up to instantiate the service and then relying on docker-compose stop and docker-compose start has no material affect on persistence of the data. Still does not persist across restarts.

编辑编辑

再加上我一直在寻找的东西.如果要正确执行到docker容器中以查看数据库的值,则可以执行以下操作:

Couple more things I've been finding out. If you want to properly exec into the docker container to see the value of the database you can do the following:

docker exec -it backend_db_1 psql -U patientplatypus -W zennify

其中backend_db_1是docker容器数据库的名称patientplatypus是我的用户名,zennify是数据库容器中的数据库的名称.

where backend_db_1 is the name of the docker container database patientplatypus is my username and zennify is the name of the database in the database container.

我也尝试过,没有运气,如下所示将网络网桥添加到docker-compose文件中:

I've also tried, with no luck, to add a network bridge to the docker-compose file as follows:

version: "3"  
services:  
  db:
    build: ./db
    image: postgres:latest
    environment:
      POSTGRES_USER: patientplatypus
      POSTGRES_PASSWORD: SUPERSECRET
      POSTGRES_DB: zennify
    ports:
      - 5432:5432
    volumes:
      - ./db/pgdata:/var/lib/postgresql/data
    networks:
      - mynet
  app:
    build: ./
    command: bash -c 'while !</dev/tcp/db/5432; do sleep 5; done; go run main.go'
    ports:
      - 8081:8081
    depends_on:
      - db
    links:
      - db
    networks:
      - mynet
networks:
  mynet:
    driver: "bridge"

我目前的工作原理是,无论出于何种原因,我的golang容器都将其必须的postgres值写入本地存储而不是共享卷中,我也不知道为什么.这是我对golang open命令的外观的最新想法:

My current working theory is that, for whatever reason, my golang container is writing the postgres values it has to local storage rather than the shared volume and I don't know why. Here is my latest idea of what the golang open command should look like:

data.InitDB("postgres://patientplatypus:SUPERSECRET@db:5432/zennify/?sslmode=disable")
...
func InitDB(dataSourceName string) {
    db, _ := sql.Open(dataSourceName)
    ...
}

同样可以,但是不会持久保存数据.

Again this works, but it does not persist the data.

推荐答案

Docker命名卷与您正在使用的原始docker-compose保持一致.

Docker named volumes are persisted with the original docker-compose you are using.

version: "3"  
services:  
  db:
    image: postgres:latest
    environment:
      POSTGRES_DB: zennify
      POSTGRES_USER: patientplatypus
      POSTGRES_PASSWORD: SUPERSECRETPASSWORD
    volumes:
      - pgdata:/var/lib/postgresql/data:rw
    ports:
      - 5432:5432
volumes: 
  pgdata:

如何证明呢?

1)运行docker-compose up -d创建容器和卷.

1) Run docker-compose up -d to create container and volume.

docker-compose up -d
Creating network "docker_default" with the default driver
Creating volume "docker_pgdata" with default driver
Pulling db (postgres:latest)...
latest: Pulling from library/postgres
be8881be8156: Already exists
bcc05f43b4de: Pull complete
....
Digest: sha256:0bbfbfdf7921a06b592e7dc24b3816e25edfe6dbdad334ed227cfd64d19bdb31
Status: Downloaded newer image for postgres:latest
Creating docker_db_1 ... done

2)在卷位置上写入文件

2) Write a file on the volume location

docker-compose exec db /bin/bash -c 'echo "File is persisted" > /var/lib/postgresql/data/file-persisted.txt'

3)运行docker-compose down

请注意,按照文档.您需要使用-v运行它才能删除卷.

Notice that when you run down it removes no volumes just containers and network as per documentation. You would need to run it with -v to remove volumes.

Stopping docker_db_1 ... done Removing docker_db_1 ... done Removing network docker_default

Stopping docker_db_1 ... done Removing docker_db_1 ... done Removing network docker_default

还请注意您的音量仍然存在 docker volume ls | grep pgdata local docker_pgdata

Also notice your volume still exists docker volume ls | grep pgdata local docker_pgdata

4)再次运行docker-compose up -d以启动容器并重新安装卷.

4) Run docker-compose up -d again to start containers and remount volumes.

5)查看文件是否仍在卷中

5) See file is still in the volume

docker-compose exec db /bin/bash -c 'ls -la /var/lib/postgresql/data | grep persisted ' -rw-r--r-- 1 postgres root 18 Aug 20 04:40 file-persisted.txt

docker-compose exec db /bin/bash -c 'ls -la /var/lib/postgresql/data | grep persisted ' -rw-r--r-- 1 postgres root 18 Aug 20 04:40 file-persisted.txt

命名卷不是主机卷.阅读文档或查找一些文章以解释不同之处.另请参阅Docker管理着存储命名卷文件的位置,您可以使用其他驱动程序,但目前最好只是学习基本的区别.

Named volumes are not host volumes. Read the documentation or look up some articles to explain the difference. Also see Docker manages where it stores named volumes files and you can use different drivers but for the moment it is best you just learn the basic difference.

这篇关于Docker-compose v3无法持久化Postgres数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆