Oracle XE ( 11.2.0 ) Database Configuration failed on Ubunto 14 and 16 - database

I am facing Error while configuring Oracle XE after installation.
I Follow this Tutorial
https://askubuntu.com/questions/566734/how-to-install-oracle-11gr2-on-ubuntu-14-04
When I run this statement for database Configuration.
/etc/init.d/oracle-xe configure
I face this Error after input ports and password
Do you want Oracle Database 11g Express Edition to be started on boot (y/n) [y]:y
Starting Oracle Net Listener...Done
Configuring database...
**Database Configuration failed. Look into /u01/app/oracle/product/11.2.0/xe/config/log for details**
I guess it maybe memory Target size issue.
I Tried this
nano /u01/app/oracle/product/11.2.0/xe/config/scripts/init.ora
comment # memory_target=100663296
but It won't work work for me.
Error Log.
PostDbCreation.log
begin
*
ERROR at line 1:
ORA-01034: ORACLE not available
Process ID: 0
Session ID: 0 Serial number: 0
File created.
ORA-01034: ORACLE not available
ORA-27101: shared memory realm does not exist
Linux-x86_64 Error: 2: No such file or directory
ORA-00845: MEMORY_TARGET not supported on this system
select 'utl_recomp_begin: ' || to_char(sysdate, 'HH:MI:SS') from dual
*
ERROR at line 1:
ORA-01034: ORACLE not available
Process ID: 0
Session ID: 0 Serial number: 0
BEGIN utl_recomp.recomp_serial(); END;
*
ERROR at line 1:
ORA-01034: ORACLE not available
Process ID: 0
Session ID: 0 Serial number: 0
select 'utl_recomp_end: ' || to_char(sysdate, 'HH:MI:SS') from dual
*
ERROR at line 1:
ORA-01034: ORACLE not available
Process ID: 0
Session ID: 0 Serial number: 0

The best would be to start from the beginning.
Step 1 - Installation of SSH server
sudo apt install openssh-server
Step 2 - Execute the following commands (pre-requisite packages)
sudo apt-get install alien libaio1 unixodbc vim
Step 3 - Download the Oracle 11g express edition setup file from Oracle website http://www.oracle.com/technetwork/database/database-technologies/express-edition/downloads/index.html . Then go to folder where you have downloaded the setup file (rpm) and convert it to debian type (deb):
sudo alien --scripts -d oracle-xe-11.2.0-1.0.x86_64.rpm
Step 4 - Execute the pre-requisites,
Create a special chkconfig script:
sudo vim /sbin/chkconfig
and add following into the file:
#!/bin/bash
file=/etc/init.d/oracle-xe
if [[ ! `tail -n1 $file | grep INIT` ]]; then
echo >> $file
echo '### BEGIN INIT INFO' >> $file
echo '# Provides: OracleXE' >> $file
echo '# Required-Start: $remote_fs $syslog' >> $file
echo '# Required-Stop: $remote_fs $syslog' >> $file
echo '# Default-Start: 2 3 4 5' >> $file
echo '# Default-Stop: 0 1 6' >> $file
echo '# Short-Description: Oracle 11g Express Edition' >> $file
echo '### END INIT INFO' >> $file
fi
update-rc.d oracle-xe defaults 80 01
Save the above file and provide appropriate permissions
sudo chmod 755 /sbin/chkconfig
Execute the following commands:
free -m
sudo ln -s /usr/bin/awk /bin/awk
mkdir /var/lock/subsys
touch /var/lock/subsys/listener
Execute the below which prevents oracle installation errors. It is weird but helped in my case. Ignore errors that will appear.
sudo -s
umount /dev/shm
sudo rm -rf /dev/shm
sudo mkdir /dev/shm
mount --move /run/shm /dev/shm
sudo mount -t tmpfs shmfs -o size=2048m /dev/shm
Step 5 - Create the below file,
sudo vim /etc/rc2.d/S01shm_load
Copy content below into the opened file:
#!/bin/sh case "$1"
in start) mkdir /var/lock/subsys 2>/dev/null
touch /var/lock/subsys/listener
rm /dev/shm 2>/dev/null
mkdir /dev/shm 2>/dev/null
mount -t tmpfs shmfs -o size=2048m /dev/shm ;;
*) echo error
exit 1 ;;
esac
Execute the following command
sudo chmod 755 /etc/rc2.d/S01shm_load
Step 6 - Restart the machine.
Step 7 - Install Oracle 11gR2 XE. Go to the directory where you created the ubuntu package file and enter following commands (not as root user),
sudo dpkg --install oracle-xe_11.2.0-2_amd64.deb
sudo /etc/init.d/oracle-xe configure
Enter the following configuration information:
Valid HTTP port for the Oracle Application Express (the default is 8080, use 7070)
Valid port for the Oracle database listener (the default is 1521)
Password for the SYS and SYSTEM administrative user accounts
Confirm password for SYS and SYSTEM administrative user accounts
Whether you want the database to start automatically when the computer starts, Y
Step 8 - Before you start using Oracle 11gR2 XE you have to set-up few things more.
Change to users home directory (type cd)
Open bashrc using the command
vim .bashrc
Add following lines to .bashrc :
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe
export ORACLE_SID=XE
export NLS_LANG=`$ORACLE_HOME/bin/nls_lang.sh`
export ORACLE_BASE=/u01/app/oracle
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export PATH=$ORACLE_HOME/bin:$PATH
Execute .profile to load the changes:
. ./.profile
Open root bash using
sudo vim /root/.bashrc
and copy the same contents at the end of that file
Step 9 - Restart the appliance. Oracle should have been started now
Step 10 - Execute the following command to enter SQL prompt
sqlplus sys as sysdba

