One Coderは,Amazon Lightsail 上の AlmaLinux で運用している.この記事では,実際にサーバーを構築したときの作業をもとに,Docker と Git を使ってWeb アプリケーションを運用するための初期設定をまとめる. SSH でサーバーへ接続できる状態から始め,OS の更新,Git と Docker の導入,ファイアウォールと SELinux の確認までを進める.アプリケーションの配置や TLS 証明書の設定は,別途行う.

AlmaLinux を選んだ理由

以前は CentOS を使っていたが,その代替として AlmaLinux を使い始めた.それ以来使い続けており,操作に慣れていることが,今回も選んだ理由だ. 個人でサイトを構築・運用するにあたり,これまでの経験を生かせる OS を選んだ.

使用環境

項目内容
サーバーAmazon Lightsail
OSAlmaLinux release 9.7(Moss Jungle Cat)
運用するサイトOne Coder(one-coder.com)
アプリケーションの運用Docker Compose
ソースコード・設定ファイルの管理Git

以降の例では,ホスト名を one-coder.com とする.ユーザー名やホスト名は,自分の環境に合わせて読み替える.

完成後の構成

AlmaLinux に Git,Docker Engine,Docker Compose を導入し,コンテナで Web アプリケーションを動かすための環境を整える.

1AlmaLinux 2├── Git 3├── Docker Engine 4└── Docker Compose

この記事では,ここまでの初期設定を行う.Web アプリケーションやデータベースなどのコンテナは,この環境を使って後から配置する.

SSH 接続と sudo による管理操作ができる,新規構築中のサーバーを対象とする.SSH 接続については,SSH の基本の使い方 にまとめている.

OS を更新する

インストール済みのパッケージを更新する.表示された変更内容を確認して実行する.

1sudo dnf upgrade 2sudo reboot

再起動で SSH 接続が切れるため,起動を待って接続し直す.すでにサービスを運用している場合は,更新と再起動による停止を考慮して実施する.

この手順は実行時点の更新を適用するため,OS のマイナーバージョンが 9.7 から変わる場合がある.更新後の環境を記録しておく.

1cat /etc/almalinux-release 2uname -r

ホスト名を設定する

サーバーを識別するホスト名を設定する.以下は One Coder の例なので,自分の環境に合わせて変更する.

1sudo hostnamectl set-hostname one-coder.com 2hostnamectl --static

設定した名前が表示されればよい.ホスト名の変更だけでは DNS は設定されない.ドメインでサイトへアクセスできるようにするには,別途 DNS レコードを設定する.

タイムゾーンと時刻同期を確認する

タイムゾーンを日本時間に設定する.

1sudo timedatectl set-timezone Asia/Tokyo 2timedatectl

Time zone が Asia/Tokyo になっていることを確認する.タイムゾーンは時刻の表示に関する設定で,時計を正確に保つ時刻同期とは別のものだ.

System clock synchronized が yes かどうかも確認する.no の場合は,時刻同期を担当する chrony の状態を調べる.

1systemctl status chronyd --no-pager 2chronyc tracking 3chronyc sources -v

chrony が未導入または停止中で,ほかの時刻同期サービスを使用していない場合は,導入して起動する.

1sudo dnf install chrony 2sudo systemctl enable --now chronyd

同期には時間がかかる場合がある.同期しない場合は,時刻源の設定や通信状態を確認する.

Git をインストールする

1sudo dnf install git 2git --version

サーバー上でコミットを作成する場合は,作業ユーザーの名前とメールアドレスも設定する.ソースコードを取得するだけなら,この設定は必須ではない.

1git config --global user.name "Your Name" 2git config --global user.email "you@example.com"

非公開リポジトリを取得する場合は,別途 Git サービスへの認証設定が必要になる.

Docker をインストールする

この記事では Docker の CentOS 向け RPM リポジトリを使用する.参照している Docker 公式手順 の対象 OS は CentOS Stream であり,AlmaLinux 自体の公式サポートを示すものではない.ここでは AlmaLinux 9.7 で使用した構成として紹介する.

既存の Docker や互換パッケージがある環境では,先にパッケージの競合を確認する.以下は新規導入の手順だ.

1sudo dnf install dnf-plugins-core 2sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 3 4sudo dnf install \ 5 docker-ce \ 6 docker-ce-cli \ 7 containerd.io \ 8 docker-buildx-plugin \ 9 docker-compose-plugin

GPG 鍵の取り込み確認が表示された場合は,上記の公式手順に掲載されているフィンガープリントと照合して承認する.インストールされるバージョンは実行時点によって異なる.

Docker を起動し,OS 起動時にも自動起動するように設定する.

1sudo systemctl enable --now docker 2sudo systemctl status docker --no-pager 3sudo docker run --rm hello-world

Hello from Docker! が表示されれば,テスト用コンテナの実行まで確認できている.イメージが手元にない場合はダウンロードされるため,外部への通信が必要になる.

一般ユーザーで Docker を操作できるようにする

One Coder のサーバーを構築したとき,最初につまずいたのが Docker を操作する権限だった.一般ユーザーの ec2-user で Docker コマンドを実行すると,権限エラーになった.

sudo なしで操作できるよう,Docker を使う一般ユーザーでログインした状態で,そのユーザーを docker グループに追加する.

