Назад | Перейти на главную страницу

SSH-туннель в фоновом режиме немедленно отключается в контейнере Docker

Я пытаюсь подключить свое приложение, работающее в контейнере докеров, к базе данных через туннель SSH. Мой файл докеров выглядит примерно так:

# 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

При построении изображения (docker build -t project .) соединение с базой данных (из миграций) не работает, а с сервера журналы аутентификации:

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.

Туннель и подключение к базе данных на моем локальном компьютере работают нормально, более того, если я не поставлю ssh команда в фоновом режиме ( -f flag) он не отключается, но, конечно, остальная часть файла Dockerfile не обрабатывается.

Я пытался поставить ssh команда на отдельном экране с screen -dm <ssh comand> или с autossh, но с этими двумя "альтернативами" он даже не подключается к хосту ( auth.log на сервере не получает ssh-соединение).

Заранее спасибо.

не уверен, какую версию Docker вы сейчас используете. Я создал похожий Dockerfile

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

и это тоже не удалось, файл не создан, вот результат:

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

в журнале очень важная информация.

Removing intermediate container e4a12097c5d4

Образ Docker имеет очень важную концепцию: слой изображения. это помогает уменьшить количество повторяющихся работ и уменьшить размер изображения. Это означает, что сборка Docker может остановиться в любой точке и создать промежуточный контейнер и образ. это причина того, что ваш скрипт не будет работать, потому что каждый "RUN" Docker будет останавливать и очищать все оставшиеся процессы, прежде чем перейти к следующей строке.

лучший подход - создать Makefile, или сценарий build.sh если хотите попроще, переместите ssh в начале этого файла, после этого поставьте docker built внутрь.

поэтому, когда вы хотите создать образ, просто запустите bash build.sh.