Related

Postgres Docker importing SQL dump on docker build

I'm trying to get rid of Docker-In-Docker, therefore I'm replacing our Postgres images with new ones. For a use case we use a pre-filled Postgres image. The old workflow is to build the image, pull it in a pipeline and use Docker-In-Docker to fill it with data, then re-upload it to the Image registry again.
The new approach is to create the Postgres image with docker, and I've copied the .sql Dumps to /docker-entrypoint-initdb.d/. But this fills the image after the startup, I'd like to have a pre-filled image in the container registry because the filling takes up to 2 minutes.
This is my Dockerfile:
FROM postgres:11.12
LABEL maintainer="Hello Stackoverflow"
ARG POSTGRES_VERSION="11.12"
ARG TZ="Europe/Berlin"
ENV TZ ${TZ}
ENV LANG de_DE.UTF-8
ENV LANGUAGE de_DE.UTF-8
ENV LC_ALL de_DE.UTF-8
ENV POSTGRES_PASSWORD 'blabla'
ENV POSTGRES_HOST_AUTH_METHOD trust
RUN set -x && \
localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8
COPY test-data/. /docker-entrypoint-initdb.d/
CMD ["postgres"]
In the test-datafolder is a shell-script which executes the filling
#!/bin/sh
cd /docker-entrypoint-initdb.d
echo "read one.sql"
psql -v ON_ERROR_STOP=1 -U postgres < sql/one.sql
echo "read two.sql"
...
...
...
So the idea is to pre-fill the Postgres docker image with the schema and upload to the registry.
In theory you can rung postgres engine during docker build and execute whatever you need, here is not completely working example, i.e. postgres fails to start because there no configuration file.
if you spend more time on this i bet it should do the trick.
between your lines COPY test-data/. /docker-entrypoint-initdb.d/ and CMD ["postgres"] insert this
RUN adduser --disabled-password --gecos "" dbuser
RUN apt-get update
RUN apt-get install -y sudo
RUN echo "dbuser ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/dbuser && chmod 0440 /etc/sudoers.d/dbuser
USER dbuser:dbuser
RUN sudo chown -R dbuser:dbuser /docker-entrypoint-initdb.d
RUN sudo chown -R dbuser:dbuser /var/lib/postgresql/
RUN postgres
WORKDIR /docker-entrypoint-initdb.d
RUN psql -v ON_ERROR_STOP=1 -U postgres < sql/one.sql
at the moment that fails on RUN postgres - fails to find configuration on german, and i am not expert on postgres neither speak german so i wasn't able to solve right away.
also this part installs sudo and adds new dbuser into sudo group because postgress didn't want to start from root, so postgres runs from dbuser.
Hope this is going to help you moving into right direction :)

