简体   繁体   中英

How to create a persistent data volume for Postgres Database container in docker swarm

I have several Postgresql services, and some other services which useful in my case (for creating HA Postgresql cluster). This cluster is described in docker-compose below:

    version: '3.3'
services:

  haproxy:
    image: haproxy:alpine
    ports:
        - "5000:5000"
        - "5001:5001"
        - "8008:8008"
    configs: 
      - haproxy_cfg
    networks:
      - dbs
    command: haproxy -f /haproxy_cfg

  etcd:
    image: quay.io/coreos/etcd:v3.1.2
    configs:
      - etcd_cfg
    networks: 
      - dbs
    command: /bin/sh /etcd_cfg

  dbnode1:
    image: seocahill/patroni:1.2.5
    secrets: 
      - patroni.yml
    environment:
      - PATRONI_NAME=dbnode1
      - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode1
      - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode1:5432
      - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode1:8008
    env_file:
      - test.env
    networks:
      - dbs
    entrypoint: patroni
    command: /run/secrets/patroni.yml

  dbnode2:
    image: seocahill/patroni:1.2.5
    secrets: 
      - patroni.yml
    environment:
      - PATRONI_NAME=dbnode2
      - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode2
      - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode2:5432
      - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode2:8008
    env_file:
      - test.env
    networks:
      - dbs
    entrypoint: patroni
    command: /run/secrets/patroni.yml

  dbnode3:
    image: seocahill/patroni:1.2.5
    secrets: 
      - patroni.yml
    environment:
      - PATRONI_NAME=dbnode3
      - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode3
      - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode3:5432
      - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode3:8008
    env_file:
      - test.env
    networks:
      - dbs
    entrypoint: patroni
    command: /run/secrets/patroni.yml

networks:
  dbs:
    external: true

configs:
  haproxy_cfg:
    file: config/haproxy.cfg
  etcd_cfg:
    file: config/etcd.sh

secrets:
  patroni.yml:
    file: patroni.test.yml

I took this yml-code from https://github.com/seocahill/ha-postgres-docker-stack.git . And i use next command to deploy this services in docker swarm - docker network create -d overlay --attachable dbs && docker stack deploy -c docker-stack.test.yml test_pg_cluster . But if i create some databases and insert some data to it and then restart servies - my data will be lost. I know that i need to use volume for saving data on host. I create volume with docker command: docker volume create pgdata with default docker volume directory and mount it like this:

dbnode1:
        image: seocahill/patroni:1.2.5
        secrets: 
          - patroni.yml
        environment:
          - PATRONI_NAME=dbnode1
          - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode1
          - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode1:5432
          - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode1:8008
        env_file:
          - test.env
        volumes:
          pgdata:/data/dbnode1
        networks:
          - dbs
        entrypoint: patroni
        command: /run/secrets/patroni.yml

        volumes:
           pgdata:

When container started it has own configs in data directory data/dbnode1 inside container. And if i mount volume pgdata for store data in host, i can't connect to db and there is empty folder in container directory data/dbnode1 . How can i create a persistent data volume for saving changed data in PostgerSQL?

It is way easier to create volumes by adding the path directly. Check this example.

dbnode1:
        image: seocahill/patroni:1.2.5
        secrets: 
          - patroni.yml
        environment:
          - PATRONI_NAME=dbnode1
          - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode1
          - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode1:5432
          - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode1:8008
        env_file:
          - test.env
        volumes:
          - /opt/dbnode1/:/data/dbnode1
        networks:
          - dbs
        entrypoint: patroni
        command: /run/secrets/patroni.yml

Note the lines

        volumes:
          - /opt/dbnode1/:/data/dbnode1

where I am using a the path /opt/dbnode1/ to store the filesystem from the container at /data/dbnode1 .

Also it is important to note that docker swarm does not create folders for you. Thus, you have to create the folder before starting the service. Run mkdir -p /opt/dbnode1 to do so.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM