Permission issue while running Dockerfile for Fhirbase - postgresql

I followed the steps provided in https://www.health-samurai.io/fhirbase website, using the Fhirbase in Docker and Download Fhirbase both are working perfectly without any issue.
Now, I want to put Fhirbase code (https://github.com/fhirbase/fhirbase?_ga=2.137200179.2086351274.1637554537-194486469.1637215452) into my private gitlab repo and I want run my gitlab fhirbase code In Docker using Dockerfile.
I have created a Dockerfile as below --
FROM postgres:10.5
WORKDIR /fhirbase
COPY demo/bundle.ndjson.gzip .
RUN apt-get update
RUN apt-get install -y git
RUN git clone https://gitlab.com/username/fhirbase.git /usr/bin/fhirbase
CMD cd /usr/bin/fhirbase
RUN ["chmod", "+x", "/usr/bin/fhirbase"]
CMD make
CMD hash -r
CMD make install
RUN mkdir /pgdata && chown postgres:postgres /pgdata
USER postgres
RUN PGDATA=/pgdata /docker-entrypoint.sh postgres & \
until psql -U postgres -c '\q'; do \
>&2 echo "Postgres is starting up in first..."; \
sleep 5; \
done && \
psql -U postgres -c 'create database fhirbase;' && \
fhirbase -d fhirbase init && \
fhirbase -d fhirbase load --mode=insert ./bundle.ndjson.gzip; \
pg_ctl -D /pgdata stop
#EXPOSE 3000
EXPOSE 3000
CMD pg_ctl -D /pgdata start && until psql -U postgres -c '\q'; do \
>&2 echo "Postgres is starting up..."; \
sleep 5; \
done && \
exec fhirbase -d fhirbase web
When I run the above dockerfile getting the below error--
D:\FhirBase\fhirbase>docker run d6ba47544a36
waiting for server to start....2021-11-26 12:37:23.322 UTC [11] LOG: listening on IPv4 address "0.0.0.0", port 5432
2021-11-26 12:37:23.323 UTC [11] LOG: listening on IPv6 address "::", port 5432
2021-11-26 12:37:23.390 UTC [11] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2021-11-26 12:37:23.483 UTC [12] LOG: database system was shut down at 2021-11-26 12:28:08 UTC
2021-11-26 12:37:23.556 UTC [11] LOG: database system is ready to accept connections
done
server started
/bin/sh: 1: exec: fhirbase: Permission denied
Please help me regarding the dockerfile.

Related

pg_upgrade port 50432 failed: fe_sendauth: no password supplied

I want to try my first upgrade from postgres 15.1 to 15.2
no instance is started,I run init on new dir:
d:\_dev_\postgres\pgsql\bin\initdb.exe -D d:\_dev_\postgres\pgsql\data
-U postgres -W -E UTF8 -A scram-sha-256
then
I've create a cmd file:
SET PGPASSWORD=xxxx
SET PATH=%PATH%;d:\_dev_\postgres\pgsql\bin;
pg_upgrade.exe
--old-datadir "d:\_dev_\postgres\OLD_pgsql\data"
--new-datadir "d:\_dev_\postgres\pgsql\data"
--old-bindir "d:\_dev_\postgres\OLD_pgsql\bin"
--new-bindir "d:\_dev_\postgres\pgsql\bin"
but got:
Checking cluster versions ok
connection to server at "localhost" (::1), port 50432 failed: FATAL: password authentication failed for user "user"
could not connect to source postmaster started with the command:
"d:/_dev_/postgres/Vpgsql/bin/pg_ctl" -w -l "d:/_dev_/postgres/pgsql/data/pg_upgrade_output.d/20230210T102433.178/log/pg_upgrade_server.log" -D "d:/_dev_/postgres/Vpgsql/data" -o "-p 50432 -b " start
Failure, exiting

Customize postgres start command in default docker postgres image

I want to change the start command of postgres to support SSL in the default docker image
db.Docerfile
FROM postgres:14.5-alpine
COPY ./.docker/dev/init-database.sh /docker-entrypoint-initdb.d/
COPY ./.docker/dev/migrations/database_schema.tar ./
COPY ./.docker/dev/certs/out/server.key /var/lib/postgresql
COPY ./.docker/dev/certs/out/server.crt /var/lib/postgresql
COPY ./.docker/dev/certs/out/myCA.crt /var/lib/postgresql
COPY ./.docker/dev/certs/out/myCA.crl /var/lib/postgresql
COPY ./.docker/dev/certs/out/news_user.key ./
COPY ./.docker/dev/certs/out/news_user.crt ./
RUN chown 0:70 /var/lib/postgresql/server.key && chmod 640 /var/lib/postgresql/server.key
RUN chown 0:70 /var/lib/postgresql/server.crt && chmod 640 /var/lib/postgresql/server.crt
RUN chown 0:70 /var/lib/postgresql/myCA.crt && chmod 640 /var/lib/postgresql/myCA.crt
RUN chown 0:70 /var/lib/postgresql/myCA.crl && chmod 640 /var/lib/postgresql/myCA.crl
RUN chown 0:70 ./news_user.key && chmod 640 ./news_user.key
RUN chown 0:70 ./news_user.crt && chmod 640 ./news_user.crt
RUN chown postgres:postgres /docker-entrypoint-initdb.d/init-database.sh
EXPOSE 5432
CMD postgres -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key -c ssl_ca_file=/var/lib/postgresql/myCA.crt -c ssl_crl_file=/var/lib/postgresql/myCA.crl
When I run this image, I get an error saying
"root" execution of the PostgreSQL server is not permitted.
news_database | The server must be started under an unprivileged user ID to prevent
news_database | possible system security compromise. See the documentation for
news_database | more information on how to properly start the server.
The default postgres image comes with a user named postgres so I tried adding a user postgres line before CMD
Now it gives me a new error saying
postgres: could not access the server configuration file "/var/lib/postgresql/data/postgresql.conf": No such file or directory
Can someone kindly tell me how to fix this so that the postgres command works?
UPDATE 1
I am not running the dockerfile directly, I run it via a docker-compose.yml file since I have a python script that accesses the database in another container
docker.compose.yml
version: "3.8"
services:
news_database:
build:
context: ../..
dockerfile: ./.docker/dev/db.Dockerfile
container_name: news_database
restart: unless-stopped
env_file:
- .env
ports:
- "5432:5432"
volumes:
- news_db:/var/lib/postgresql/data
# https://stackoverflow.com/a/55835081/5371505
# https://stackoverflow.com/questions/72213661/test-connection-to-postgres-with-ssl-with-the-command-line
healthcheck:
test: ["CMD-SHELL", "pg_isready -d 'hostaddr=$DATABASE_HOST user=$DATABASE_USER port=$DATABASE_PORT dbname=$DATABASE_NAME'"]
interval: 5s
timeout: 5s
retries: 5
# Dont add a 'restart' policy to the app because we run it as a cronjob regardless of whether it succeeds or fails
news_app:
# https://stackoverflow.com/questions/65594752/docker-compose-how-to-reference-files-in-other-directories
build:
context: ../..
dockerfile: ./.docker/dev/app.Dockerfile
env_file:
- .env
image: news_app
container_name: news_app
depends_on:
news_database:
condition: service_healthy
volumes:
news_db:
driver: local
I run the above file with this command
docker compose -f ".docker/dev/docker-compose.yml" up -d --build news_database && docker compose -f ".docker/dev/docker-compose.yml" logs --follow
I see a couple of problems with your Dockerfile. First, I've stripped out a few bits to reduce the complexity to something I can reproduce locally, so I have:
FROM postgres:14.5-alpine
COPY ./certs/out/server.key /var/lib/postgresql
COPY ./certs/out/server.crt /var/lib/postgresql
RUN chown 0:70 /var/lib/postgresql/server.key && chmod 640 /var/lib/postgresql/server.key
RUN chown 0:70 /var/lib/postgresql/server.crt && chmod 640 /var/lib/postgresql/server.crt
EXPOSE 5432
CMD postgres -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key -c ssl_ca_file=/var/lib/postgresql/myCA.crt -c ssl_crl_file=/var/lib/postgresql/myCA.crl
If we build a pgtest image from this Dockerfile and run it, we see:
$ docker build -t pgtest .
...
$ docker run --rm pgtest
"root" execution of the PostgreSQL server is not permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromise. See the documentation for
more information on how to properly start the server.
What's going on here? It turns out this is caused by how you've written your CMD directive. You need to use the "exec style", which means passing in a JSON array rather than a string:
CMD ["postgres", \
"-c", "ssl=on", \
"-c", "ssl_cert_file=/var/lib/postgresql/server.crt", \
"-c", "ssl_key_file=/var/lib/postgresql/server.key"]
This is necessary because there's a check in the entrypoint script for
the image that looks like this:
if [ "$1" = 'postgres' ] && ! _pg_want_help "$#"; then
When you write:
CMD postgres -c ...
This wraps the command in a call to sh -c, so $1 will be sh,
thus skipping the important database initialization logic. When we use
the exec format of the CMD statement, $1 will be postgres, as
expected.
With that fix, the image runs correctly:
$ docker run --rm -e POSTGRES_PASSWORD=secret pgtest
.
.
.
PostgreSQL init process complete; ready for start up.
2022-08-28 12:48:48.784 UTC [1] LOG: starting PostgreSQL 14.5 on x86_64-pc-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit
2022-08-28 12:48:48.784 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2022-08-28 12:48:48.784 UTC [1] LOG: listening on IPv6 address "::", port 5432
2022-08-28 12:48:48.786 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2022-08-28 12:48:48.789 UTC [48] LOG: database system was shut down at 2022-08-28 12:48:48 UTC
2022-08-28 12:48:48.792 UTC [1] LOG: database system is ready to accept connections

PostgreSQL on container throws an error chmod: /var/lib/postgresql/data: Operation not permitted

I have tried to run Postgres 12 on the docker and the following files I have created. I do not understand where do I made a mistake and what is an issue of PostgreSQL file permission.
Dockerfile:
FROM postgres:12.0-alpine
USER root
RUN chmod 0775 /var/lib/postgresql
RUN chown postgres /var/lib/postgresql
USER postgres
# RUN chmod 0775 /var/lib/postgresql
# RUN chown postgres /var/lib/postgresql
RUN ls -l /var/lib/postgresql
# RUN pgctl -D /usr/local/psql/data initdb &&\
RUN initdb -D /var/lib/postgresql/data &&\
echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf && \
echo "listen_addresses='*'" >> /var/lib/postgresql/data/postgresql.conf && \
pg_ctl start && \
psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'test'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE test" && \
psql --command "ALTER USER postgres WITH ENCRYPTED PASSWORD '123';"
# RUN initdb /var/lib/postgresql/data &&\
# echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf && \
# echo "listen_addresses='*'" >> /var/lib/postgresql/data/postgresql.conf && \
# pg_ctl start && \
# psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'test'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE test" && \
# psql --command "ALTER USER postgres WITH ENCRYPTED PASSWORD '123';"
# Add VOLUMEs to allow backup of config, logs and databases
VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
EXPOSE 5432
docker-compose.yml
version: "3.7"
services:
postgresql:
build:
context: .
dockerfile: ./../postgresql/Dockerfile
volumes:
- ../postgresql/db_data:/var/lib/postgresql/data
ports:
- 5432:5432
I have run following command in terminal
docker-compose up
The following error occurs.
Building mydb_postgresql
Step 1/6 : FROM postgres:12-alpine
---> ecb176ff304a
Step 2/6 : USER postgres
---> Running in ee9fe8ed246f
Removing intermediate container ee9fe8ed246f
---> 8dfa002a5fab
Step 3/6 : RUN ls -l /var/lib/postgresql
---> Running in 08d98e1ea7b2
total 4
drwxrwxrwx 2 postgres postgres 4096 Mar 23 23:58 data
Removing intermediate container 08d98e1ea7b2
---> 548bb96ed8db
Step 4/6 : RUN initdb -D /var/lib/postgresql/data && echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf && echo "listen_addresses='*'" >> /var/lib/postgresql/data/postgresql.conf && pg_ctl start && psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'mydb'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE mydb" && psql --command "ALTER USER postgres WITH ENCRYPTED PASSWORD '123';"
---> Running in dbee0a2346df
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 ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... sh: locale: not found
2020-04-17 18:16:13.112 UTC [11] WARNING: no usable system locales were found
ok
syncing data to disk ... ok
Success. You can now start the database server using:
pg_ctl -D /var/lib/postgresql/data -l logfile start
initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
waiting for server to start....2020-04-17 18:16:13.427 UTC [15] LOG: starting PostgreSQL 12.2 on x86_64-pc-linux-musl, compiled by gcc (Alpine 9.2.0) 9.2.0, 64-bit
2020-04-17 18:16:13.427 UTC [15] LOG: listening on IPv4 address "0.0.0.0", port 5432
2020-04-17 18:16:13.427 UTC [15] LOG: listening on IPv6 address "::", port 5432
2020-04-17 18:16:13.433 UTC [15] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2020-04-17 18:16:13.447 UTC [16] LOG: database system was shut down at 2020-04-17 18:16:13 UTC
2020-04-17 18:16:13.451 UTC [15] LOG: database system is ready to accept connections
done
server started
CREATE DATABASE
ALTER ROLE
Removing intermediate container dbee0a2346df
---> 8fd449f2a9e2
Step 5/6 : VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
---> Running in 76f4b6ee235e
Removing intermediate container 76f4b6ee235e
---> 343b2ddca9d2
Step 6/6 : EXPOSE 5432
---> Running in 306d1fd18818
Removing intermediate container 306d1fd18818
---> aa732eb5b2b6
Successfully built aa732eb5b2b6
Successfully tagged services_mydb_postgresql:latest
WARNING: Image for service mydb_postgresql was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating services_mydb_postgresql_1 ... done
Attaching to services_mydb_postgresql_1
mydb_postgresql_1 | chmod: /var/lib/postgresql/data: Operation not permitted
services_mydb_postgresql_1 exited with code 1
I don't know what is going on and why my process has stopped.

How to run the python application and postgres in one docker container?

I have a python application that interacts with the postgresql database and i need to run it all in one docker container.
I get a connection error when running the container:
...
File "/usr/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
return fut.result()
File "/usr/lib/python3.6/asyncio/base_events.py", line 787, in create_connection
', '.join(str(exc) for exc in exceptions)))
OSError: Multiple exceptions: [Errno 111] Connect call failed ('::1', 5432), [Errno 111] Connect call failed ('127.0.0.1', 5432)
My Dockerfile:
FROM postgres:10.0-alpine
RUN apk add --update --no-cache g++ alpine-sdk
RUN apk --no-cache add python3-dev
RUN apk add --no-cache python3 && \
python3 -m ensurepip && \
rm -r /usr/lib/python*/ensurepip && \
pip3 install --upgrade pip setuptools && \
if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi && \
if [[ ! -e /usr/bin/python ]]; then ln -sf /usr/bin/python3 /usr/bin/python; fi && \
rm -r /root/.cache
ADD app /app/
RUN chmod -R 777 /app
WORKDIR /app
ADD requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
USER postgres
RUN chmod 0700 /var/lib/postgresql/data &&\
initdb /var/lib/postgresql/data &&\
echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf &&\
echo "listen_addresses='*'" >> /var/lib/postgresql/data/postgresql.conf &&\
pg_ctl start &&\
psql --command "ALTER USER postgres WITH ENCRYPTED PASSWORD 'postgres';"
EXPOSE 5432
EXPOSE 80
CMD ["python3", "main.py"]
Although this is not recommended, it's doable. The problem is pg_ctl in RUN instruction is executed at build time, not in the container. You need to run it with CMD.
You can have a script like
pg_ctl start
psql --command "ALTER USER postgres WITH ENCRYPTED PASSWORD 'postgres';"
python3 main.py
COPY the script in the image and at the end of the dockerfile, `CMD ["./script.sh"]
#Anton, it is not recommended to run multiple processes inside a docker container. Have a look at this link https://docs.docker.com/config/containers/multi-service_container/ it will explain more and demonstrate a manner to accomplish this. You probably are aware, but your container will be running the postgresql instance and have the data in it, so if you ever re-create the container, you will lose any data in that container.

How to run Postgres in a docker Alpine Linux container?

I'm trying to get Postgresql 10.0 working in a docker container. I have the following Dockerfile:
FROM postgres:10.0-alpine
RUN apk add openrc --no-cache
USER postgres
RUN /etc/init.d/postgresql start
RUN psql --command "IF NOT EXISTS (SELECT FROM pg_catalog.pg_user WHERE usename = 'user') THEN CREATE USER user WITH SUPERUSER ENCRYPTED PASSWORD 'password'; END IF;"
RUN createdb main
EXPOSE 5432
VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
CMD ["/usr/lib/postgresql/10.0/bin/postgres", "-D", "/var/lib/postgresql/10.0/main", "-c", "config_file=/etc/postgresql/10.0/main/postgresql.conf"]
I got following error:
/bin/sh: /etc/init.d/postgresql: not found
Seems that /etc/init.d/postgresql is really missing. What am I doing wrong?
I finished with this Dockerfile:
FROM postgres:10.0-alpine
USER postgres
RUN chmod 0700 /var/lib/postgresql/data &&\
initdb /var/lib/postgresql/data &&\
echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf &&\
echo "listen_addresses='*'" >> /var/lib/postgresql/data/postgresql.conf &&\
pg_ctl start &&\
psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'main'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE main" &&\
psql -c "ALTER USER postgres WITH ENCRYPTED PASSWORD 'mysecurepassword';"
EXPOSE 5432
This dockerfile create database 'main' (if not exists), starts postgres and sets default user password
I was able to do it using exec commands, so I can run postgres in a running container, in this case alpine 3.7. Note $CONTAINER_NAME is the container id from docker ps:
# Install postgresql, create user, db & start the daemon (for testing)
sudo docker exec $CONTAINER_NAME sh -c 'apk add postgresql'
sudo docker exec $CONTAINER_NAME sh -c 'addgroup -S postgres && adduser -S postgres -G postgres'
sudo docker exec $CONTAINER_NAME sh -c 'mkdir -p /var/lib/postgresql/data'
sudo docker exec $CONTAINER_NAME sh -c 'mkdir -p /run/postgresql/'
sudo docker exec $CONTAINER_NAME sh -c 'chown -R postgres:postgres /run/postgresql/'
sudo docker exec $CONTAINER_NAME sh -c 'chmod -R 777 /var/lib/postgresql/data'
sudo docker exec $CONTAINER_NAME sh -c 'chown -R postgres:postgres /var/lib/postgresql/data'
sudo docker exec --user postgres $CONTAINER_NAME sh -c 'initdb /var/lib/postgresql/data'
sudo docker exec --user postgres $CONTAINER_NAME sh -c 'echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf'
sudo docker exec --user postgres $CONTAINER_NAME sh -c 'pg_ctl start -D /var/lib/postgresql/data -l /var/lib/postgresql/log.log'
sudo docker exec --user postgres $CONTAINER_NAME sh -c "psql --command \"ALTER USER postgres WITH ENCRYPTED PASSWORD 'buildpgpass';\""
sudo docker exec --user postgres $CONTAINER_NAME sh -c "psql --command \"CREATE DATABASE builddb;\""
You can also include this in your Dockerfile like so:
# Postgres
RUN apk add postgresql=11.1-r0
RUN (addgroup -S postgres && adduser -S postgres -G postgres || true)
RUN mkdir -p /var/lib/postgresql/data
RUN mkdir -p /run/postgresql/
RUN chown -R postgres:postgres /run/postgresql/
RUN chmod -R 777 /var/lib/postgresql/data
RUN chown -R postgres:postgres /var/lib/postgresql/data
RUN su - postgres -c "initdb /var/lib/postgresql/data"
RUN echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf
RUN su - postgres -c "pg_ctl start -D /var/lib/postgresql/data -l /var/lib/postgresql/log.log && psql --command \"ALTER USER postgres WITH ENCRYPTED PASSWORD 'postgres';\" && psql --command \"CREATE DATABASE builddb;\""
This seems to work great if you want to test something out on the fly.
There are multiple problems with your dockerfile. I guess you are trying to start the server when building the image to create the main database. This won't work since each command in the dockefile will execute in its own layer, and thus when you reach RUN psql ... the database won't be started since it was started in a different layer. So you need to group the commands in one line.
Second problem is that the file /etc/init.d/postgresql does not exist. The server can be started using the postgres command:
RUN postgres &\
psql --command "IF NOT EXISTS (SELECT FROM pg_catalog.pg_user WHERE usename = 'user')\
THEN CREATE USER user WITH SUPERUSER ENCRYPTED PASSWORD 'password'; END IF;" &\
createdb main