首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Docker v3不持久化postgres数据库

Docker v3不持久化postgres数据库
EN

Stack Overflow用户
提问于 2018-08-19 14:16:09
回答 3查看 6.2K关注 0票数 5

在停靠-组合v3容器被取下并重新启动后,我很难持久化postgres数据。这似乎是一个常见的问题,但经过大量的搜索,我一直未能找到一个可行的解决方案。

我的问题类似于这里:如何使用卷持久化postgres数据库中的数据,但解决方案不起作用-所以请不要关闭。我将通过下面的所有步骤来复制这个问题。

这是我的停靠-撰写文件:

代码语言:javascript
复制
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:

以下是我打开终端并将其写入数据库后的终端输出:

代码语言:javascript
复制
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表的输出:

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

所以,写到数据库曾经有效!

然而,

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

代码语言:javascript
复制
$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中的表,它就是空的:

代码语言:javascript
复制
zennify=# TABLE userinfo;
 email | password | regstring | regbool | uid 
-------+----------+-----------+---------+-----
(0 rows)

我曾想过,在初始化步骤中,我可能是在重写代码中的表,但我只重写了表(golang代码段):

代码语言:javascript
复制
_, 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);")

当然,只有在以前没有创建表的情况下,才应该创建该表。

有人对出了什么问题有什么建议吗?据我所知,这肯定是对接者编写的问题,而不是我的代码。谢谢你的帮助!

编辑:

我研究了使用版本2的docker,并通过使用以下撰写方式遵循了本文(码头工人组成不持久化数据)中所示的格式:

代码语言:javascript
复制
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 stopdocker-compose start,对数据的持久性没有实质性影响。在重新启动的过程中仍然不会持续。

编辑:

还有几件事我一直在查。如果您想要正确地执行到docker容器中以查看数据库的值,则可以执行以下操作:

代码语言:javascript
复制
docker exec -it backend_db_1 psql -U patientplatypus -W zennify

其中,backend_db_1是码头容器数据库的名称,patientplatypus是我的用户名,zennify是数据库容器中数据库的名称。

我还尝试添加了一个网络桥,但没有成功,如下所示:

代码语言:javascript
复制
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命令应该是什么样子的最新想法:

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

同样,这是可行的,但它不持久化数据。

EN

回答 3

Stack Overflow用户

发布于 2020-10-16 19:03:12

在postgres和一个Django应用程序中,我遇到了完全相同的问题,后者运行在中。

结果,我的应用程序的Dockerfile使用了一个入口点,其中执行了以下命令:python manage.py flush,它清除数据库中的所有数据。当应用程序容器每次启动时都会执行此操作,因此它会清除所有数据。这和码头工没有任何关系。

票数 8
EN

Stack Overflow用户

发布于 2018-08-20 04:55:14

名为“卷”的Docker将持久化,使用的是您正在使用的原始停靠器-组合。

代码语言:javascript
复制
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创建容器和卷。

代码语言:javascript
复制
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

注意,当您运行下去时,它不会删除任何卷,只删除容器和网络,就像按照文档那样。您需要使用-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

命名卷不是宿主卷。阅读文档或查阅一些文章来解释这种差异。另外,请参见Docker管理其存储命名卷文件的位置,您可以使用不同的驱动程序,但就目前而言,您最好了解一下基本的区别。

票数 1
EN

Stack Overflow用户

发布于 2018-08-19 14:44:27

在环境变量项下:

PGDATA这个可选环境变量可用于为数据库文件定义另一个位置(如子目录)。默认为/var/lib/postgresql/,但如果您使用的数据卷是fs挂载点(与GCE持久磁盘类似),则Postgres initdb建议创建一个子目录(例如/var/lib/postgresql/ data /pgdata )以包含数据。

这里有更多信息-> /postgres/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51918544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档