当前位置: 首页 > 知识库问答 >
问题:

Docker-compose v3不持久化postgres数据库

充子航
2023-03-14

在docker compose v3容器关闭并重新启动后,我很难持久化postgres数据。这似乎是一个常见的问题,但经过大量搜索,我一直无法找到有效的解决方案。

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

这是我的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撰写而不是持久化数据):

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容器以查看数据库的值,可以执行以下操作:

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

其中backend_db_1是docker容器数据库的名称patentplatypus是我的用户名,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)
    ...
}

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

共有3个答案

史鹏云
2023-03-14

在环境变量下:

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

更多信息请点击此处--

阳勇
2023-03-14

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”文件被持久化

3) 运行docker compose down

请注意,当您运行时,根据文档,它不会删除任何卷,只删除容器和网络。您需要使用-v运行它才能删除卷。

Stopping docker\u db\u 1…done Removing docker\u db\u 1…done Removing network docker\u default

另外请注意,您的卷仍然存在docker volume ls | grep pgdata local docker\u 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 20年8月18日04:40文件persisted。txt

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

屠锦
2023-03-14

我在postgres db和运行docker compose的Django应用程序上遇到了完全相同的问题。

事实证明,我的应用程序的Dockerfile使用了一个入口点,其中执行了以下命令:python manage。py flush,清除数据库中的所有数据。由于每次启动应用程序容器时都会执行此操作,因此会清除所有数据。这与docker compose无关。

 类似资料:
  • 我刚开始使用docker,但我不明白一些事情。我只是使用docker-compose来使用PostgreSQL的基本映像,但我不知道如何在杀死docker甚至删除我的本地映像后使db中的数据持久化。这一切都可能吗? 这是我实际的docker-compose.yml: 也许我应该用体积?怎样

  • 我在我的项目中使用postgres docker映像。对于初始化,我使用以下命令来创建和初始化我的数据库(表、视图、数据…) 复制sql_dump.sql /docker-entrypoint-initdb.d 容器停止和删除后是否可以保留这些数据?例如,当我运行postgres的图像时,它将使用这些数据创建数据库,而每次容器启动时都没有加载脚本。只需加载第一次运行创建的数据。 我做了一些研究,发

  • 我正在使用网络逻辑10.3。我正在尝试配置一个持久订阅,其中包含由 jdbc 存储(在 Oracle DB 中)支持的持久消息。我有一个主题,MDB 正在作为持久订阅者侦听该主题。在场景-1下:如果我发送消息,它会命中MDB。 在场景2中:我挂起了MDB,希望发送到主题的消息只要不被MDB(它是唯一注册的持久订阅者)使用,就会一直存在。但是当我向主题发送消息时,它短暂地出现在那里,然后就消失了(我

  • 我的docker组合文件有三个容器,web、nginx和Postgres。Postgres看起来是这样的: null

  • 问题内容: 我的docker compose文件包含三个容器:web,nginx和postgres。Postgres看起来像这样: 我的目标是安装一个与postgres容器内称为的本地文件夹相对应的卷。当我启动这些容器并将数据插入到postgres中时,我验证了所添加数据的全部内容(在postgres容器中),但是在我的本地系统中,只在其中获得了一个文件夹,即已创建,但它为空。为什么? 笔记: 这