0

I'm trying to connect my app running in a docker container to a database through a SSH Tunnel. My dockerfile is something like this:

# Alpine, PHP7.4, Nginx
FROM richarvey/nginx-php-fpm:1.9.1
EXPOSE 8080

ENV WEBROOT /var/www/html/public/

RUN docker-php-ext-install tokenizer xml pcntl

RUN echo "@community http://dl-4.alpinelinux.org/alpine/v3.6/community/" >> /etc/apk/repositories \
    && apk add --update autossh@community \
    && rm -rf /var/lib/apt/lists/*

COPY . /var/www/html/

RUN chmod 600 /ssh_key
RUN ssh -o StrictHostKeyChecking=no -o ServerAliveInterval=5 -o ServerAliveCountMax=1 -i /ssh_key -fN -4 -L 3317:127.0.0.1:3306 user@host

RUN php artisan migrate --force

When building the image (docker build -t project .) the connection to the database (from the migrations) fail and from the server, the auth logs are:

May 23 21:18:04 ultron sshd[3680]: pam_unix(sshd:session): session opened for user <user> by (uid=0)
May 23 21:18:04 ultron systemd-logind[468]: New session 126 of user <user>.
May 23 21:18:05 ultron sshd[3680]: pam_unix(sshd:session): session closed for user <user>
May 23 21:18:05 ultron systemd-logind[468]: Session 126 logged out. Waiting for processes to exit.
May 23 21:18:05 ultron systemd-logind[468]: Removed session 126.

The tunnel and database connection on my local computer are working fine, furthermore if I don't put the ssh command in background (the -f flag) it does not disconnect, but of course the rest of the Dockerfile if not processed.

I tried to put the ssh command on a detached screen with screen -dm <ssh comand> or with autossh, but with these two "alternatives" it does not even connect to the host (the auth.log on the server does not receive the ssh connection).

Thank you in advance.

Theraloss
  • 103
  • 5

1 Answers1

1

not sure which Docker version you're currently using. I created a similar Dockerfile

FROM debian:latest
RUN nohup sh -c "sleep 5|touch test|echo created" &
RUN echo 5
RUN sleep 10
RUN echo 10

and it failed too, no file created, here is the output:

Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM debian:latest
 ---> 5971ee6076a0
Step 2/5 : RUN nohup sh -c "sleep 5|touch test|echo created" &
 ---> Running in e4a12097c5d4
Removing intermediate container e4a12097c5d4
 ---> 19c7f0299f63
Step 3/5 : RUN echo 5
 ---> Running in 6320537fd71c
5
Removing intermediate container 6320537fd71c
 ---> f57fd8f76a8c
Step 4/5 : RUN sleep 10
 ---> Running in a0e51201821f
Removing intermediate container a0e51201821f
 ---> 536fab968b90
Step 5/5 : RUN echo 10
 ---> Running in 6cbe27a02e83
10
Removing intermediate container 6cbe27a02e83
 ---> 79090270d8dc
Successfully built 79090270d8dc

the log is very important information.

Removing intermediate container e4a12097c5d4

Docker image has a very important concept called: image layer. it helps to reduce duplicate works and reduce image size. which means Docker build may stop and any point and create an intermediate container and image. that's the reason your script won't work, because each "RUN", Docker will stop and clean any leftover processes before goes to the next line.

the better approach is, create a Makefile, or a script build.sh if you want it simpler, and move the ssh command at the beginning of this file, after that, put the docker built into it.

so when you want to build the image, just run bash build.sh.

Ethan Xu
  • 343
  • 2
  • 10
  • Moving the ssh outside the container requires me to include something like `--net="host"` to proxy my local into the container (since the tunnel is done on my local pc), but then it won't work on production. I tried also to stop removing the intermediate containers with `--rm=false` but nothing. I decided just to drop the SSH tunnel, unlucky. Thank you anyway! – Theraloss May 24 '20 at 09:48