前回からの続きです。
【Astro入門】トップページに新着記事一覧を表示!getCollectionを使ったデータ取得と並び替え
今回は、作成したサイトをインターネットに公開するための本番環境を構築していきます。
本番環境の構成内容
本番環境は以下の構成で構築します。
- Astro開発用コンテナ(いままで使用していたもの)
- 開発環境として使用していたもので、HTMLやCSSなどの静的ファイルをビルド(作成)する際にも使用します。
- Podmanのコンテナとして作成されています。
- コンテンツ公開用Nginxコンテナ(新規作成)
- Astroが作成したHTMLやCSSなどの静的ファイルを公開するために使用します。
- Podmanのコンテナで新規に作成します。
- リバースプロキシ用Nginx(新規作成)
- インターネットからの通信をコンテンツ公開用Nginxに振り分けたり、HTTPS接続の処理を行います。
- 新規でホストに直接インストールします。
Astroコンテナでの作業
開発用として使用していたAstroで以下の作業を行います。
- astro.config.mjsへ本番環境で使用するFQDN設定
- 静的ファイルのビルド(生成)
Astro設定(本番で使用するFQDN設定)
本番環境に向けて、プロジェクトの一番上の階層にある「astro.config.mjs」に、本番環境で使用するFQDNの設定を行います。
設定内容
「gamelife.server-memo.net」を、本番環境で使用するFQDNとして設定を行っていきます。
変更前
初期状態の「astro.config.mjs」は以下の通りです。
// @ts-check
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({});
変更後
「export default defineConfig({});」の({})内に、FQDNを「site: 'https://gamelife.server-memo.net',」といったように追加します。
// @ts-check
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({
site: 'https://gamelife.server-memo.net',
});
サブディレクトリで公開したい場合
もしサイトを「https://vpslife.server-memo.net/」ではなく、「https://vpslife.server-memo.net/gamelife/」といったように「特定のフォルダの中(サブディレクトリ)」で公開したい場合は、「site」とセットで「base」という設定も追加します。
export default defineConfig({
site: 'https://vpslife.server-memo.net',
base: '/gamelife', // サブディレクトリの場合はこれを追加
});
Astroで静的ファイルをビルド(作成)
HTMLやCSSファイルなどの静的ファイルを作成するために、以下のコマンドを実行してビルド作業を行います。
コマンドを実行することで、distディレクトリの中にディレクトリやファイルが生成されます。
$ npm run build
今回はAstroがPodmanのコンテナとして構築されているため、「compose.yaml」があるディレクトリで以下のコマンドを実行します。
$ podman-compose exec コンテナ名 npm run build
実際にビルドを行ってみます。
$ podman-compose exec astro-dev npm run build podman-compose version: 1.0.6 ['podman', '--version', ''] using podman version: 4.9.3 podman exec --interactive --tty astro-dev npm run build > build > astro build ### 中略 ### 13:13:58 ▶ src/pages/index.astro 13:13:58 └─ /index.html (+22ms) 13:13:58 ✓ Completed in 272ms. generating optimized images 13:13:58 ▶ /_astro/20250321-01.BaDWPF5Q_1pEGEg.webp (before: 150kB, after: 40kB) (+510ms) (1/2) 13:13:58 ▶ /_astro/20250321-02.yWHbI897_Zknfaw.webp (before: 155kB, after: 43kB) (+527ms) (2/2) 13:13:58 ✓ Completed in 531ms. 13:13:58 [build] 10 page(s) built in 6.26s 13:13:58 [build] Complete! exit code: 0
ビルドが完了すると、「dist」ディレクトリが作成されます。
$ ls -l | grep dist drwxr-xr-x 6 tamohiko tamohiko 4096 3月 26 22:13 dist
distディレクトリの中には、HTMLファイル等が生成されています。
$ ls -l dist/ 合計 28 drwxr-xr-x 2 tamohiko tamohiko 4096 3月 26 22:13 _astro drwxr-xr-x 2 tamohiko tamohiko 4096 3月 26 22:13 about drwxr-xr-x 7 tamohiko tamohiko 4096 3月 26 22:13 blog -rw-r--r-- 1 tamohiko tamohiko 655 3月 26 22:13 favicon.ico -rw-r--r-- 1 tamohiko tamohiko 749 3月 26 22:13 favicon.svg drwxr-xr-x 3 tamohiko tamohiko 4096 3月 26 22:13 game -rw-r--r-- 1 tamohiko tamohiko 2395 3月 26 22:13 index.html
コンテナの停止
静的ファイルのビルドが完了したら、現在起動している開発環境のコンテナは起動させておく必要はないので、以下のコマンドで停止しておきます。
$ podman-compose down
コンテンツ公開用Nginxコンテナ作業
コンテンツ公開用Nginxコンテナを構築していくために、以下の作業を行います。
- 設定ファイル(default.conf)の作成
- compose.yamlにNginxのコンテナ設定追加
- コンテナ起動
- 動作確認
設定ファイル(default.conf)の作成
Astroのプロジェクトのディレクトリに、コンテンツ公開用のNginx設定ファイルを格納するためのディレクトリを準備し、そこに設定ファイルを作成します。
ディレクトリの作成
今回は「~/project/astro-dev/nginx」という名前でディレクトリを作成していきます。
$ mkdir ~/project/astro-dev/nginx
設定ファイル(default.conf)の作成
Nginxの設定ファイルを「default.conf」という名前で作成し、以下の内容を設定します。
キャッシュを保持する時間などは、お好きなように適宜変更してください。
server {
listen 80;
# サーバーのドメインを指定します
server_name gamelife.server-memo.net;
# Astroが生成した静的ファイル(distの中身)を置く場所
# ※Podmanコンテナ内の標準的なパスを指定しています
root /usr/share/nginx/html;
# ディレクトリにアクセスされた時に読み込むファイル
index index.html;
# 文字コードの設定
charset utf-8;
# URLの処理ルール
location / {
# $uri : まずはURLと完全一致するファイルを探す
# $uri/ : なければ、その名前のディレクトリを探して中の index.html を返す(AstroのURL構造に必須)
# =404 : どちらもなければ 404 Not Found エラーにする
try_files $uri $uri/ =404;
}
# キャッシュの設定
# 画像、CSS、JavaScriptファイルなどは、訪問者のブラウザに1日間保存させます
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|ttf|eot)$ {
expires 1d;
access_log off; # これらのファイルのアクセスログをオフにして負荷を減らす
}
# エラーページの設定(Astroで 404.astro を作っている場合)
error_page 404 /404.html;
location = /404.html {
internal;
}
}
compose.yamlへNginxのコンテナ設定を追加
既存の「compose.yaml」に、以下のコンテンツ公開用Nginxコンテナ(astro-nginx)の設定を追加します。
services:
astro-dev:
##### 中略 #####
# 追加する部分
astro-nginx:
image: docker.io/nginx:alpine
ports:
# ホスト側の 8080番ポート と コンテナの 80番ポート を繋ぐ
- "8080:80"
volumes:
# 静的ファイルが格納されているdistディレクトリをマウント
- ./dist:/usr/share/nginx/html:ro
# nginxの設定ファイルをマウント
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
コンテナの起動
以下のコマンドで、追加した「astro-nginx」コンテナを起動します。
$ podman-compose up astro-nginx -d
動作確認
実際にWebブラウザから「http://ホスト名:8080」へ接続して、Astroで作成したサイトが表示されるか確認を行ってください。
確認手順
VPSなどにAstroの環境を構築している場合は、以下の方法で動作確認を行うことができます。
hostsへgamelife.server-memo.netを登録
Linux(Ubuntuなど)やmacOSであれば「/etc/hosts」に、Windowsであれば「C:\Windows\System32\drivers\etc\hosts」に以下の内容を追加します。
※「gamelife.server-memo.net」の部分はご自身の環境に合わせて適宜読み替えてください。
127.0.0.1 gamelife.server-memo.net
SSHのポートフォワーディングを設定
手元のPCのターミナル(コマンドプロンプトなど)から、以下のコマンドでVPSへSSH接続し、ポートフォワーディングを行うよう設定します。
$ ssh -L 8080:localhost:8080 ユーザー名@VPSサーバ
これにより、手元のPC(localhost)の8080番ポートへの接続が、自動的にVPSの8080番ポートへ転送されるようになります。
この状態で、ブラウザから以下のURLへアクセスしてサイトが表示されれば成功です。
接続URL例: http://gamelife.server-memo.net:8080
動作確認が終わったら、hostsに追加した設定は忘れずに削除しておいてください。
リバースプロキシ用Nginx
インターネットからの接続をコンテンツ公開用Nginxへ振り分けたり(リバースプロキシ)、HTTPS接続の処理を行うためのNginxを、以下の手順で構築していきます。
- Nginxのインストール
- Nginxの公式サイトで公開しているリポジトリを使用してインストールします。
- Let's EncryptでSSL/TLS証明書の取得
- Certbotをインストールし、Let's EncryptでSSL/TLS証明書を取得します。
- リバースプロキシ用の設定
- コンテンツ公開用Nginxへの振り分け設定を行います。
- 動作確認
- Webブラウザで接続して、Astroで作成したサイトが表示されるかの確認を行います。
なお、インターネットでWebサイトを公開するためには、公開するホストの名前をDNSに設定しておく必要がありますので、こちらの準備も忘れずにしておいてください。
Nginxのインストール
Nginxの公式サイトで公開しているリポジトリを使用してインストールします。
まず、Nginxのインストールに必要となるパッケージをインストールします。
$ sudo apt update $ sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
リポジトリの追加
Nginxの署名鍵をインポートします。
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
リポジトリの追加を行います。
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \ | sudo tee /etc/apt/sources.list.d/nginx.list
Nginxのインストール
aptでNginxをインストールします。
$ sudo apt update $ sudo apt install nginx
より詳しい手順は以下のページで解説していますので、そちらをご確認ください。
Let's EncryptでSSL/TLS証明書の取得
Let's EncryptでSSL/TLS証明書を取得するためには、まずインターネットから対象のホスト(ドメイン)へHTTPでアクセスできる状態にしておく必要があります。ここでは、そのための最低限のNginx設定を行っていきます。
ルートディレクトリの作成
まずは、Nginxのルートディレクトリとして「/usr/share/nginx/gamelife」を作成し、同時に動作確認用の「index.html」ファイルも作成します。
$ sudo mkdir /usr/share/nginx/gamelife $ echo gamelife.server-memo.net | sudo tee /usr/share/nginx/gamelife/index.html
Nginx設定ファイルの作成
HTTPで接続するための最低限の設定を記述した設定ファイルを、「gamelife.server-memo.net.conf」という名前で作成します。
$ sudo vi /etc/nginx/conf.d/gamelife.server-memo.net.conf
設定内容は以下のとおりです。
server {
server_name gamelife.server-memo.net;
root /usr/share/nginx/gamelife;
index index.html;
}
設定の反映
設定が完了したら、以下のコマンドを実行して文法エラーがないか確認し、Nginxを再起動して設定を反映させます。
$ sudo nginx -t $ sudo systemctl restart nginx
動作確認
Webブラウザから「http://gamelife.server-memo.net」にアクセスして、先程作成したindex.htmlの内容(gamelife.server-memo.net)が画面に表示されることを確認してください。
Certbotのインストール
Let's EncryptでSSL/TLS証明書を取得するためのクライアントであるCertbot本体と、Nginx用のプラグインである「python3-certbot-nginx」をインストールします。
$ sudo apt install certbot python3-certbot-nginx
SSL/TLS証明書の取得
certbotコマンドを実行してSSL/TLS証明書の取得作業を行います。
$ sudo certbot --nginx -d ホスト名 -m メールアドレス --agree-tos
今回の場合はホスト名が「gamelife.server-memo.net」なので、「/etc/letsencrypt/live/gamelife.server-memo.net/」ディレクトリ内に証明書が作成されます。
この段階で、Certbotが自動的にHTTPS接続用の設定を、Nginxの設定ファイル(gamelife.server-memo.net.conf)に追記してくれます。
設定が追加されると、自動的にNginxへ設定が反映(リロード)されます。
その後、実際にHTTPS接続が出来るようになっているか、Webブラウザで対象のURL(https://gamelife.server-memo.net)へアクセスして動作確認を行ってください。
詳しい手順は以下のページで解説していますので、そちらもご確認ください。
リバースプロキシ用設定
リバースプロキシ用の設定を行っていきます。
とりあえず最低限の設定だけ行いますので、必要があれば設定を適宜追加してください。
$ cd /etc/nginx $ sudo vi proxy_params
設定内容は以下のとおりです。
これで、実際のクライアント情報を、コンテンツ公開用Nginxでログに残すようにすることが出来ます。
この設定がないと、接続クライアントのIPアドレスが、すべてプロキシサーバのものになってしまいます。
proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
コンテンツ公開用Nginxへの振り分け設定
インターネットからの接続を、コンテンツ公開用Nginxへ振り分けるための設定を追加します。
$ cd conf.d $ sudo vi gamelife.server-memo.net.conf
そこに、以下の設定を追加します。
- コンテンツ公開用Nginxへ通信振り分け設定
- SSL/TLS証明書の自動更新用設定
# コンテンツ公開用Nginxコンテナをastro_nginxという名前で設定 upstream astro_nginx { server 127.0.0.1:8080 fail_timeout=0; } server { server_name gamelife.server-memo.net; index index.html; charset utf-8; root /usr/share/nginx/gamelife; access_log /var/log/nginx/gamelife_access.log ; error_log /var/log/nginx/gamelife_error.log ; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/gamelife.server-memo.net/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/gamelife.server-memo.net/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot # SSL/TLS更新時に一時ファイルを作成するディレクトリを指定 # リバースプロキシの設定より前に記述すること # gamelife.server-memo.net/.well-known宛の通信は # /usr/share/nginx/gamelifeをルートディレクトリとする location ^~ /.well-known { root /usr/share/nginx/gamelife; } # リバースプロキシ設定 # gamelife.server-memo.net宛の通信は # upstreamで設定したastro_nginxへ転送する location / { include proxy_params; proxy_pass http://astro_nginx; } } server { if ($host = gamelife.server-memo.net) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name gamelife.server-memo.net; return 404; # managed by Certbot }
設定反映
Nginxを再起動して設定を反映させます。
$ sudo nginx -t $ sudo systemctl restart nginx
動作確認
実際にWebブラウザで接続して、Astroで作成したサイトが表示されるかの確認を行ってください。
https://gamelife.server-memo.net
自動起動設定
最後に、Astroコンテンツ公開用のNginxコンテナ「astro-nginx」を、サーバー起動時に自動的に起動させるための設定を行います。
今回は、PodmanのRootlessコンテナ運用に最適な「systemdのユーザーサービス」を使用して設定していきます。
設定ファイルの作成
ユーザーサービス用の設定ファイルを格納するためのディレクトリ「~/.config/systemd/user」を作成し、そこに「astro-nginx.service」という名前で設定ファイルを作成します。
$ mkdir -p ~/.config/systemd/user $ vi ~/.config/systemd/user/astro-nginx.service
設定内容は以下のとおりです。
※「WorkingDirectory」のパスは、ご自身の環境の「compose.yaml」があるディレクトリに書き換えてください。
[Unit] Description=Astro Nginx Production Container [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/home/tamohiko/project/astro/gamelife ExecStart=/usr/bin/podman-compose up astro-nginx -d ExecStop=/usr/bin/podman-compose stop astro-nginx [Install] # ユーザーサービスの場合は default.target にします WantedBy=default.target
設定の読み込み
作成した設定ファイルをsystemdに読み込ませます。ユーザーサービスに対するコマンドなので、「--user」オプションを忘れずにつけてください。
$ systemctl --user daemon-reload
コンテナの起動と常駐設定(Linger有効化)
サーバー再起動後、ユーザーがまだログインしていない状態でもコンテナを自動起動・常駐させるために、以下のコマンドを実行します。
※「tamohiko」の部分は、現在ログインしているご自身のユーザー名に書き換えてください。
$ sudo loginctl enable-linger tamohiko
続いて、コンテナの起動と、自動起動設定(OS起動時の有効化)を同時に行います。
$ systemctl --user enable --now astro-nginx.service
動作確認
「astro-nginx」サービスが正常に起動しているかを、以下のコマンドで確認します。
Active: の部分が active (exited) になっていれば成功です。
$ systemctl --user status astro-nginx
● astro-nginx.service - Astro Nginx Production Container
Loaded: loaded (/home/tamohiko/.config/systemd/user/astro-nginx.service; enabled; preset: enabled)
Active: active (exited) since Tue 2026-03-31 17:04:06 JST; 4h 24min ago
Process: 922 ExecStart=/usr/bin/podman-compose up astro-nginx -d (code=exited, status=0/SUCCESS)
Main PID: 922 (code=exited, status=0/SUCCESS)
Tasks: 14 (limit: 1054)
Memory: 4.9M (peak: 42.7M swap: 2.1M swap peak: 2.1M)
CPU: 936ms
##### 以下省略 #####
この状態で、Astroで作成したWebサイトにブラウザでアクセスして、正常に表示できるかどうかを確認してください。
問題がなければ、一度サーバー自体を再起動(sudo reboot)し、再起動後に何もコマンドを叩かなくてもWebサイトが表示できること(自動起動が成功していること)を確認してください。
日々の運用方法
最後に、AstroでWebサイトを運用していく場合の、日常的な作業フロー(運用方法)をまとめます。
記事の作成・更新
普段はAstroの開発用コンテナは停止しておき、「src/content」ディレクトリ配下で記事を作成・編集したあとにのみビルドを行い、HTMLファイルなどを生成する運用にします。
実際には、「compose.yaml」があるディレクトリで以下のコマンドを実行します。
$ podman-compose run --rm astro-dev npm run build
この「run --rm」コマンドを使うことで、ビルド処理が終わった直後にAstroコンテナが自動的に停止・削除されます。これにより、VPSの限られたメモリやリソースを無駄に消費せずに済みます。
開発環境を使用する場合
デザインの変更や動作確認など、ブラウザでリアルタイムに編集結果を確認しながら作業したい場合は、以下のコマンドでAstro開発用コンテナを起動して作業を行います。
$ podman-compose up -d astro-dev
作業が終了したら、無駄なリソースを使わないように以下のコマンドでコンテナを停止しておきます。
$ podman-compose down astro-dev





コメント