Open SSH tunnel during PostGIS Docker build

187 Views Asked by At

How to open an SSH tunnel during the build process of PostGIS container build?

I need to SSH tunnel to database, so I can create dump, then restore in container.

With other docker containers, I usually create a startup.sh then run from Dockerfile. However, to run startup scripts in PostGIS container we need to add the script to /docker-entrypoint-initdb.d folder.

The problem with this is, the script runs as user postgres with a user id of 999. I need to run as root with userid of 0 to execute ssh commands.

 Instructions run from the Dockerfile execute under the root user, but again once the scripts are run from /docker-entrypoint-initdb.d, they are run under the postgres user.

 If I run docker exec -it postgis_container bash, I am in bash as the root user and I can execute all the commands I need. However, I do not want to do this. I want to just execute docker-compose up and allow the docker compose configurations, the Dockerfile and possible any startup script to do the rest.

I know I can install OpenSSH and run tunnel from Dockerfile but connecting to a server the first time brings up the known_host prompt. I can user ssh-keyscan -H some_server >> /root/.ssh/known_hosts or even make a volume from the host machine of my ~/.ssh folder, that containers working a known_host file but the error I get is:

Dockerfile

RUN echo "Install OpenSSH \n" \
&& apt-get -y update \
&& apt-get install -y openssh-client \
&& echo "Config SSH \n" \
&& mkdir /root/.ssh && touch /root/.ssh/id_rsa-dev \
&& chmod 700 /root/.ssh/id_rsa-dev \
&& touch /root/.ssh/known_hosts \
&& touch /root/.ssh/config \
&& ssh-keyscan -H some_server.com >> /root/.ssh/known_hosts \
&& echo "Tunnel to DB \n" \
&& ssh -N -L 9001:some_other_server.com:5432 some_user@some_server.com -i /root/.ssh/id_rsa-dev & \
&& echo "Setup for dump and restore \n" \
&& cd /root/dump \
&& date_today=$(date +%F) \
&& echo "Createing dump file from dev db name = dev_db_$date_today.sql" \
&& export PGPASSWORD=${DEV_DB_PASSWORD} \
&& pg_dump -Fc -v -U dbuser -d dev_db -p 9001 -h 0.0.0.0 > ./dev_db_$date_today.sql \
&& export PGPASSWORD=$POSTGRES_PASSWORD \
&& echo "Restoring db" \
&& pg_restore -Fc -v -U dbuser -d dev_db_docker_local ./dev_db_$date_today.sql

Error from output

0.335 Warning: Permanently added the ECDSA host key for IP address ‘111.222.333.444’ to the list of known hosts.                                                                                                                                                                                   
#0 0.418 Authorized uses only. All activity may be monitored and reported.                                                                                                                                                                                                                         
#0 0.418 Load key "/root/.ssh/id_rsa-dev": invalid format
#0 0.418 some_user@some_server.com: Permission denied (publickey).

However, again, if I run docker exec -it postgis_container bash, then execute the exact same commands, I am able to open the ssh tunnel, dump and restore.

startup.sh

#!/usr/bin/env bash
cho "Install OpenSSH
apt-get -y update
apt-get install -y openssh-client
echo "Config SSH
mkdir /root/.ssh && touch /root/.ssh/id_rsa-dev
chmod 700 /root/.ssh/id_rsa-dev
touch /root/.ssh/known_hosts
touch /root/.ssh/config
ssh-keyscan -H some_server.com >> /root/.ssh/known_hosts
echo "Tunnel to DB
ssh -N -L 9001:some_other_server.com:5432 some_user@some_server.com -i /root/.ssh/id_rsa-dev &
echo "Setup for dump and restore
cd /root/dump
date_today=$(date +%F)
echo "Createing dump file from dev db name = dev_db_$date_today.sql"
export PGPASSWORD=${DEV_DB_PASSWORD}
pg_dump -Fc -v -U dbuser -d dev_db -p 9001 -h 0.0.0.0 > ./dev_db_$date_today.sql
export PGPASSWORD=$POSTGRES_PASSWORD
echo "Restoring db"
pg_restore -Fc -v -U dbuser -d dev_db_docker_local ./dev_db_$date_today.sql

I would prefer to be able to run my startup.sh script from /docker-entrypoint-initdb.d folder as a root user. But If I can not, then would like to be able to added all the steps to Dockerfile

Any help would be greatly appreciated.


Note:

I asked a question here.

I was trying to find out how to get my startup script to run as root, but realized the question did not give enough context so I created this post. I mention this because setting user root or 0, wether in the Dockerfile or the docker-compose.yml does not solve my problem.

If I try to run startup.sh from /docker-entrypoint-initdbd:

sudo is not available. su is available, but I do not know root password. gosu is available but when I used that it give an error along the lines of operation not permitted.

Update 1:

Seems like this is an issue. The postgres docker github says you can not run as root from /docker-entrypoint-initdb.d.

https://github.com/docker-library/postgres/issues/973

But something seems weird about that. I figure there has got to be a way around this. Or maybe some best practice that address this use case. I imagine I am not the only one who has run into an issue like this.

Update 2:

I just realized running the commands in Dockerfile will not work because postgres would not have been started yet. And I need to run psql after I open the tunnel. So I have to run from /docker-entrypoint-initdb.d folder or figure out some way to get startup.sh to run after postgis container finishes its default start up processes.

Appearently this was not a problem a few years ago, but I believe there was a move to stop the use of root access during the build start up process in the /docker-entrypoint-initdb.d for security reasons. But there was no suggested work around.

0

There are 0 best solutions below