Docker-compose.yml file with startup.sql not working

I create my MSSQL database docker container with only docker-compose.yml file and setup.sql file. My .yml file looks like that:
version: "3.7"
services:
sql-server-db:
container_name: sql-server-db
image: mcr.microsoft.com/mssql/server:2019-latest
ports:
- "1433:1433"
environment:
SA_PASSWORD: "secret123new!"
ACCEPT_EULA: "Y"
volumes:
- ./data/mssql:/scripts/
command:
- /bin/bash
- -c
- |
# Launch MSSQL and send to background
/opt/mssql/bin/sqlservr &
pid=$$!
# Wait for it to be available
echo "Waiting for MS SQL to be available ⏳"
/opt/mssql-tools/bin/sqlcmd -l 30 -S localhost -h-1 -V1 -U sa -P secret123new! -Q "SET NOCOUNT ON SELECT \"YAY WE ARE UP\" , ##servername"
is_up=$$?
while [ $$is_up -ne 0 ] ; do
echo -e $$(date)
/opt/mssql-tools/bin/sqlcmd -l 30 -S localhost -h-1 -V1 -U sa -P secret123new! -Q "SET NOCOUNT ON SELECT \"YAY WE ARE UP\" , ##servername"
is_up=$$?
sleep 5
done
# Run every script in /scripts
# TODO set a flag so that this is only done once on creation,
# and not every time the container runs
cd /scripts
for foo in /scripts/"*.sql"
do echo "Processing $foo";
done
echo "All scripts have been executed. Waiting for MS SQL(pid $$pid) to terminate."
# Wait on the sqlserver process
wait $$pi
when i try to connect with Dbeaver to set in file user credentials there in an error looks like that:
Login failed for user 'system'. ClientConnectionId:17e53706-8242-4bca-974b-3648b5ba7f13
there in an extra warning:
The foo variable is not set. Defaulting to a blank string
setup.sql file in /scripts folder mounted on localhost directory mssql on desktop:
CREATE DATABASE probna
GO
USE probna
GO
CREATE LOGIN system WITH PASSWORD='system'
GO
CREATE USER system FOR LOGIN system
GO
ALTER ROLE [db_owner] ADD MEMBER system
GO
CREATE TABLE Products (ID int, ProductName nvarchar(max))
GO
sql-server-db | ServiAll scripts have been executed. Waiting for MS SQL(pid 8) to terminate.
sql-server-db | ce Broker endpoint is in disabled or stopped state.
What could be wrong with this ? my setup.sql file is in /scripts folder. I don t have another files. Should i replace some of the code or some $$ lines ? Please give me some tips how to start docker mssql database with startup file on windows without node.js :) Have a nice day !

How can I install vs-code-server manually and tell vs-code-remote?

When I try use remote-ssh connect to my server to install install vs-code-server, it hangs with these message:
Install and start server if needed
bash: no job control in this shell
Installing...
Downloading with wget
It seems my server cannot use wget to download vs-code-server.
Can I install vs-code-server manually?
Download your current used version via
wget https://update.code.visualstudio.com/commit:c3f126316369cd610563c75b1b1725e0679adfb3/server-linux-x64/stable
You can check the commit id in vscode Help -> About
Copy it to your machine through ssh.
Unpack to ~/.vscode-server/bin/c3f126316369cd610563c75b1b1725e0679adfb3
And you're done
I used this bash script on my linux container and it works fine. You can try this too.
read -p 'What commit of vscode server do you wish to install? ' commit
echo ""
if [ ! -d "$HOME/.vscode-server/bin/$commit" ] ; then
mkdir -p install-vscode-server
cd install-vscode-server
wget -q https://update.code.visualstudio.com/commit:$commit/server-linux-x64/stable
tar -xf stable
mkdir -p ~/.vscode-server/bin
mv vscode-server-linux-x64 ~/.vscode-server/bin/$commit
cd ..
rm -rf install-vscode-server
echo "vscode server commit:$commit installed"
else
echo "Commit already installed"
fi
echo ""
This problem is caused by your terminal shell path isn't configured rightly.
Follow this issue
https://github.com/microsoft/vscode-remote-release/issues/220#issuecomment-490374437
Check which shell you are using: which $SHELL

