简体   繁体   中英

Connecting Docker Postgres container to an existing empty database

I want to create a tarball that contains an empty db (ie a series of empty tables) and a shell script launching a Postgres container that would connect to the empty db. The end product is a .tar.gz that has a copy of the db, a start script and a stop script. All this is meant to work in macOS

To create the db I started a Postgres server locally on my laptop and created a db called 'postgres-15year'. Using 'DBeaver' database manager and 'psql' at the CLI I can see that the dbase is correctly created and functional.

I then created the following scripts:

start.sh

#!/bin/bash
echo $(pwd)
docker run --rm --name payments-15years -e POSTGRES_PASSWORD=docker -d -p5432:5432 -v$(pwd)/postgres-15year/data:/var/lib/postgresql/data:delegated postgres:11.6

stop.sh

#!/bin/bash
docker stop payments-15years
echo "docker stop payments-15years"

I then put all this in a directory that I would like to tarball.

在此处输入图片说明

So user would receiver the tarball, unpack it and run the start script and be able to connect to a db that has a predefined structure and schemas. Here is what I think 'my start.sh' script is doing:

  1. creating a container name 'payments-15years'
  2. setting the db password for a generic user ('postgres')
  3. setting the db port to 5432 and also mapping it to local server port 5432 (not sure if that's necessary but all the examples seem to do it)
  4. mapping the db to the container's var/lib and 'delegated' as opposed to 'cache' so changes persist
  5. specifying the Postgres docker image as 11.6

My challenge is that after running the start script 'docker ps' returns:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
14d2cba6abe2        postgres:11.6       "docker-entrypoint.s…"   44 seconds ago      Up 42 seconds       0.0.0.0:5432->5432/tcp   payments-15years

But when I do so and then run 'psql' from CLI:

docker exec -it payments-15years psql -U postgres

the database ('postgres-15year') is not listed.

Does anyone see what is wrong with my approach?

NOTE:

  1. I am not providing the db, however it is empty tables with schemas defined and all the above scripts and pictures should be sufficient to recreate the problem.
  2. Closest stack answer I found was here but it didn't help.

Actually when you ran the command with -v $(pwd)/postgres-15year/data:/var/lib/postgresql/data:delegated , According to the official documentation of the postgres-docker .

The -v /my/own/datadir:/var/lib/postgresql/data part of the command mounts the /my/own/datadir directory from the underlying host system as /var/lib/postgresql/data inside the container, where PostgreSQL by default will write its data files.

So you are just creating a data directory not a database. You can check it by using inspect keyword.

docker container inspect <container_name>

In your scenario payments-15years gives volume details of this,

"Mounts": [
            {
                "Type": "bind",
                "Source": "/Users/macair/postgres-15year/data",
                "Destination": "/var/lib/postgresql/data",
                "Mode": "delegated",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

To create a database execute a interactive session as did before and create a db manually or try this.

docker run -it --rm --network some-network postgres psql -h some-postgres -U postgres

Reference to your comment first,

I was able to create the DB using interactive. To populate the empty db with the proper schema I have a pg-dump file (.sql). I'm not sure how to make that file available to the container. Thoughts?

If you have dump file why one should bother to run the command once container up?

Better to make it part of Dockerfile and you will not need to and dump manually Docker image will take care of it.

FROM postgres
ADD mydb.sql /docker-entrypoint-initdb.d

Now if you up the container the DB will be populated automatically.

Initialization scripts

If you would like to do additional initialization in an image derived from this one, add one or more *.sql, *.sql.gz, or *.sh scripts under /docker-entrypoint-initdb.d (creating the directory if necessary). After the entrypoint calls initdb to create the default postgres user and database, it will run any *.sql files, run any executable *.sh scripts, and source any non-executable *.sh scripts found in that directory to do further initialization before starting the service.

postgress init DB

Now come to your question, you can do that with Tarball, tar does not deal with volume while Postgres docker image come with volume . so you need to follow the Dockerfile to import on Data on startup.

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