在关闭并重新启动docker-compose v3容器后,我很难保留postgres数据。这似乎是一个普遍的问题,但是经过大量搜索之后,我仍然无法找到可行的解决方案。
我的问题类似于这里:How to persist data in a dockerized postgres database using volumes,但解决方案不起作用-因此请不要关闭。我将逐步完成下面的所有步骤来复制问题。
这是我的docker-compose文件:
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:
这是我调出并写入数据库后的终端输出:
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
表的输出:
zennify=# TABLE userinfo
;
email | password | regstring | regbool | uid
-----------------------+--------------------------------------------------------------+----------------------------------+---------+-----
pwoiioieind@gmail.com | $2a$14$u.mNBrITUJaVjly15BOV9.Q9XmELYRjYQbhEUi8i4vLWtOr9QnXJ6 | r33ik3Jtf0m9U3zBRelFoWyYzpQp7KzR | f | 1
(1 row)
所以一旦写入数据库就行了!
如何
现在让我们执行以下操作:
$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中查询该表,则该表为空:
zennify=# TABLE userinfo;
email | password | regstring | regbool | uid
-------+----------+-----------+---------+-----
(0 rows)
我以为我可能已经在初始化步骤中覆盖了我代码中的表,但是我只有(golang片段):
_, 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);")
当然,只有先前未创建过的表才应该创建。
有人对出什么问题有任何建议吗?据我所知,这一定是docker-compose的问题,而不是我的代码。感谢您的帮助!
编辑:
我研究了使用docker版本2,并通过以下撰写方式遵循本文(Docker compose not persisting data)中显示的格式:
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: {}
不幸的是,我再次遇到相同的问题-数据可以写入,但在两次关机之间不会持久存在。
编辑编辑:
仅需简短说明一下,使用docker-compose up
实例化服务,然后依赖docker-compose stop
和docker-compose start
对数据的持久性没有实质影响。在重启后仍然无法持续。
编辑编辑编辑:
再加上我一直在寻找的东西。如果要正确执行到docker容器中以查看数据库的值,则可以执行以下操作:
docker exec -it backend_db_1 psql -U patientplatypus -W zennify
其中backend_db_1
是docker容器数据库的名称,patientplatypus
是我的用户名,zennify
是数据库容器中的数据库的名称。
我也尝试过运气,如下所示将网络网桥添加到docker-compose文件中:
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命令的外观的最新想法:
data.InitDB("postgres://patientplatypus:SUPERSECRET@db:5432/zennify/?sslmode=disable")
...
func InitDB(dataSourceName string) {
db, _ := sql.Open(dataSourceName)
...
}
同样可以,但是不会持久保存数据。
答案 0 :(得分:1)
我在使用docker-compose运行postgres数据库和Django应用程序时遇到了完全相同的问题。
事实证明,我的应用程序的Dockerfile正在使用执行以下命令的入口点:python manage.py flush
清除数据库中的所有数据。每次启动应用容器时都会执行此操作,因此它将清除所有数据。它与docker-compose无关。
答案 1 :(得分:0)
在环境变量下:
PGDATA 此可选的环境变量可用于为数据库文件定义另一个位置,例如子目录。 默认值为/ var / lib / postgresql / data ,但是如果您使用的数据量是fs挂载点(例如GCE永久磁盘),则 Postgres initdb建议使用一个子目录(用于示例/ var / lib / postgresql / data / pgdata)创建为包含数据。
更多信息在这里-> https://hub.docker.com/_/postgres/
答案 2 :(得分:-1)
Docker命名卷与您正在使用的原始docker-compose保持一致。
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
创建容器和卷。
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)在卷位置上写入文件
docker-compose exec db /bin/bash -c 'echo "File is persisted" > /var/lib/postgresql/data/file-persisted.txt'
3)运行docker-compose down
请注意,按照documentation,当您用尽它时,它不会删除任何卷,只会删除容器和网络。您需要使用-v
运行它才能删除卷。
Stopping docker_db_1 ... done
Removing docker_db_1 ... done
Removing network docker_default
还请注意您的音量仍然存在
docker volume ls | grep pgdata
local docker_pgdata
4)再次运行docker-compose up -d
以启动容器并重新安装卷。
5)查看文件是否仍在卷中
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
命名卷不是主机卷。阅读documentation或查阅一些文章以解释不同之处。另请参阅Docker管理着存储命名卷文件的位置,您可以使用其他驱动程序,但目前最好只是学习基本区别。