Alpine Linux は当社で最も小さいイメージです。当社のサーバーでは、新しい Alpine 3.21 のアイドル時の使用量は RAM 55 MB、ディスク 153 MB で、Ubuntu 24.04 の 313 MB と 2.7 GB とは大きな差があります。その代わり、使い慣れたツールは手放すことになります。Alpine では apt の代わりに apk、sudo の代わりに doas、systemd の代わりに OpenRC、glibc の代わりに musl を使います。
以下の手順は、Debian や Ubuntu と同じ最初の 10 分間を Alpine 向けに置き換えたものです。公開前にすべてのコマンドを当社の Alpine 3.21 イメージで実行し、そのうち 2 つには最初につまずきました。ダッシュボードのパスワードで root としてログインしてください。
1. 更新して、一度再起動する
apk update && apk upgrade
uname -r
ls /lib/modules
サーバーは最初の起動時に、利用できる更新をすでにインストールしています。そのため apk upgrade にはたいていほとんど仕事が残っていません。見るべきは最後の 2 行です。最初の更新で新しいカーネルが入った場合、動作中のカーネル(uname -r)のモジュールはもうディスク上にありません。モジュールを読み込む処理は、再起動するまで失敗します。当社のテストサーバーでは、ファイアウォールのインストールで ERROR: Couldn't determine iptables version が出ました。2 つのバージョンが違う場合は、今すぐ再起動してください。
reboot
テストサーバーは 1 分かからずに戻ってきました。
2. ログインできるユーザーを作る
adduser -D deploy
passwd deploy
adduser deploy wheel
passwd は飛ばさないでください。adduser -D はパスワードなしでアカウントを作り、Alpine はそれをロック状態として扱います。そして sshd はロックされたアカウントを、正しい鍵があっても拒否します。当社のテストでは、手がかりは /var/log/messages のこの 1 行だけでした。
User deploy not allowed because account is locked
パスワードは後でも必要です。doas が求めるのはこのパスワードです。
サーバーの注文時に SSH 鍵を登録した場合、その鍵は root の authorized_keys に入っています。新しいユーザーにコピーします。
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
まだ鍵がない場合は、自分のパソコンで作成し、公開鍵を /home/deploy/.ssh/authorized_keys に貼り付けてください。
3. doas でパスワードを求めるようにする
Alpine では sudo の代わりに doas を使い、当社のイメージではすでに wheel グループに許可されています。/etc/doas.d/wheel.conf のルールは permit nopass :wheel なので、wheel のメンバーなら何も入力せずに root になれます。パスワードを求め、入力後は数分間覚えておくように変えます。
echo 'permit persist :wheel' > /etc/doas.d/wheel.conf
これで doas apk add nano が、Ubuntu の sudo apt install nano と同じように使えます。
4. SSH:鍵のみ、root は不可
sshd は /etc/ssh/sshd_config.d/ 内のファイルを名前順に読み、各設定について最初に見つけた値を採用します。当社のイメージでは最初のファイルが 00-eqvps.conf で、初日にログインできるよう root とパスワードでのログインを許可しています。中身を置き換えてください。
cat > /etc/ssh/sshd_config.d/00-eqvps.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
EOF
sshd -t && rc-service sshd restart
sshd -T | grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication) '
Alpine では 3 行目が重要です。イメージは PAM 対応版の OpenSSH を使っていて、最初の 2 行だけでは、テストサーバーはまだ keyboard-interactive によるログインを受け付けていました。3 行すべてを書くと、鍵なしのログインはこうなります。
Permission denied (publickey).
root のセッションは開いたままにしておきます。別のターミナルで ssh deploy@YOUR.SERVER.IP が通ること(NAT プランでは -p とダッシュボードの専用ポートを付けます)と、doas id がパスワードを受け付けることを確認してください。
5. ファイアウォール:ufw
ufw は community リポジトリにあり、当社のイメージではこのリポジトリが有効になっています。
apk add ufw
ufw limit 22/tcp
ufw --force enable
rc-update add ufw default
ufw status
limit は SSH を通しますが、短時間に多くの接続を開く相手は遅くします。ここでは rc-update が欠かせません。runlevel に追加しないと、OpenRC は再起動後にファイアウォールを起動しないからです。再起動後、テストサーバーは Status: active の状態で戻りました。NAT プランでは SSH をポート 22 のままにしてください。専用の外部ポートはサーバー内の 22 番に転送されています。専用 IPv4 付きのプランでは、必要になったときに Web 用のポートを開けます(ufw allow 80/tcp、ufw allow 443/tcp)。詳しくは ufw ガイドをご覧ください。
6. cron と毎日の更新を有効にする
新しい Alpine サーバーでは cron がまったく動いていません。有効にします。
rc-update add crond default
rc-service crond start
Alpine の root の crontab は、/etc/periodic/daily にあるものを毎日 02:00 に実行するようになっています。そこに更新スクリプトを置きます。
cat > /etc/periodic/daily/apk-upgrade <<'EOF'
#!/bin/sh
apk upgrade --update-cache --no-progress >> /var/log/apk-auto.log 2>&1
EOF
chmod +x /etc/periodic/daily/apk-upgrade
run-parts --test /etc/periodic/daily
最後のコマンドは cron が実行するスクリプトの一覧を表示し、作ったスクリプトがそこに含まれているはずです。これで 3.21 の修正を受け取れます。次の Alpine リリースへの移行は、別に手動で行う作業です。カーネルの更新には相変わらず再起動が必要なので、手順 1 の uname -r / ls /lib/modules の確認をときどき繰り返してください。
7. OpenRC を一つの表で
systemd を知っているなら、変わるのはだいたい次のとおりです。
| 作業 | systemd | Alpine (OpenRC) |
|---|---|---|
| サービスを起動 | systemctl start nginx | rc-service nginx start |
| 起動時に自動開始 | systemctl enable nginx | rc-update add nginx default |
| 状態 | systemctl status nginx | rc-service nginx status |
| 動いているもの | systemctl list-units | rc-status |
| システムログ | journalctl | /var/log/messages |
8. Docker と、ufw では止まらないポート
Alpine はシステム自体がほとんど邪魔をしないので、Docker のホストに向いています。
apk add docker docker-cli-compose
rc-update add docker default
rc-service docker start
docker run --rm hello-world
当社のサーバーではダウンロード込みで 12 秒でした。Docker デーモンが動いている状態で、使用メモリは 57 MB から 124 MB に増えました。
Alpine に限らない落とし穴があります。Docker は独自のファイアウォールルールを書き込みます。ufw が SSH しか許可していない状態で nginx を -p 8080:80 で起動すると、サーバーの外からポート 8080 でアクセスできてしまいました。ufw では止まりませんでした。同じサーバーのリバースプロキシ経由でだけ使うコンテナなら、localhost で公開してください。
docker run -d -p 127.0.0.1:8080:80 nginx:alpine
どのプランを選ぶか
Alpine は RAM のほとんどを自分のソフトウェアに残してくれます。Nano プラン(2 vCPU、1 GB、15 GB、月 $3)なら、小さなサービスや数個のコンテナに十分です。NAT プランなので、SSH は専用ポート経由で入ります。ポート 80 と 443 をインターネットに公開する必要があるなら、Nano-IP は専用 IPv4 付きで月 $8 です。より重い Docker 環境には、2 GB で月 $5 の Micro が使えます。
Alpine 3.21 は Alpine VPS のページに掲載されており、VPS のすべての Linux プランで選べます。支払いは Base、Ethereum、Polygon 上の USDT、USDC、ETH で、本人確認書類もカードも不要です。
コメント
まだコメントはありません。最初になりましょう。