#!/bin/bash
set -e
if [ ! -f /var/app/.initialized ]; then
######## First Time ########
echo "First run. Setting up ..."
mkdir -p /var/app
touch /var/app/.initialized
# ユーザーが存在しない場合のみ作成する
if id "${UNAME}" &>/dev/null; then
echo "User ${UNAME} already exists. Skipping creation."
else
# 同名グループが無ければ作成
if ! getent group "${UNAME}" &>/dev/null; then
echo "Creating group ${UNAME} with GID=${GID}"
groupadd -g ${GID} ${UNAME}
else
echo "Group ${UNAME} already exists. Skipping group creation."
fi
echo "Creating user ${UNAME} with UID=${UID}, GID=${GID}"
useradd -m -u ${UID} -g ${GID} -s /bin/bash ${UNAME}
echo "${UNAME}:${PASS}" | chpasswd
adduser ${UNAME} sudo
fi
# ホームディレクトリの Owner が root:root になることがあるので変更する。
chown -v ${UNAME}:${UNAME} /home/${UNAME}
# SSHD のポート番号を変更する
sed -i "s/^Port.*/Port ${SSHD_PORT}/" /etc/ssh/sshd_config
else
######## Second Time or Later ########
echo "Starting for the second time or later ..."
fi
# supervisord start (background)
/usr/bin/supervisord -c /etc/supervisor/supervisord.conf &
# Execute Commands in CMD
if [ "$#" -gt 0 ]; then
exec "$@"
else
echo "No command provided. Starting bash ..."
exec bash
fi
; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf
Container 用の永続的なファイルシステムを作成する
コンテナに永続的なファイルシステムを提供するために、1777 のパーミッションでフォルダを作っておく。
skicky bit が on (1777) のフォルダには、
「誰でもファイルを作成できるが、作成した本人だけがファイルを変更したり消したりできる」
という特徴がある。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
ebbd998b2086 bridge bridge local
17420af9f271 host host local
557533733a33 macvlan_net macvlan local
a3538f29efc6 none null local
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
ebbd998b2086 bridge bridge local
17420af9f271 host host local
557533733a33 macvlan_net macvlan local
a3538f29efc6 none null local
$ docker network ls --no-trunc
NETWORK ID NAME DRIVER SCOPE
ebbd998b20868aea17c1e9f3cd85edb3c7c0ce9181edfe9b308284604275e136 bridge bridge local
17420af9f27199ef5081c56e85910d913c73ae8f3885e48e4ed0b09a06d48016 host host local
557533733a33e84ca9eb665736f6a273414778f30a3e744411596008728b0b2b macvlan_net macvlan local
a3538f29efc60166d3f639d42894eff9f902649036619190011c3a66b262a06a none null local
First run. Setting up ...
Creating group www with GID=2000
Creating user www with UID=2000, GID=2000
info: Adding user `www' to group `sudo' ...
ownership of '/home/www' retained as www:www
No command provided. Starting bash ...
root@74996e43a896:/# 2025-05-25 04:58:18,756 CRIT Supervisor is running as root. Privileges were not dropped because no user is \
specified in the config file. If you intend to run as root, you can set user=root in the config file to avoid this message.
2025-05-25 04:58:18,759 INFO RPC interface 'supervisor' initialized
2025-05-25 04:58:18,759 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2025-05-25 04:58:18,759 INFO supervisord started with pid 41
2025-05-25 04:58:19,763 INFO spawned: 'apache2' with pid 44
2025-05-25 04:58:19,765 INFO spawned: 'cron' with pid 45
2025-05-25 04:58:19,766 INFO spawned: 'php-fpm' with pid 46
2025-05-25 04:58:19,768 INFO spawned: 'sshd' with pid 48
2025-05-25 04:58:20,787 INFO success: apache2 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2025-05-25 04:58:20,788 INFO success: cron entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2025-05-25 04:58:20,788 INFO success: php-fpm entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2025-05-25 04:58:20,788 INFO success: sshd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
# ← Container 内の対話環境 (root 権限の bash) が動く
直ちに ユーザ www のパスワードを変更する。
# passwd www
New password: 新しいパスワード ← 新しいパスワードを入力する(エコーバックされない)
Retype new password: 新しいパスワード ← もう一度新しいパスワードを入力する(エコーバックされない)
# iptables -L
bash: iptables: command not found
# ufw status
bash: ufw: command not found
手動で firewall を設定する。
ufw をインストールする。
# apt update
# apt install -y ufw
ufw を有効化する
# ufw enable
Status: active
# ufw allow from 0.0.0.0/0 to any port 22 proto tcp
Rule added
# ufw allow from 0.0.0.0/0 to any port 80 proto tcp
Rule added
# ufw allow from 0.0.0.0/0 to any port 443 proto tcp
Rule added
外部からのアクセスはデフォルトで禁止にする。
# ufw default deny incoming
ファイアウォールの設定状況を見る
# ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
# a2enmod ssl
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
service apache2 restart
*** default-ssl.conf.ORG Sun May 25 05:46:24 2025
--- default-ssl.conf Sun May 25 05:48:02 2025
***************
*** 1,5 ****
<VirtualHost *:443>
! ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
--- 1,2 ----
<VirtualHost *:443>
! ServerAdmin root@example.com
DocumentRoot /var/www/html
***************
*** 28,35 ****
# /usr/share/doc/apache2/README.Debian.gz for more info.
# If both key and certificate are stored in the same file, only the
# SSLCertificateFile directive is needed.
! SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
! SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
# Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the
--- 28,35 ----
# /usr/share/doc/apache2/README.Debian.gz for more info.
# If both key and certificate are stored in the same file, only the
# SSLCertificateFile directive is needed.
! SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
! SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the
***************
*** 38,44 ****
# the referenced file can be the same as SSLCertificateFile
# when the CA certificates are directly appended to the server
# certificate for convinience.
! #SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
--- 38,44 ----
# the referenced file can be the same as SSLCertificateFile
# when the CA certificates are directly appended to the server
# certificate for convinience.
! SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
# supervisorctl restart apache2
2025-06-06 15:26:04,195 INFO waiting for apache2 to stop
2025-06-06 15:26:04,204 WARN stopped: apache2 (terminated by SIGTERM)
apache2: stopped
2025-06-06 15:26:04,214 INFO spawned: 'apache2' with pid 1418
2025-06-06 15:26:04,257 WARN exited: apache2 (exit status 0; not expected)
2025-06-06 15:26:05,261 INFO spawned: 'apache2' with pid 1421
2025-06-06 15:26:07,227 INFO success: apache2 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
apache2: started