開発環境の構築時にDockerを使う機会が度々有ります。通常コンテナへのログインはdocker exec -it
かdocker-compose exec
を使用することで実現出来ます。但し、VSCodeからリモート上のコンテナにログインしたい場合はこの方法が使えません。故に本記事ではSSHでリモートログイン可能なコンテナの作り方を取り上げたいと思います。
実はDockerのドキュメントにも解説が有る
SSH デーモン用サービスの Docker 化に解説が記載されています。また参考記事1、参考記事2にも同様の解説が有ります。しかし、これらの記事で解説されている方法でUbuntu18.04のコンテナを起動し、SSHでログインしようとしてもpermission denied
とエラーが表示されログイン出来ません。本記事ではUbuntu18.04イメージをベースとしたSSHログイン可能1なコンテナの構築を目指します。
新旧UbuntuのDockerfile比較
まず先述の参考記事に記載されているDockerfileの中身です。
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:THEPASSWORDYOUCREATED' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
# 以下の二行は動作に直接関係ない部分なので削除しても構わない
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
以下にUbuntu18.04をベースにしたDockerfileの記載内容を示します。Ubuntu18.04?から
/etc/ssh/sshd_config
内の各々のオプションがデフォルトではコメントアウトされており、SSHの認証を有効化するためにはコメントアウトを解除する必要2が有ります。その操作を考慮した内容になっています。
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:THEPASSWORDYOUCREATED' | chpasswd
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -i 's/#PasswordAuthentication/PasswordAuthentication/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
パスワードを外出しにする
このままイメージビルドを行えばSSHでログイン可能なコンテナが起動します。しかし、このままではSSHログイン時に入力するパスワードがDockerfile内に記載された状態になります。セキュリティー上好ましくないと言う理由でコンテナ起動後パスワードを変更するのは煩雑になる為、外出しにしてビルド時にオプションとして渡せる様に変更します。
FROM ubuntu:18.04
ARG PASSWD
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:'${PASSWD} | chpasswd
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -i 's/#PasswordAuthentication/PasswordAuthentication/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
イメージビルド時にdocker image build --build-arg PASSWD=<PASSWORD> -t <IMAGE_NAME> .
とすれば、任意のパスワードを設定したコンテナイメージがビルド出来ます。但し、Docker Composeを利用するとより手間無くコンテナの起動が可能となります。
version: "2.4"
services:
example_service:
build:
context: .
dockerfile: Dockerfile
args:
- PASSWD=${PASSWD}
ports:
- '2222:22'
restart: always
docker-compose.yml
を格納したディレクトリ上でdocker-compose build --build-arg PASSWD=<PASSWORD>
を実行し、任意のパスワード(PASSWD=<PASSWORD>部分)を--build-argオプションとして渡します。ビルドが完了したら、docker-compose up -d
コマンドを実行し、起動が完了したらssh -p 2222 root@localhost
(リモート上で起動した場合はリモートのIPアドレスを指定)コマンドを実行することで、コンテナにログイン出来ます。
まとめ
Ubuntu18.04イメージをベースとしたSSHログイン可能なコンテナの構築を試みた時にpermission denied
エラーでログイン出来ないトラブルに阻まれてしまい、解決に時間を要しました。故に備忘録も兼ねて本記事をまとめました。