1sudo usermod -aG docker "$(id -un)"

$(id -un) は現在のユーザー名に置き換わるため,ec2-user で実行すればそのユーザーが対象になる.root のシェルから実行すると root が対象になるので,実行するユーザーを確認する.-aG は既存の補助グループを保持したままグループを追加する指定だ.

一度 SSH 接続を終了して再接続し,グループと動作を確認する.

1id -nG 2docker run --rm hello-world 3docker compose version

id -nG に docker が含まれ,sudo なしでテスト用コンテナが実行できればよい.Compose のバージョン表示はプラグインの導入確認であり,アプリケーションの動作確認は実際の Compose ファイルを用意してから行う.

docker グループは実質的に root 相当の権限を持つため,追加するユーザーは必要最小限にする.Docker の導入後の設定

ファイアウォールを確認する

Lightsail 側の設定

Lightsail の管理画面で,対象インスタンスのネットワーク設定を確認する.公開する Web サイトでは HTTP(TCP 80)と HTTPS(TCP 443)を許可し,SSH(通常は TCP 22)は管理に必要な接続元に絞る.SSH ポートを変更している場合は,実際のポートに合わせる.

IPv6 も利用する場合は,IPv4 とは別にルールを確認する.Lightsail のファイアウォールはパブリック IP 宛ての通信を対象とし,プライベート通信の制御は別途考える必要がある.Lightsail のファイアウォール

OS 側の設定

まず firewalld の導入状況と起動状態を確認する.

1rpm -q firewalld 2systemctl is-active firewalld

firewalld は環境によって未導入の場合がある.利用する場合は sudo dnf install firewalld で導入する.ただし,起動前に接続インターフェースのゾーンと SSH の許可設定を確認する必要がある.遠隔操作中に無条件で起動すると,SSH 接続を失う可能性がある.

以下は,firewalld が起動済みで,接続インターフェースが public ゾーンを使用し,SSH が TCP 22 の環境の例だ.別のゾーンやポートを使う場合は読み替える.

1sudo firewall-cmd --get-active-zones 2sudo firewall-cmd --zone=public --list-all 3 4sudo firewall-cmd --zone=public --add-service=ssh 5sudo firewall-cmd --zone=public --add-service=http 6sudo firewall-cmd --zone=public --add-service=https 7 8sudo firewall-cmd --permanent --zone=public --add-service=ssh 9sudo firewall-cmd --permanent --zone=public --add-service=http 10sudo firewall-cmd --permanent --zone=public --add-service=https 11 12sudo firewall-cmd --zone=public --list-all 13sudo firewall-cmd --permanent --zone=public --list-all

実行中の設定と永続設定の両方へ追加する.既存の SSH 接続を残し,別のターミナルから新しく接続できることを確認する.この操作は既存の許可ルールを削除しないため,不要な公開がないかも一覧で確認する.firewall-cmd の説明

firewalld が未起動の環境への初回導入は,インターフェース,ゾーン,SSH ポートを確認してから別途行う.この節の起動済み環境向けコマンドだけでは初回導入は完了しない.

Docker のポート公開

Docker は独自の通信ルールを作るため,ホストの firewalld のサービス一覧だけでコンテナの公開範囲を判断しない.Compose の ports ではリバースプロキシの 80・443 番など必要なポートだけを公開し,データベースなどの内部サービスには外部公開用の ports を設定しない構成にする.Docker とファイアウォール

SELinux を確認する

1getenforce

Enforcing ならアクセス制御が有効になっている.通常はこの状態を維持する.Permissive は拒否を強制せず記録する状態,Disabled は SELinux が無効な状態だ.

ファイルへのアクセスで困った場合は,まず通常の所有者・権限と,SELinux の拒否記録を確認する.バインドマウントでは :Z が単一コンテナ用,:z が複数コンテナで共有するためのラベル指定になる.ホスト側のラベルも変更するため,アプリケーション専用ディレクトリを対象に検討する.Docker の SELinux ラベル設定

原因の切り分けに必要な場合に限り,一時的に Permissive に変更して確認する.初期設定として毎回実行する操作ではない.

1# Enforcing の環境で,一時的に制御を緩めて調査する場合のみ実行 2sudo setenforce 0 3 4# 問題の操作を確認したら Enforcing に戻す 5sudo setenforce 1 6getenforce

setenforce は永続設定を変更しない.再起動後の状態は設定ファイルや起動パラメーターに従う.Disabled の環境をこのコマンドだけで有効化することはできない.SELinux の状態とモード

初期設定後の確認

1hostnamectl --static 2timedatectl 3git --version 4docker version 5docker compose version 6systemctl is-enabled docker 7systemctl is-active docker 8getenforce

Docker の Client と Server の両方が表示され,自動起動が enabled,起動状態が active であることを確認する.タイムゾーン,時刻同期,SELinux の状態も確認しておく.

ここまでで,コンテナを実行するための基本的な環境を確認できる.サイトを公開する前には,実際の Compose 構成での起動確認に加えて,DNS,TLS 証明書,外部からの通信確認,ログ管理,バックアップと復元,監視,更新方法を準備する.

日常的な操作は,Docker のよく使うコマンド と Docker Compose のよく使うコマンド にまとめている.

参考