Ubuntu 22.04でCaddyを使ってウェブサイトをホストする方法
Ubuntu 22.04を使用していませんか?別のバージョンまたはディストリビューションを選択してください。
著者は、Write for DOnationsプログラムの一環として寄付を受けるために、Free and Open Source Fundを選びました。
紹介
Caddyは、シンプルさとセキュリティを中心に設計されたウェブサーバーで、ウェブサイトのホスティングに役立つ多くの機能が備わっています。例えば、自動的にLet's EncryptからTLS証明書を取得および管理し、HTTPSを有効にすることができ、HTTP/2のサポートも含まれています。HTTPSは、ユーザーとサーバー間のトラフィックを保護するためのシステムであり、本番環境で運営されるウェブサイトの基本的な期待となりつつあります。それがない場合、ChromeやFirefoxは、ユーザーがログイン情報を送信しようとすると、あなたのウェブサイトが「安全ではありません」と警告します。
このチュートリアルでは、xcaddyというカスタムCaddyビルダーを使用してソースからCaddyをビルドし、HTTPSで保護されたウェブサイトをホスティングします。これには、コンパイル、Caddyfileを使用した設定、およびプラグインのインストールが含まれます。最終的には、あなたのドメインが静的ページを提供し、Let's Encryptからの無料のTLS証明書で保護されます。
前提条件
- ルート権限を持ち、少なくとも2GBのRAMと、非ルートアカウントを持つUbuntu 22.04サーバー。これは、Ubuntu 22.04用の初期サーバー設定ガイドに従ってセットアップできます。このチュートリアルでは、非ルートユーザーは
sammyです。 - サーバーにインストールされたGo言語ツールチェーン。最新のGoバージョンをセットアップするには、Ubuntu 20.04にGoをインストールする方法の手順1と2に従ってください(CaddyはGoのバージョン17以上を必要とします)。
- 完全に登録されたドメイン名。このチュートリアルでは、
your_domainを通じてずっと使用します。Namecheapでドメイン名を購入するか、Freenomで無料のものを取得するか、お好みのドメインレジストラを使用することができます。 your_domainがサーバーのパブリックIPアドレスを指すAレコードと、www.your_domainが@を指すCNAMEレコードを持つDNS記録です。これらを追加する方法の詳細については、DigitalOcean DNSの入門ガイドを参照できます。- あなたのDigitalOceanアカウント用の読み取りおよび書き込み権限を持つ個人アクセストークン(APIキー)。個人アクセストークンの作成方法を訪れて作成してください。
ステップ1 — キャディの構築
このステップでは、Caddyのソースコードを変更することなく、後でプラグインを追加する能力を持った状態でCaddyをソースからビルドします。あなたのニーズに応じてCaddyとそのプラグインをダウンロードしてビルドするためにxcaddyを使用します。
xcaddyのリリースページにアクセスして、linux_amd64プラットフォームの最新リリースのリンクをコピーします。ダウンロードする前に、次のコマンドを実行して/tmpに移動します:
- cd /tmp
次に、wgetを使用して最新のリリースをダウンロードします:
- wget https://github.com/caddyserver/xcaddy/releases/download/v0.3.1/xcaddy_0.3.1_linux_amd64.tar.gz
ダウンロードしたら、バイナリのみを抽出してください:
- tar xvf xcaddy_0.3.1_linux_amd64.tar.gz xcaddy
最後に、xcaddy 実行可能ファイルを /usr/bin に移動し、システム全体でアクセスできるようにします:
- sudo mv xcaddy /usr/bin
今、xcaddyがインストールされているので、Caddyをビルドします。そのために、保存用の別のディレクトリを作成します:
- mkdir ~/caddy
次のコマンドを実行して移動します:
- cd ~/caddy
サードパーティのプラグインを使用せずにCaddyの最新バージョンをビルドするには、次のコマンドを実行してください:
- xcaddy build
このコマンドは終了までに時間がかかりますが、次のような出力が表示されます:
2022/08/10 15:55:18 [INFO] Temporary folder: /tmp/buildenv_2022-08-10-1555.834895411
2022/08/10 15:55:18 [INFO] Writing main module: /tmp/buildenv_2022-08-10-1555.834895411/main.go
package main
import (
caddycmd "github.com/caddyserver/caddy/v2/cmd"
// plug in Caddy modules here
_ "github.com/caddyserver/caddy/v2/modules/standard"
)
func main() {
caddycmd.Main()
}
2022/08/10 15:55:18 [INFO] Initializing Go module
2022/08/10 15:55:18 [INFO] exec (timeout=10s): /usr/local/go/bin/go mod init caddy
go: creating new go.mod: module caddy
go: to add module requirements and sums:
go mod tidy
2022/08/10 15:55:18 [INFO] Pinning versions
2022/08/10 15:55:18 [INFO] exec (timeout=0s): /usr/local/go/bin/go get -d -v github.com/caddyserver/caddy/v2
go: downloading github.com/caddyserver/caddy v1.0.5
...
2022/08/10 15:55:49 [INFO] Build environment ready
2022/08/10 15:55:49 [INFO] Building Caddy
2022/08/10 15:55:49 [INFO] exec (timeout=0s): /usr/local/go/bin/go mod tidy
...
2022/08/10 15:55:57 [INFO] exec (timeout=0s): /usr/local/go/bin/go build -o /home/sammy/caddy/caddy -ldflags -w -s -trimpath
2022/08/10 15:58:48 [INFO] Build complete: ./caddy
2022/08/10 15:58:48 [INFO] Cleaning up temporary folder: /tmp/buildenv_2022-08-10-1555.834895411
完了すると、現在のフォルダーに caddy の実行ファイルが利用可能になります。それを /usr/bin に移動してインストールしてください:
- sudo mv caddy /usr/bin
インストールが正しく行われているか確認するために caddy を実行してみることができます:
- caddy version
出力には、あなたがちょうどコンパイルしたCaddyのバージョンが含まれます:
v2.6.1 h1:EDqo59TyYWhXQnfde93Mmv4FJfYe00dO60zMiEt+pzo=
あなたは今、Caddyを構築し実行しました。次のステップでは、Caddyをサービスとしてインストールし、自動的に起動するように設定し、その後、サーバーのセキュリティを確保するために所有権と権限設定を調整します。
ステップ2 — キャディのインストール
Caddyをビルドして実行できることを確認したので、Caddyをシステム起動時に自動的に起動するようにsystemdサービスを設定できます。systemdについてもっと知りたい方は、私たちのSystemd Essentialsチュートリアルをご覧ください。
Caddyは、systemdサービスとして実行するために独自のユーザーとグループを必要とします。次のコマンドを使用してグループを作成してください:
- sudo groupadd --system caddy
次に、caddy グループに属する新しいユーザー caddy を作成します:
- sudo useradd --system \
- --gid caddy \
- --create-home \
- --home-dir /var/lib/caddy \
- --shell /usr/sbin/nologin \
- --comment "Caddy web server" \
- caddy
新しい caddy ユーザーは、独自のホームディレクトリが作成されます。シェルが nologin に設定されているため、caddy としてログインすることはできません。
Caddyバイナリの所有権をrootユーザーに変更します:
- sudo chown root:root /usr/bin/caddy
この変更により、他のアカウントが実行可能ファイルを変更することを防ぐことができます。ただし、rootユーザーがCaddyを所有している間は、システム上に存在する他の非rootアカウントを使用して実行することをお勧めします。これはsystemdサービスでも同様です。非rootアカウントからコマンドを実行することで、Caddy(または他のプログラム)が攻撃された場合に、攻撃者がバイナリを変更したり、rootとしてコマンドを実行することができなくなります。
次に、バイナリファイルの権限を755に設定します。これにより、rootはファイルに対して完全な読み取り/書き込み/実行権限を持ち、他のユーザーは読み取りと実行のみが可能になります。
- sudo chmod 755 /usr/bin/caddy
Caddyのバイナリの設定が完了し、Caddyの設定を開始する準備が整いました。
Caddyの設定ファイルを保存するディレクトリを作成してください:
- sudo mkdir /etc/caddy
次に、それに対するユーザーとグループの権限を設定します:
- sudo chown -R root:caddy /etc/caddy
ユーザーをrootに、グループをcaddyに設定することで、Caddyはそのフォルダへの読み取りおよび書き込みアクセスを持つことが保証され(caddyグループを介して)、スーパーユーザーアカウントのみが同様の読み取りおよび変更権限を持つことになります。
後のステップで、Let's Encryptからの自動TLS証明書のプロビジョニングを有効にします。その準備として、Caddyが取得するTLS証明書を保存するディレクトリを作成し、/etc/caddyディレクトリと同じ所有権ルールを適用します:
- sudo mkdir /etc/ssl/caddy
- sudo chown -R root:caddy /etc/ssl/caddy
Caddyは、このディレクトリに証明書を書き込み、リクエストを暗号化するために読み込むことができる必要があります。このため、/etc/ssl/caddyディレクトリの権限を変更して、rootおよびcaddyだけがアクセスできるようにしてください:
- sudo chmod 0770 /etc/ssl/caddy
次に、Caddyがホストするファイルを保存するディレクトリを作成します。
- sudo mkdir /var/www
次に、ディレクトリの所有者とグループを
- sudo chown caddy:caddy /var/www
Caddyサービスをインストールするには、CaddyのGitHubリポジトリから/etc/systemd/systemにsystemdユニットファイルをダウンロードします。そのためには、以下のコマンドを実行してください:
- sudo sh -c 'curl https://raw.githubusercontent.com/caddyserver/dist/master/init/caddy.service > /etc/systemd/system/caddy.service'
あなたはこのような返事を受け取ります:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1030 100 1030 0 0 4698 0 --:--:-- --:--:-- --:--:-- 4703
```
Modify the service file's permissions so it can only be modified by its owner, `root`:
```command
sudo chmod 644 /etc/systemd/system/caddy.service
次に、Caddyサービスを検出するためにsystemdをリロードします:
- sudo systemctl daemon-reload
systemdがCaddyサービスを検出しているかどうかを確認するには、systemctl statusを実行してください:
- sudo systemctl status caddy
出力は次のようになります:
● caddy.service - Caddy
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: https://caddyserver.com/docs/
同じ出力がある場合、新しいサービスは systemd によって検出されました。
初期サーバーセットアップの一環として、ufwを有効にし、SSH接続を許可しました。CaddyがサーバーからHTTPおよびHTTPSトラフィックを提供するには、次のコマンドを実行してufwでそれらを許可する必要があります:
- sudo ufw allow proto tcp from any to any port 80,443
出力は次の通りです:
Rule added
Rule added (v6)
ufw status を使って変更を確認してください:
- sudo ufw status
次の出力を受け取ります:
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80,443/tcp ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80,443/tcp (v6) ALLOW Anywhere (v6)
Caddyのインストールは完了しましたが、まだ何も提供できるように設定されていません。次のステップでは、Caddyを設定して/var/wwwディレクトリからファイルを提供します。
ステップ3 — Caddyの構成
このセクションでは、サーバーから静的ファイルを提供するための基本的なCaddy設定を記述します。
/var/wwwにindex.htmlという基本的なHTMLファイルを作成してください。
- sudo nano /var/www/index.html
次の行を追加してください:
<!DOCTYPE html>
<html>
<head>
<title>Hello from Caddy!</title>
</head>
<body>
<h1 style="font-family: sans-serif">This page is being served via Caddy</h1>
</body>
</html>
ウェブブラウザーで表示されると、このファイルはこのページはCaddy経由で提供されていますというテキストを含む見出しを表示します。ファイルを保存して閉じてください。
Caddyは、/etc/caddyの下に保存されたCaddyfileというファイルから設定を読み取ります。ファイルを作成して編集のために開きます:
- sudo nano /etc/caddy/Caddyfile
次の行を追加してください:
- http:// {
- root * /var/www
- encode gzip
- file_server
- }
この基本的なCaddy設定は、すべてのHTTPトラフィックがサーバーで/var/wwwからファイル(file_server)を提供し、ページの読み込み時間をクライアント側で短縮するためにgzipを使用して圧縮されるべきであることを宣言しています。
Caddyは多くのユースケースに対して異なるディレクティブを持っています。例えば、logディレクティブは、発生するすべてのHTTPリクエストをログに記録するために役立ちます。ディレクティブの公式ドキュメントページでさらに多くのオプションを確認できます。
終わったら、ファイルを保存して閉じてください。
すべてが正しく動作していることを確認するために、Caddyサービスを開始します。
- sudo systemctl start caddy
次に、systemctl statusを実行して、Caddyサービスのステータスに関する情報を確認します:
- sudo systemctl status caddy
以下を受け取ります:
● caddy.service - Caddy
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
Active: active (running) since Wed 2022-08-10 15:02:41 UTC; 2s ago
Docs: https://caddyserver.com/docs/
Main PID: 5443 (caddy)
Tasks: 7 (limit: 1119)
Memory: 7.5M
CPU: 30ms
CGroup: /system.slice/caddy.service
└─5443 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
今、ウェブブラウザでサーバーのIPアドレスにアクセスできます。サンプルウェブページが表示されます:
あなたは今、Caddyを使って自分のサーバーから静的ファイルを提供するように設定しました。次のステップでは、プラグインを通じてCaddyの機能を拡張します。
ステップ 4 — Let’s Encrypt を使用した自動 TLS の有効化
プラグインはCaddyの動作を変更および拡張できます。一般的に、使用ケースに応じて、より多くの設定ディレクティブを提供します。このステップでは、TXT DNSレコードを使用して検証し、自動的なLet’s Encrypt証明書のプロビジョニングと更新を有効にします。TXT DNSレコードを使用して検証するために、DigitalOcean DNS APIとインターフェースする公式プラグインをインストールします。
プラグインを追加するには、xcaddyを使用してCaddyを再コンパイルする必要があります。利用可能なプラグインのリポジトリを指定します。以下のコマンドを実行して、DigitalOcean DNSをサポートするCaddyをコンパイルします:
- xcaddy build --with github.com/caddy-dns/digitalocean@master
出力はこのようになります:
...
2022/08/10 15:03:24 [INFO] exec (timeout=0s): /usr/local/go/bin/go get -d -v github.com/caddy-dns/digitalocean@master github.com/caddyserver/caddy/v2
go: downloading github.com/caddy-dns/digitalocean v0.0.0-20220527005842-9c71e343246b
go: downloading github.com/libdns/digitalocean v0.0.0-20220518195853-a541bc8aa80f
go: downloading github.com/digitalocean/godo v1.41.0
go: downloading github.com/google/go-querystring v1.0.0
go: downloading golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
go: downloading google.golang.org/appengine v1.6.6
go: added github.com/caddy-dns/digitalocean v0.0.0-20220527005842-9c71e343246b
go: added github.com/digitalocean/godo v1.41.0
go: added github.com/libdns/digitalocean v0.0.0-20220518195853-a541bc8aa80f
2022/08/10 15:03:33 [INFO] exec (timeout=0s): /usr/local/go/bin/go get -d -v
go: downloading github.com/antlr/antlr4 v0.0.0-20200503195918-621b933c7a7f
go: downloading github.com/Masterminds/semver v1.4.2
go: downloading github.com/cenkalti/backoff v2.2.1+incompatible
go: downloading github.com/cpuguy83/go-md2man v1.0.10
go: downloading github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220804214150-8b0cc382067f
go: downloading github.com/antlr/antlr4 v4.10.1+incompatible
go: upgraded github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed => v0.0.0-20220804214150-8b0cc382067f
go: upgraded golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c => v0.0.0-20211104180415-d3ed0bb246c8
go: upgraded google.golang.org/appengine v1.6.6 => v1.6.7
2022/08/10 15:03:39 [INFO] Build environment ready
2022/08/10 15:03:39 [INFO] Building Caddy
2022/08/10 15:03:39 [INFO] exec (timeout=0s): /usr/local/go/bin/go mod tidy
2022/08/10 15:03:40 [INFO] exec (timeout=0s): /usr/local/go/bin/go build -o /home/sammy/caddy/caddy -ldflags -w -s -trimpath
2022/08/10 15:03:56 [INFO] Build complete: ./caddy
2022/08/10 15:03:56 [INFO] Cleaning up temporary folder: /tmp/buildenv_2022-08-10-1503.1377463227
コンパイルが終了したら、結果のバイナリを/usr/binに移動するには、以下を実行してください:
- sudo mv caddy /usr/bin
次に、適切な権限を設定します:
- sudo chown root:root /usr/bin/caddy
- sudo chmod 755 /usr/bin/caddy
次に、CaddyをDigitalOceanのAPIと連携させてDNSレコードを設定するために構成します。CaddyはDigitalOceanのDNSを設定するためにAPIトークンを環境変数として読み取る必要があるため、そのsystemdユニットファイルを編集します。編集のためにファイルを開きます:
- sudo nano /etc/systemd/system/caddy.service
[Service] セクションに、your_token_here をあなたのAPIトークンに置き換えて、強調表示された行を追加してください:
...
[Service]
Type=notify
User=caddy
Group=caddy
Environment=DO_AUTH_TOKEN=your_token_here
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
...
このファイルを保存して閉じた後、設定が更新されていることを確認するために systemd デーモンをリロードしてください:
- sudo systemctl daemon-reload
systemctl restart を実行して、構成変更を確認します:
- sudo systemctl restart caddy
次に、systemctl statusを実行して、それが正しく動作したか確認します:
- sudo systemctl status caddy
次の出力を受け取ります:
● caddy.service - Caddy
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
Active: active (running) since Wed 2022-08-10 15:06:01 UTC; 2s ago
Docs: https://caddyserver.com/docs/
Main PID: 5620 (caddy)
Tasks: 7 (limit: 1119)
Memory: 7.5M
CPU: 37ms
CGroup: /system.slice/caddy.service
└─5620 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
次に、Caddyfileに少し変更を加える必要がありますので、編集のために開いてください:
- sudo nano /etc/caddy/Caddyfile
強調表示された行をCaddyfileに追加してください。your_domainをあなたのドメイン(http://の代わりに)に置き換え、DigitalOcean DNSを指定したtlsブロックを追加します:
your_domain {
root * /var/www
encode gzip
file_server
tls {
dns digitalocean {env.DO_AUTH_TOKEN}
}
}
ホスト名にプロトコル指定子ではなくドメインを使用すると、CaddyはHTTPS経由でリクエストを処理します。tlsディレクティブは、TLSを使用する際のCaddyの動作を設定し、DNSレコードを設定し、証明書を要求するためにdigitaloceanプラグインを使用するように指示します。dnsサブディレクティブは、CaddyがHTTPではなくDigitalOceanのDNSシステムを使用するべきであることを指定します。
ファイルを保存して閉じてください。
これで、あなたのウェブサイトはデプロイの準備が整いました。systemctlでCaddyを再起動し、次にenableしてブート時に実行されるようにします:
- sudo systemctl restart caddy
- sudo systemctl enable caddy
ドメインにアクセスすると、自動的にHTTPSにリダイレクトされ、同じこのページはCaddyを介して提供されていますというメッセージが表示されます。
あなたのCaddyのインストールは完了し、安全に設定されました。さらに、あなたの使用ケースに応じてカスタマイズできます。
結論
サーバーにCaddyがインストールされ、設定されており、希望するドメインでスタティックページを提供し、無料のLet’s Encrypt TLS証明書で保護されています。
次の良いステップは、Caddyの新しいバージョンがリリースされたときの通知を設定することです。例えば、CaddyリリースのためのAtomフィードや、dependencies.ioなどの専用サービスを利用することができます。Caddyの設定に関する詳細情報は、Caddyのドキュメントを参照してください。
Go言語の使い方について、私たちの「Goでコーディングする方法」シリーズを通じてさらに学ぶこともできます。

