代码之家  ›  专栏  ›  技术社区  ›  Peter Weyand

Docker compose v3未持久化postgres数据库

  •  1
  • Peter Weyand  · 技术社区  · 6 年前

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

    How to persist data in a dockerized postgres database using volumes ,但解决方案不起作用-因此请不要关闭。我将通过下面的所有步骤来复制这个问题。

    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)
    

    _, 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的版本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 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"
    

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

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

    2 回复  |  直到 6 年前
        1
  •  3
  •   bartaelterman    4 年前

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

    python manage.py flush 清除数据库中的所有数据。由于每次应用程序容器启动时都会执行此操作,因此会清除所有数据。这与docker无关。

        2
  •  0
  •   Trung Nguyen    6 年前

    在环境变量下:

    此可选环境变量可用于为数据库文件定义另一个位置(如子目录)。 默认值是/var/lib/postgresql/data ,但如果您使用的数据卷是fs装入点(如GCE永久磁盘),

    https://hub.docker.com/_/postgres/

        3
  •  0
  •   Bizmate    6 年前

    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:
    

    如何证明?

    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'

    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) 跑 码头工人 再次启动容器并重新装载卷。

    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管理它存储命名卷文件的位置,您可以使用不同的驱动程序,但目前最好您只是了解基本的区别。