How to run a setup script on a Docker SQL Server image?

I'm trying to run a setup script on a Docker SQL Server image
For this I have created a Dockerfile from the mssql image
FROM microsoft/mssql-server-linux:2017-CU8
# Create directory to place app specific files
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Copy setup scripts
COPY entrypoint.sh \
./
RUN chmod +x ./entrypoint.sh
CMD /bin/bash ./entrypoint.sh
In entrypoint.sh I'm starting SQL Server and I want to run some setup commands.
#!/bin/bash
#start SQL Server
/opt/mssql/bin/sqlservr &
echo 'Sleeping 20 seconds before running setup script'
sleep 20s
echo 'Starting setup script'
#run the setup script to create the DB and the schema in the DB
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P <MyPassWd> -d master -i setup.sql
echo 'Finished setup script'
When I run this script, the database starts, the setup runs, and after the
setup is finished, the container shuts down.
So I thought something in the script makes the container shut down, therefore I stripped the script down to a bare minimum
#!/bin/bash
#start SQL Server
/opt/mssql/bin/sqlservr &
echo 'Sleeping 20 seconds before running setup script'
sleep 20s
That also stops the container after sleep 20s finished.
Moving on...
#!/bin/bash
#start SQL Server
/opt/mssql/bin/sqlservr &
Which stops the container right away
And then...
#!/bin/bash
#start SQL Server
/opt/mssql/bin/sqlservr
Now the container runs, but I can't do any initialization
Does someone know how to get this working?
Change the password of the sql server to be complex enough.
docker run -d -p 1433:1433 -e "sa_password=ComplexPW2019!" -e "ACCEPT_EULA=Y" <sqlserverimageid>
Root cause of this issue is PID 1 allocation for docker container.
PID 1 will be allocated to command given in CMD in Dockerfile (in our case ./entrypoint.sh)
Container has a life spam according to PID 1(as soon as PID 1 is stop/killed container will be stopped)
1) In case of /opt/mssql/bin/sqlservr &
a child process ID will be allocated to sqlserver cmd and will be executed in background and as soon as rest of the script is executed, container will stop.
2) In case of /opt/mssql/bin/sqlservr
script will not proceed from here until this execution will complete.
so the solution is to assign PID 1 to CMD /opt/mssql/bin/sqlservr and rest of the script should be executed as child process.
I have done below changes and it is working for me.
in Dockerfile
replace CMD /bin/bash ./entrypoint.sh to CMD exec /bin/bash entrypoint.sh
in entrypoint.sh
#!/bin/bash
#start SQL Server
sh -c "
echo 'Sleeping 20 seconds before running setup script'
sleep 20s
echo 'Starting setup script'
#run the setup script to create the DB and the schema in the DB
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P \"YourStrong!Passw0rd\" -Q
\"ALTER LOGIN SA WITH PASSWORD='NewStrong!Passw0rd'\"
echo 'Finished setup script'
exit
" &
exec /opt/mssql/bin/sqlservr
To create the database on startup, try the approach below.
Dockerfile
FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA Y
ENV DB_NAME test
COPY startup.sh /var/opt/mssql/startup.sh
CMD ["bash", "/var/opt/mssql/startup.sh"]
startup.sh
#!/usr/bin/env bash
if ! [ -f /var/opt/mssql/.initialized ] && [ -n "$DB_NAME" ]; then
while ! </dev/tcp/localhost/1433 2>/dev/null; do
sleep 2
done
echo "Creating $DB_NAME database..."
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "$SA_PASSWORD" -d master \
-Q "CREATE DATABASE $DB_NAME"
touch /var/opt/mssql/.initialized
fi &
/opt/mssql/bin/sqlservr
SQL Server has to be the right most command.
I know it does not make sense as you want SQL Server to run first and then run your scripts to create/restore databases. I guess this is because of the way SQL Server runs on Linux ( Sql server process creates a SQL server process as part of startup).
MSDN documentation makes the order of execution clear at: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-configure-docker?view=sql-server-ver15#customcontainer
So for your example, you would have to write something like:
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P <MyPassWd> -d master -i setup.sql & /opt/mssql/bin/sqlservr
There is a pull request to allow to run an init SQL script on first time run.
The purpose of this PR is to add into the start.ps1 the ability to check the folder docker-entrypoint-initdb and run all sql scripts inside. Once it is done, the script creates a flag file to avoid running the setup phase on the next startup after a stop.
By mounting a volume from local folder scripts to c:/docker-entrypoint-initdb, the container will execute all .sql scripts files. The volume should be a directory.
E.g.
version: "3.8"
services:
sqlserver:
platform: windows/amd64
environment:
- sa_password=<YourPassword>
- ACCEPT_EULA=Y
image: microsoft/mssql-server-windows-developer
volumes:
- ./dockerfiles/sqlserver/initdb:c:/docker-entrypoint-initdb:ro
ports:
- "1433:1433"

