2025/4/26 Updated by 
Docker GustOSのカスタムイメージを作成する
ubuntu 24.04LTS, apache2, ssh
[Up]

前提条件
- ubuntu24.04LTS 上に docker-desktop がインストールされている。
- docker のゲストOSとして、ubuntu 24.04lTS を動かす。
- sshd を自動起動する
- apache2 を自動起動する。
apache2 と sshd が自動起動する ubuntu24.04LTS の docker Image を生成する (1)
$ mkdir -p ~/doc/docker/apache2_image
$ cd ~/doc/docker/apache2_image
作業用フォルダの中に Dockerfile を作成する。Dockerfile中の パスワード の部分は、推測されにくい文字列に必ず変更すること。
Dockerfile |
FROM ubuntu:24.04
# 必要なパッケージのインストール
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
sudo \
apache2 \
openssh-server \
supervisor \
&& rm -rf /var/lib/apt/lists/*
# guestユーザー追加+パスワード設定+sudo権限
RUN useradd -m guest && \
echo 'guest:パスワード' | chpasswd && \
adduser guest sudo
# SSH 設定: パスワード認証を有効化
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \
mkdir /var/run/sshd
# Apache 設定: ServerNameエラー防止
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
# supervisord 設定ファイル設置
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# ポート開放
EXPOSE 22 80
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
作業用フォルダの中に supervisord.conf を作成する
supervisord.conf |
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:apache2]
command=/usr/sbin/apache2ctl -D FOREGROUND
|
build する。
$ docker build -t ubuntu24-apache2-sshd .
エラーが起きた。
RROR: failed to solve: ubuntu:24.04: failed to resolve source metadata for docker.io/library/ubuntu:24.04: error getting credentials - err: exit status 1, out: error\
getting credentials - err: exit status 1, out: exit status 2: gpg: 公開鍵の復号に失敗しました: そのようなファイルやディレクトリはありません
gpg: 復号に失敗しました: そのようなファイルやディレクトリはありません`
エラー対策を行う。
(推測)エラーの原因
- Docker Hub への認証情報が壊れている/無効
- Docker の credential helper の設定不良・壊れたキャッシュ
- GPG 関連の環境トラブル(稀)
- ネットワークや一時的な障害
(対策)
- Dockerのログイン情報リセット
$ docker logout
$ docker login
URL と認証コードが示されるので、ブラウザでアクセスして、Docker Hub の ID とパスワードでloginする。
USING WEB-BASED LOGIN
i Info → To sign in with credentials on the command line, use 'docker login -u '
Your one-time device confirmation code is: XXXX-YYYY
Press ENTER to open your browser or submit your device code here: https://login.docker.com/activate
credential helper のキャッシュクリア・リセット ← やらなかった
$ rm ~/.docker/donfig.json
GPG関連のファイルをチェック(Linux/WSLの場合) ← やらなかった
$gpg --list-keys
- Docker イメージキャッシュのクリア
$ docker system prune -a
...
Are you sure you want to continue? [y/N] y
再度、build する
$ docker build -t ubuntu24-apache2-sshd .
...
成功
生成したイメージを確認する
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu24-apache2-sshd latest aa2786c0514a 16 minutes ago 428MB
コンテナに永続的なファイルシステムを提供するために、1777 のパーミッションでフォルダを作る。
$ sudo mkdir -p /home/docker ← ディレクトリを作成する
$ sudo chmod 1777 /home/docker ← 誰でもファイルを作成できるが、作成した本人にしか消去できないモードに設定する
$ ls -ld /home/docker ← ディレクトリのsticky bit が on になっていることを確認する。
drwxrwxrwt 3 root root 4096 4月 26 15:47 /home/docker
image から container を起動する。
$ docker run --name httpd -p 20022:22 -p 20080:80 -p 20443:443 -v /home/docker/httpd:/root/doc -it ubuntu24-apache2-sshd
起動オプション
- 仕様する image は ubuntu24-apache2-sshd
- container の名前は httpd
- ホストOSの /home/docker/httpd がゲストOSからは/root/doc として見える。
- ホストOSのポートへのアクセスが、ゲストOSのポートにforwardされる。
ホストOSのポート | ゲストOSのポート |
20022 | 22 |
20080 | 80 |
20443 | 443 |
/home/docker/httpd が存在しない場合は、 "docker run" を実行したユーザの権限で作成される。
$ ls -ld /home/docker/httpd
drwxr-xr-x 2 nitta nitta 4096 4月 26 15:47 /home/docker/httpd
docker が動作しているマシンから http://localhost:20080/ にアクセスすると、httpdにアクセスできた。
docker の外部のマシンから http://192.168.12.3:20080/ にアクセスすると、httpdにアクセスできなかった。
firewall が効いているようなので、20080 番ポートを開けると外部からアクセスできた。
$ sudo ufw allow 20080 ← ホストOSの20080番ポートを開ける
$ sudo ufw status ← ホストOSのファイアウォール設定状況を調べる
状態: アクティブ
To Action From
-- ------ ----
...
20080 ALLOW Anywhere
...
20080 (v6) ALLOW Anywhere (v6)
セキュリティ対策
ホストOSから ssh でゲストOSの guest ユーザにアクセスして、パスワードを変更する。
(ホストOSのターミナルから)
$ ssh -p 20022 guest@localhost ← ホストOSから自分の 20022番ポートへ ssh アクセスすると、ゲストOSの22番ポートへforwardされる。
guest@localhost's password: パスワード ← Dockerfile で指定したguest のパスワード
(ゲストOS上のシェルにアクセスできた)
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.10.14-linuxkit x86_64)
Last login: Week Month Day Hour:Minitue:Second Year from XXX.XXX.XXX.XXX
$ passwd ← ゲストOS上でパスワードを変更する
Current password: パスワード ← Dockerfile で指定したguest のパスワード
New password: 新しいパスワード ← 新しいパスワード(推測されにくい文字列を使うこと)
Retype new password: 新しいパスワード ← 再度入力する
ゲストOSの自動起動
Docker Desktop において、ホストOSが再起動すると自動的にゲストOSが起動するように設定する方法は2通りある。
- コンテナ作成時に
docker run --restart
オプションで設定する。
(使用例)
$ docker run -d --restart always --name httpd ubuntu24-apache2-sshd
- 既に作成済みのコンテナに対して
docker update --restart
オプションで設定する。
(使用例)
$ docker update --restart unless-stopped httpd
--restart オプションで指定できる値
値 | 説明 |
no | 自動起動しない (default) |
always | ホスト再起動後も自動起動 |
unless-stopped | 手動停止しない限り自動起動 |
on-failure | 異常終了したときのみ自動起動 |
apache2関連の設定
php をインストールする
$ sudo apt update
$ sudo apt install -y libapache2-mod-php
$ sudo sed -i 's/^;date\.timezone =.*/date\.timezone = "Asia\/Tokyo"/' /etc/php/8.3/apache2/php.ini
PHP+FPM による高速化
$ sudo apt -y install php-fpm
------/etc/apache2/sites-available/default-ssl.conf
# <VirtualHost> </VirtualHost> の間に記述する
<FilesMatch "\.php$">
SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost/"
</FilesMatch>
$ sudo a2enmod proxy_fcgi setenvif
$ sudo a2enconf php8.3-fpm
$ sudo service php8.3-fpm restart ← sudo systemctl restart php8.3-fpm は使えない
$ sudo apachectl restart ← sudo systemctl restart apache2 は使えない
その他
$ apt update
$ apt install -y vim
guest ユーザのログインシェルが /bin/sh なので、/bin/bash に変更する。
$ chsh
Password: ← パスワード入力(エコーバックなし)
Changing the login shell for guest
Enter the new value, or press ENTER for the default
Login Shell [/bin/sh]: /bin/bash
bash の対話環境で Control-hを「1文字消去」に設定する。
~/.bashrc の最後に追加する。
if [[ $- == *i* ]]; then
stty erase ^H
fi
rsync をインストールする
$ sudo apt update
$ sudo apt install rsync
apache2 と sshd が自動起動する ubuntu24.04LTS の docker Image を生成する (2)
php のインストールと、さらに PP+FPM による高速化も行う。
Dockerfile |
FROM ubuntu:24.04
# 必要なパッケージのインストール
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
sudo \
apache2 \
libapache2-mod-php \
php-fpm \
openssh-server \
supervisor \
&& rm -rf /var/lib/apt/lists/*
# guestユーザー追加+パスワード設定+sudo権限
RUN useradd -m guest && \
echo 'guest:パスワード' | chpasswd && \
adduser guest sudo
# SSH 設定: パスワード認証を有効化
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \
mkdir /var/run/sshd
# Apache 設定: ServerNameエラー防止
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
# PHP 設定
RUN sed -i 's/^;date\.timezone =.*/date\.timezone = "Asia\/Tokyo"/' /etc/php/8.3/apache2/php.ini
# PHP-FPM によるPHPの高速化
RUN sed -i '/<\/VirtualHost>/i <FilesMatch "\\.php$">\n SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost/"\n</FilesMatch>' /etc/apache2/sites-available/default-ssl.conf
RUN a2enmod proxy_fcgi setenvif
RUN a2enconf php8.3-fpm
# supervisord 設定ファイル設置
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# ポート開放
EXPOSE 22 80
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
supervisord.conf |
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:php-fpm]
command=/usr/sbin/php-fpm8.3 -F
autostart=true
autorestart=true
stdout_logfile=/var/log/php-fpm.log
stderr_logfile=/var/log/php-fpm.err
[program:apache2]
command=/usr/sbin/apache2ctl -D FOREGROUND
|
buildする。
$ docker build -t ubuntu24-apache2-php-sshd .
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu24-apache2-php-sshd latest 52d211a7a4f8 12 seconds ago 470MB
ubuntu24-apache2-sshd latest 2e70eec62db8 16 hours ago 431MB
起動する
$ docker run --name apache2 --restart always -p 21022:22 -p 21080:80 -p 21443:443 -v /home/docker/httpd:/home/guest/doc -it ubuntu24-apache2-php-sshd
apache2 と sshd が自動起動する ubuntu24.04LTS の docker Image を生成する (3)
- Dockerfile で指定したENV変数は、"docker run" 時に -e または --env オプションで値を変更できる。
(実行例)
docker run -e 変数名=値 イメージ名
"docker run" の実行時に --user を指定することで、コンテナ内で実行するプロセスのユーザ (UID/GID)) を指定できる。
(実行例)
docker run --user guest イメージ名 ← ユーザ名で指定
docker run --user 3000:3000 イメージ名 ← UID/GIDで指定
Dockerfile 内の RUN 命令は image の build 時に実行される。
このとき、将来実行される "docker run -e " の値はまだ渡せないので、
"docker run" 時点で値を変えて実行したい手順は、エントリーポイントスクリプトで行う必要がある
Dockerfile |
FROM ubuntu:24.04
ENV UNAME=guest
ENV UID=3000
ENV GID=3000
ENV PASS=パスワード
# 必要なパッケージのインストール
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
sudo \
apache2 \
libapache2-mod-php \
php-fpm \
openssh-server \
supervisor \
&& rm -rf /var/lib/apt/lists/*
# guestユーザー追加+パスワード設定+sudo権限
RUN useradd -m guest && \
echo 'guest:guestpass' | chpasswd && \
adduser guest sudo
# SSH 設定: パスワード認証を有効化
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \
mkdir /var/run/sshd
# Apache 設定: ServerNameエラー防止
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
# PHP 設定
RUN sed -i 's/^;date\.timezone =.*/date\.timezone = "Asia\/Tokyo"/' /etc/php/8.3/apache2/php.ini
# PHP-FPM によるPHPの高速化
RUN sed -i '/<\/VirtualHost>/i <FilesMatch "\\.php$">\n SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost/"\n</FilesMatch>' /etc/apache2/sites-available/default-ssl.conf
RUN a2enmod proxy_fcgi setenvif
RUN a2enconf php8.3-fpm
# supervisord 設定ファイル設置
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# ポート開放
EXPOSE 22 80
#CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
# Add User and start Supervisord in entrypoint.sh
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"] |
supervisord.conf |
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:php-fpm]
command=/usr/sbin/php-fpm8.3 -F
autostart=true
autorestart=true
stdout_logfile=/var/log/php-fpm.log
stderr_logfile=/var/log/php-fpm.err
[program:apache2]
command=/usr/sbin/apache2ctl -D FOREGROUND
|
entrypoint.conf (docker run 時に実行されるスクリプト) |
#!/bin/bash
set -e
# ${UNAME} ユーザーのパスワードを再設定
if [ -n "${PASS}" ]; then
echo "${UNAME}:${PASS}" | chpasswd
fi
# supervisord start (background)
/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf &
# Execute Commands in CMD
if [ "$#" -gt 0]; then
exec "$@"
else
wait
fi
|
buildする。
$ docker build -t ubuntu24-apache2-php-sshd-uid .
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu24-apache2-php-sshd-uid latest f63c6004e567 23 seconds ago 470MB
ubuntu24-apache2-php-sshd latest 52d211a7a4f8 4 hours ago 470MB
ubuntu24-apache2-sshd latest 2e70eec62db8 21 hours ago 431MB
起動する
$ docker run --name webserver --restart always -e PASS=新しいパスワード -p 20022:22 -p 20080:80 -p 20443:443 -v /home/docker/www:/home/guest/www -it ubuntu24-apache2-php-sshd-uid