Comrades, please help a newbie.
I have postgres installed on my Ubuntu 22.04 LTS and I’m trying to learn how to run a postgres container. What am I doing? I downloaded the official image, created a docker file with the following content:
FROM postgres
ENV POSTGRES_PASSWORD docker
ENV POSTGRES_PORT 54322
ENV POSTGRES_DB elibrary
COPY ELibrary_DataBase_Dump_Schema_WithotData_08.07.2022.sql /docker-entrypoint-initdb.d/
USER postgres
RUN /etc/init.d/postgresql restart && pg_restore -U postgres -p 54322 -C -d elibrary < /docker-entrypoint-initdb.d/ELibrary_DataBase_Dump_Schema_WithotData_08.07.2022.sql
No PostgreSQL clusters exist; see "man pg_createcluster" ... (warning).
pg_restore: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.54322" failed: No such file or directory
Is the server running locally and accepting connections on that socket?
What am I doing wrong?
I also have a question, how to make sure that the content of the database itself is somewhere on the main system, so that when the container is deleted, the data does not disappear?
First you copy a sql script into /docker-entrypoint-initdb.d which on it’s own is enough to get the sql script executed the first time the container is started (and the volume mapped to /var/lib/postgres is emtpy). This is part of the postgres base image entrypoint script your image inherits from its base image. There is no need to restore the dump when creating the database.
When building an image, no processes are running inside the container. You start the postgres process with a restart command, which probably leaves behind marks that could be responsible for the problem you experience.
Just create your image like this and it should work
FROM postgres
ENV POSTGRES_PASSWORD docker
ENV POSTGRES_PORT 54322
ENV POSTGRES_DB elibrary
COPY ELibrary_DataBase_Dump_Schema_WithotData_08.07.2022.sql /docker-entrypoint-initdb.d/
USER postgres
You can use a bind to achieve this: docker run ... -v /location/on/host:/var/lib/postgresql/data {image}. A bind will eclipse the content of the container folder with the folder it bind mounts on top of it. If you restore your db dump when building the image, the container will not be able to see it when you bind a host folder into the container folder.
There is a way to use named volumes backed by binds instead of bind volumes, which are able to copy the content of a container folder back into the volume (only the first time when it’s emtpy!) before binding it into the container folder - this way the state in the volume is what the container will see from then on, due to the eclipsing effect, it will not see any changes you did on the database in the image until the volume (and as such your complete dabase state) is removed. I don’t recommend depending on this mechanism at all.
Note: your action to restore the dump while creating the image and your requirement to store the container database files on the host are contractive.
I am pretty sure because /var/lib/postgresql/data is not empty in the container by default.
I am missing the -v argument where you mount an empty folder or a named volume into this folder.
> docker run -it --name my-elibrary-postgres-container -p 54322:5432 -v /location/on/host:/var/lib/postgresql/data rick1177/my-elibrary-postgres-db
chmod: changing permissions of '/var/lib/postgresql/data': Operation not permitted
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/lib/postgresql/data ... initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
You need to make sure the uid/gid of the postgres container is the same as the owner of the host folder you are adding in. This should have beenexplained even in the most basic tutorials.
May I suggest this fabulous free docker training: Introduction to Containers. Docker is more fun if you know the basics and have a solid foundation about the concepts and how things are supposed to be used. Don’t be intimidated by the number of slides, most slides can be easily processed - just make sure you do the hand-on examples.
> id
uid=1000(rick1177) gid=1000(rick1177) группы=1000(rick1177),4(adm),24(cdrom),27(sudo),29(audio),30(dip),46(plugdev),109(kvm),122(lpadmin),134(lxd),135(sambashare),137(vboxsf),138(docker),141(libvirt)
Please consult the postgres dockerhub description regarding volumes and ownership. As we both need to look at the description, I leave the part to you.
The overall result of successfully fixing the problem, i.e. launching Potgres with a pre-installed base scheme:
first you need to create ladies databases not from the postgres graphic design, but I use the command line (well, or I don’t know how to create a normal dump with pg_admin), I use the command:
Seems the USER postgres instruction from your original Dockerfile was causing the problem - I didn’t validate wether it makes sense of not. Though, it would be a good explaination why the permissions issues took place.
Regarding your CMD instruction:
A containers starts whetever is defined as ENTRYPOINT and uses CMD as argument to it. Since the base image already declares “docker-entrypoint.sh” as ENTRYPOINT and “postgres” as CMD, your CMD instruction a) results in “docker-entrypoint.sh docker-entrypoint.sh postgres” beeing executed when the container is started and b) can be removed all along as it already inherits the correct CMD form the base image.