Starting and populating a Postgres container in Docker

I have a Docker container that contains my Postgres database. It's using the official Postgres image which has a CMD entry that starts the server on the main thread.
I want to populate the database by running RUN psql –U postgres postgres < /dump/dump.sql before it starts listening to queries.
I don't understand how this is possible with Docker. If I place the RUN command after CMD, it will of course never be reached because Docker has finished reading the Dockerfile. But if I place it before the CMD, it will run before psql even exists as a process.
How can I prepopulate a Postgres database in Docker?
After a lot of fighting, I have found a solution ;-)
For me was very useful a comment posted here: https://registry.hub.docker.com/_/postgres/ from "justfalter"
Anyway, I have done in this way:
# Dockerfile
FROM postgres:9.4
RUN mkdir -p /tmp/psql_data/
COPY db/structure.sql /tmp/psql_data/
COPY scripts/init_docker_postgres.sh /docker-entrypoint-initdb.d/
db/structure.sql is a sql dump, useful to initialize the first tablespace.
Then, the init_docker_postgres.sh
#!/bin/bash
# this script is run when the docker container is built
# it imports the base database structure and create the database for the tests
DATABASE_NAME="db_name"
DB_DUMP_LOCATION="/tmp/psql_data/structure.sql"
echo "*** CREATING DATABASE ***"
# create default database
gosu postgres postgres --single <<EOSQL
CREATE DATABASE "$DATABASE_NAME";
GRANT ALL PRIVILEGES ON DATABASE "$DATABASE_NAME" TO postgres;
EOSQL
# clean sql_dump - because I want to have a one-line command
# remove indentation
sed "s/^[ \t]*//" -i "$DB_DUMP_LOCATION"
# remove comments
sed '/^--/ d' -i "$DB_DUMP_LOCATION"
# remove new lines
sed ':a;N;$!ba;s/\n/ /g' -i "$DB_DUMP_LOCATION"
# remove other spaces
sed 's/ */ /g' -i "$DB_DUMP_LOCATION"
# remove firsts line spaces
sed 's/^ *//' -i "$DB_DUMP_LOCATION"
# append new line at the end (suggested by #Nicola Ferraro)
sed -e '$a\' -i "$DB_DUMP_LOCATION"
# import sql_dump
gosu postgres postgres --single "$DATABASE_NAME" < "$DB_DUMP_LOCATION";
echo "*** DATABASE CREATED! ***"
So finally:
# no postgres is running
[myserver]# psql -h 127.0.0.1 -U postgres
psql: could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
[myserver]# docker build -t custom_psql .
[myserver]# docker run -d --name custom_psql_running -p 5432:5432 custom_psql
[myserver]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce4212697372 custom_psql:latest "/docker-entrypoint. 9 minutes ago Up 9 minutes 0.0.0.0:5432->5432/tcp custom_psql_running
[myserver]# psql -h 127.0.0.1 -U postgres
psql (9.2.10, server 9.4.1)
WARNING: psql version 9.2, server version 9.4.
Some psql features might not work.
Type "help" for help.
postgres=#
# postgres is now initialized with the dump
Hope it helps!
For those who want to initialize a PostgreSQL DB with millions of records during the first run.
Import using *.sql dump
You can do simple sql dump and copy the dump.sql file into /docker-entrypoint-initdb.d/. The problem is speed. My dump.sql script is about 17MB (small DB - 10 tables with 100k rows in only one of them) and the initialization takes over a minute (!). That is unacceptable for local development / unit test, etc.
Import using binary dump
The solution is to make a binary PostgreSQL dump and use shell scripts initialization support.
Then the same DB is initialized in about 500ms instead of 1 minute.
1. Create the dump.pgdata binary dump of a DB named "my-db"
directly from within a container or your local DB
pg_dump -U postgres --format custom my-db > "dump.pgdata"
Or from host from running container (postgres-container)
docker exec postgres-container pg_dump -U postgres --format custom my-db > "dump.pgdata"
2. Create a Docker image with a given dump and initialization script
$ tree
.
├── Dockerfile
└── docker-entrypoint-initdb.d
├── 01-restore.sh
├── 02-small-updates.sql
└── dump.pgdata
$ cat Dockerfile
FROM postgres:11
COPY ./docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/
$ cat docker-entrypoint-initdb.d/01-restore.sh
#!/bin/bash
file="/docker-entrypoint-initdb.d/dump.pgdata"
dbname=my-db
echo "Restoring DB using $file"
pg_restore -U postgres --dbname=$dbname --verbose --single-transaction < "$file" || exit 1
$ cat docker-entrypoint-initdb.d/02-small-updates.sql
-- some updates on your DB, for example for next application version
-- this file will be executed on DB during next release
UPDATE ... ;
3. Build an image and run it
$ docker build -t db-test-img .
$ docker run -it --rm --name db-test db-test-img
Alternatively, you can just mount a volume to /docker-entrypoint-initdb.d/ that contains all your DDL scripts. You can put in *.sh, *.sql, or *.sql.gz files and it will take care of executing those on start-up.
e.g. (assuming you have your scripts in /tmp/my_scripts)
docker run -v /tmp/my_scripts:/docker-entrypoint-initdb.d postgres
There is yet another option available that utilises Flocker:
Flocker is a container data volume manager that is designed to allow databases like PostgreSQL to easily run in containers in production. When running a database in production, you have to think about things like recovering from host failure. Flocker provides tools for managing data volumes across a cluster of machines like you have in a production environment. For example, as a Postgres container is scheduled between hosts in response to server failure, Flocker can automatically move its associated data volume between hosts at the same time. This means that when your Postgres container starts up on a new host, it has its data. This operation can be accomplished manually using the Flocker API or CLI, or automatically by a container orchestration tool that Flocker is integrates with, for example Docker Swarm, Kubernetes or Mesos.
I Followed the same solution which #damoiser , The only situation which was different was I wanted to import all dump data.
Please follow the solution below.(I have not done any kind of checks)
Dockerfile
FROM postgres:9.5
RUN mkdir -p /tmp/psql_data/
COPY db/structure.sql /tmp/psql_data/
COPY scripts/init_docker_postgres.sh /docker-entrypoint-initdb.d/
then the init_docker_postgres.sh script
#!/bin/bash
DB_DUMP_LOCATION="/tmp/psql_data/structure.sql"
echo "*** CREATING DATABASE ***"
psql -U postgres < "$DB_DUMP_LOCATION";
echo "*** DATABASE CREATED! ***"
and then you can build your image as
docker build -t abhije***/postgres-data .
docker run -d abhije***/postgres-data
My solution is inspired by Alex Dguez's answer which unfortunately doesn't work for me because:
I used pg-9.6 base image, and the RUN /docker-entrypoint.sh --help never ran through for me, which always complained with The command '/bin/sh -c /docker-entrypoint.sh -' returned a non-zero code: 1
I don't want to pollute the /docker-entrypoint-initdb.d dir
The following answer is originally from my reply in another post: https://stackoverflow.com/a/59303962/4440427. It should be noted that the solution is for restoring from a binary dump instead of from a plain SQL as asked by the OP. But it can be modified slightly to adapt to the plain SQL case
Dockerfile:
FROM postgres:9.6.16-alpine
LABEL maintainer="lu#cobrainer.com"
LABEL org="Cobrainer GmbH"
ARG PG_POSTGRES_PWD=postgres
ARG DBUSER=someuser
ARG DBUSER_PWD=P#ssw0rd
ARG DBNAME=sampledb
ARG DB_DUMP_FILE=example.pg
ENV POSTGRES_DB launchpad
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD ${PG_POSTGRES_PWD}
ENV PGDATA /pgdata
COPY wait-for-pg-isready.sh /tmp/wait-for-pg-isready.sh
COPY ${DB_DUMP_FILE} /tmp/pgdump.pg
RUN set -e && \
nohup bash -c "docker-entrypoint.sh postgres &" && \
/tmp/wait-for-pg-isready.sh && \
psql -U postgres -c "CREATE USER ${DBUSER} WITH SUPERUSER CREATEDB CREATEROLE ENCRYPTED PASSWORD '${DBUSER_PWD}';" && \
psql -U ${DBUSER} -d ${POSTGRES_DB} -c "CREATE DATABASE ${DBNAME} TEMPLATE template0;" && \
pg_restore -v --no-owner --role=${DBUSER} --exit-on-error -U ${DBUSER} -d ${DBNAME} /tmp/pgdump.pg && \
psql -U postgres -c "ALTER USER ${DBUSER} WITH NOSUPERUSER;" && \
rm -rf /tmp/pgdump.pg
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
CMD pg_isready -U postgres -d launchpad
where the wait-for-pg-isready.sh is:
#!/bin/bash
set -e
get_non_lo_ip() {
local _ip _non_lo_ip _line _nl=$'\n'
while IFS=$': \t' read -a _line ;do
[ -z "${_line%inet}" ] &&
_ip=${_line[${#_line[1]}>4?1:2]} &&
[ "${_ip#127.0.0.1}" ] && _non_lo_ip=$_ip
done< <(LANG=C /sbin/ifconfig)
printf ${1+-v} $1 "%s${_nl:0:$[${#1}>0?0:1]}" $_non_lo_ip
}
get_non_lo_ip NON_LO_IP
until pg_isready -h $NON_LO_IP -U "postgres" -d "launchpad"; do
>&2 echo "Postgres is not ready - sleeping..."
sleep 4
done
>&2 echo "Postgres is up - you can execute commands now"
The above scripts together with a more detailed README are available at https://github.com/cobrainer/pg-docker-with-restored-db
I was able to load the data in by pre-pending the run command in the docker file with /etc/init.d/postgresql. My docker file has the following line which is working for me:
RUN /etc/init.d/postgresql start && /usr/bin/psql -a < /tmp/dump.sql
We for E2E test in which we need a database with structure and data already saved in the Docker image we have done the following:
Dockerfile:
FROM postgres:9.4.24-alpine
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD postgres
ENV PGDATA /pgdata
COPY database.backup /tmp/
COPY database_restore.sh /docker-entrypoint-initdb.d/
RUN /docker-entrypoint.sh --help
RUN rm -rf /docker-entrypoint-initdb.d/database_restore.sh
RUN rm -rf /tmp/database.backup
database_restore.sh:
#!/bin/sh
set -e
pg_restore -C -d postgres /tmp/database.backup
To create the image:
docker build .
To start the container:
docker run --name docker-postgres -d -p 5432:5432 <Id-docker-image>
This does not restore the database every time the container is booted. The structure and data of the database is already contained in the created Docker image.
We have based on this article, but eliminating the multistage:
Creating Fast, Lightweight Testing Databases in Docker
Edit: With version 9.4-alpine does not work now because it does not
run the database_restore.sh scrips. Use version 9.4.24-alpine
My goal was to have an image that contains the database - i. e. saving the time to rebuild it everytime I do docker run oder docker-compose up.
We would just have to manage to get the line exec "$#" out of docker-entrypoint.sh. So I added into my Dockerfile:
#Copy my ssql scripts into the image to /docker-entrypoint-initdb.d:
COPY ./init_db /docker-entrypoint-initdb.d
#init db
RUN grep -v 'exec "$#"' /usr/local/bin/docker-entrypoint.sh > /tmp/docker-entrypoint-without-serverstart.sh && \
chmod a+x /tmp/docker-entrypoint-without-serverstart.sh && \
/tmp/docker-entrypoint-without-serverstart.sh postgres && \
rm -rf /docker-entrypoint-initdb.d/* /tmp/docker-entrypoint-without-serverstart.sh

Resources