ConoHa VPS に Docker Compose で Python API を構築する手順
ConoHa VPSにUbuntu 24.04でDocker Composeを使ってPython APIサーバーを構築する完全手順。SSH公開鍵設定・ufw・DockerインストールからFastAPI構成・Nginxリバースプロキシ・自動起動まで、帯域制限の実体験も含めて解説する。

VPSにNext.jsを本番デプロイするとき、多くの記事は next start をそのまま動かす構成を紹介している。しかしその方法では、node_modules を含む全ファイルをコンテナにコピーすることになり、Dockerイメージが1GB近くになることも珍しくない。
Next.jsには output: 'standalone' という設定があり、これを使うと本番実行に必要なファイルだけを含む軽量なビルド出力が得られる。.next/standalone/server.js を node で直接実行するシンプルな構成で、イメージサイズを数百MB単位で削減できる。
この記事では、Xserver VPSにUbuntu 24.04でDocker Composeを使い、Next.jsをスタンドアロン出力で本番デプロイする手順を一から解説する。静的ファイルをNginxで直配信する構成・Xserver VPS特有のパケットフィルター設定・多くの記事が見落としている HOSTNAME 環境変数の設定まで含めて書く。
VPSの契約・初期設定から、GitHub Actionsによる自動デプロイ、運用に入ったあとのログ確認・ディスク管理・DBバックアップまで、実際に運用して必要になったものを一本にまとめてある(運用しているのは ConoHa VPS。詳細は後述)。
Xserver VPSを選ぶ理由として最も大きいのは、データ転送量が無制限という点だ。
ConoHa VPSは共有100Mbps回線で「他のユーザーへの影響が出るレベルのトラフィック」が発生すると帯域が500kbps前後まで絞られる仕様がある(実体験はConoHa VPS Docker記事に書いた)。Next.jsアプリは画像・JS・CSSなどの静的アセットを配信するため、アクセスが増えてきたときの帯域制限は痛手になる。Xserver VPSはデータ転送量無制限を明示しており、突然の帯域制限を気にせず運用できる。
また、全プランにNVMe SSDのRAID0構成が採用されており、DockerのビルドやNext.jsのファイルI/O処理が速い。
| 項目 | Xserver VPS | ConoHa VPS |
|---|---|---|
| ストレージ | NVMe SSD(RAID0) | SSD |
| データ転送量 | 無制限 | 制限あり(共有100Mbps) |
| CPU | AMD EPYC™ 3世代 | 非公開 |
| 2GB / 36ヶ月 | 新規受付停止中 | 約¥657/月 |
| 4GB / 36ヶ月 | 約¥2,035/月 | 約¥1,184/月 |
2026年9月時点:Xserver VPS の2GBプランは新規受付を停止している
公式の料金ページで全契約期間にわたり「新規受付を一時停止しています」と表示されている。
いま新規契約できる最小構成は4GB(36ヶ月で月¥2,035)だ。
この記事は2GBプランで構築した実構成をもとに書いているが、これから同じ構成を作る場合は
4GBプランを前提に読んでほしい(手順自体は変わらない)。
価格重視で2GB帯を探しているなら、現時点では ConoHa VPS(36ヶ月で月¥657)が選択肢になる。
以前は2GB帯でもXserver VPSの方が安かったが、受付停止と価格改定によって状況が変わった。 転送量無制限とNVMe SSDという強みは変わらないので、4GB以上を前提にするなら依然として有力だ。
自分が本番運用しているのは ConoHa VPS で、Xserver VPS は使っていない
この記事で解説する Docker Compose + Next.js スタンドアロン出力の構成は、
実際に運用しているものだ。ただしそれを動かしているのは ConoHa VPSで、
Xserver VPS 上で半年運用した実績があるわけではない。
ここから先の Xserver VPS 固有の記述(プラン構成・パケットフィルター・コントロールパネルの操作)は、
公式ドキュメントと料金ページに当たって書いたものだ。
使用感の評価は書かない。手順の再現性で判断してほしい。
使用感ではなく、公式が明示している仕様のうち、この構成で効いてくるものを挙げておく。
VPS各社の詳しい比較はVPS比較記事にまとめているので、まだVPSを選定中の場合はそちらも参照してほしい。
Xserver VPS の料金を確認する →
※本リンクはアフィリエイトリンクですこの記事では以下の環境を前提に書く。
| 項目 | 内容 |
|---|---|
| OS | Ubuntu 24.04 LTS |
| Docker Engine | 26.x(2026年5月時点) |
| Docker Compose | v2.x(docker compose コマンド) |
| Node.js | 20 LTS(Dockerイメージ内) |
| フレームワーク | Next.js 14 / 15(App Router対応) |
| ローカル環境 | macOS または Linux |
Docker Compose v1(docker-compose)は非推奨
docker-compose(ハイフンあり)コマンドはすでに非推奨・EOL。2026年時点ではdocker compose(スペース区切り)が標準だ。古い記事の手順をコピーするときは要注意。
この記事の構成は2GBプランで組んだものだが、前述のとおり2GBは新規受付が停止している(2026年9月時点)。 これから契約するなら4GBプランが実質的な入口になる。Xserver VPSはコントロールパネルから オンラインでスケールアップできるので、あとから上げること自体は難しくない。
2026年9月時点で公式料金ページに掲載されているプラン構成は以下のとおり(36ヶ月契約・月額換算)。
| プラン | メモリ | vCPU | NVMe SSD | 36ヶ月(月額換算) |
|---|---|---|---|---|
| 2GBプラン | 2GB | 3コア | 50GB | 新規受付停止中 |
| 4GBプラン | 4GB | 4コア | 150GB | ¥2,035 |
| 8GBプラン | 8GB | 6コア | 400GB | ¥3,850 |
| 16GBプラン | 16GB | 8コア | 800GB | ¥8,690 |
※ 1GBプランは存在しない。最小構成は2GBプラン。 ※ 契約期間分の一括前払い。申込前に必ず公式の料金ページで最新の価格を確認すること。
用途別の目安はこうなる。
Dockerを使う場合はコンテナ自体が数百MB〜1GBのメモリを食う。実際に2GBで Next.js + PostgreSQL + Nginx の3コンテナ構成を動かしていたが、余裕があったとは言えない。 4GBが下限になったことは、この用途ではむしろ扱いやすい。
Xserver VPSのOSテンプレートはUbuntu・AlmaLinuxなど複数から選べる。Dockerの公式サポートが最も手厚く、情報量も多いのはUbuntuだ。24.04 LTSを選べばセキュリティアップデートが2029年まで保証される。
アプリイメージは選ばない
Xserver VPSにはWordPressやLAMPがプリインストールされた「アプリイメージ」がある。Dockerで自前管理したい場合は素のUbuntuを選ぶこと。アプリイメージを選ぶと既存のApache等が起動しており、80/443ポートが競合する。
Xserver VPSでサーバーを作成すると、rootユーザーのパスワードログインが有効な状態で起動する。以下の順で初期設定を行う。
ローカルマシンで鍵ペアを生成する。
ssh-keygen -t ed25519 -C "your_email@example.com"
# ~/.ssh/id_ed25519 と id_ed25519.pub が生成される
cat ~/.ssh/id_ed25519.pub
# 表示された公開鍵をコピーしてXserverコンパネに登録するXserver VPSのコントロールパネル → 「SSH Key」→「SSH Keyを登録」で公開鍵を登録しておくと、サーバー作成時に自動で設定される。
ssh root@<サーバーのIPアドレス>一般ユーザーを作成してsudo権限を付与する。
adduser deploy
usermod -aG sudo deploy
# rootの公開鍵を新しいユーザーにコピー
mkdir -p /home/deploy/.ssh
cp ~/.ssh/authorized_keys /home/deploy/.ssh/
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keysvim /etc/ssh/sshd_config# rootログインを禁止
PermitRootLogin no
# パスワード認証を無効化(公開鍵のみ許可)
PasswordAuthentication no
# ポートをデフォルトから変更(任意だが推奨)
Port 2222systemctl restart sshd切断前に必ず別ターミナルで接続確認
sshd_configを変更した後、現在の接続を切る前に別のターミナルから新しい設定で接続できることを確認すること。設定ミスのまま切断するとVPSにアクセスできなくなる。
# SSHポートを先に許可してから有効化する
sudo ufw allow 2222/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw statusXserver VPSにはコントロールパネル上に独自の「パケットフィルター」機能がある。ufwに加えてコントロールパネル側でもポートを開放しないと外部からアクセスできない。
コントロールパネル → サーバー詳細 → 「パケットフィルター」→「パケットフィルターの設定」から以下を許可する。
| 対象 | プロトコル | ポート |
|---|---|---|
| SSH | TCP | 2222(変更した場合) |
| HTTP | TCP | 80 |
| HTTPS | TCP | 443 |
ufwとパケットフィルターの両方が必要
「ufwで開けたのに接続できない」というトラブルの多くは、コントロールパネルのパケットフィルターが閉じていることが原因だ。うまく接続できない場合は必ず両方を確認してほしい。
sudo apt-get remove docker docker-engine docker.io containerd runcsudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-pluginsudo usermod -aG docker $USER
newgrp dockerdocker --version
# Docker version 26.x.x
docker compose version
# Docker Compose version v2.x.x
docker run hello-worldHello from Docker! と表示されれば成功だ。
next.config.js(または next.config.ts)に output: 'standalone' を追加する。
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
}
module.exports = nextConfigこの設定でビルドすると、.next/standalone/ に本番実行に必要なファイルだけが出力される。
.next/
├── standalone/
│ ├── server.js ← node で直接実行するエントリーポイント
│ ├── node_modules/ ← 本番に必要な依存のみ(ツリーシェイク済み)
│ └── .next/
│ └── server/ ← サーバーサイドのコード
├── static/ ← クライアント向け静的ファイル(standalone に含まれない)
└── ...
public/ ← 画像・フォントなど重要なのは、static/ ディレクトリは standalone/ の中に含まれないという点だ。Dockerfileで別途コピーする必要がある。これを知らないと静的ファイルがコンテナに入らず、ページのスタイルが崩れる原因になる。
マルチステージビルドを使い、本番イメージに含まれるファイルを最小限にする。
# ---- Stage 1: 依存インストール ----
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
# ---- Stage 2: ビルド ----
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
# ---- Stage 3: 本番ランナー ----
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
# HOSTNAME=0.0.0.0 を明示的に設定する(後述)
ENV HOSTNAME=0.0.0.0
# スタンドアロン出力をコピー
COPY --from=builder /app/.next/standalone ./
# 静的ファイルを正しい位置にコピー
COPY --from=builder /app/.next/static ./.next/static
# public/ をコピー(OGP画像・フォントなど)
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]HOSTNAME 未設定でNginxからのリクエストが届かなくなる
Next.jsスタンドアロン出力の server.js は、HOSTNAME 環境変数が設定されていない場合に localhost(127.0.0.1)でバインドすることがある。この状態だとコンテナ内では起動しているのにNginxからのリクエストが届かず、502 Bad Gatewayになる。ENV HOSTNAME=0.0.0.0 をDockerfileに書いておけば確実に防げる。
FROM node:20-alpine AS deps
RUN npm install -g pnpm
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfilenode_modules
.next
.git
.env*
*.md.next/ を除外しているのは、ローカルのビルドキャッシュがコンテナ内のビルドに干渉しないようにするためだ。docker compose up --build のたびにコンテナ内でフルビルドを実行する。
myapp/
├── docker-compose.yml
├── Dockerfile
├── .dockerignore
├── nginx/
│ └── default.conf
└── (Next.jsのソースコード)services:
nextjs:
build: .
container_name: nextjs
restart: always
expose:
- "3000"
volumes:
- nextjs_static:/app/.next/static
environment:
NODE_ENV: production
nginx:
image: nginx:alpine
container_name: nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- nextjs_static:/var/www/html/_next/static:ro
depends_on:
- nextjs
volumes:
nextjs_static:nextjs_static という名前付きボリュームを使い、Next.jsコンテナが持つ .next/static/ をNginxが読めるようにしている。
名前付きボリュームの初期化タイミング
Dockerの名前付きボリュームは、空の状態で初めて作成されるとき、コンテナのディレクトリ内容でInitializeされる。再デプロイ時に古い静的ファイルが残り続ける問題があるため、コードを更新して再デプロイするときは docker compose down -v でボリュームを削除してから起動し直す必要がある(後述)。
server {
listen 80;
server_name _;
# /_next/static/ はNginxが直接配信(1年キャッシュ)
location /_next/static/ {
alias /var/www/html/_next/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
# それ以外はNext.jsコンテナへプロキシ
location / {
proxy_pass http://nextjs:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $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;
proxy_cache_bypass $http_upgrade;
}
}/_next/static/ にはNext.jsがビルド時にコンテンツハッシュ付きのファイル名を付ける(例:_next/static/chunks/main-a1b2c3.js)。ファイルが更新されると必ずファイル名も変わるため、1年間キャッシュしても古いファイルを掴み続ける問題は起きない。
cd ~/myapp
docker compose up -d --build
# ログ確認
docker compose logs -f
# 動作確認(IPアドレスで確認)
curl http://localhost/VPSのIPアドレスにブラウザでアクセスしてNext.jsアプリが表示されれば成功だ。
本番運用にはHTTPS化が必須だ。ドメインを取得してVPSのIPアドレスに向けておく必要がある。
services:
nextjs:
build: .
container_name: nextjs
restart: always
expose:
- "3000"
volumes:
- nextjs_static:/app/.next/static
environment:
NODE_ENV: production
nginx:
image: nginx:alpine
container_name: nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- nextjs_static:/var/www/html/_next/static:ro
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
depends_on:
- nextjs
certbot:
image: certbot/certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
volumes:
nextjs_static:server {
listen 80;
server_name example.com www.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location /_next/static/ {
alias /var/www/html/_next/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
proxy_pass http://nextjs:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $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;
proxy_cache_bypass $http_upgrade;
}
}docker compose run --rm certbot certonly \
--webroot \
--webroot-path=/var/www/certbot \
--email your@email.com \
--agree-tos \
--no-eff-email \
-d example.com \
-d www.example.com
# Nginxを再起動して証明書を読み込む
docker compose restart nginx# crontab -e で以下を追加
0 0 * * 0 cd ~/myapp && docker compose run --rm certbot renew && docker compose restart nginxコードを更新して再デプロイする際の手順をまとめておく。
cd ~/myapp
# 最新コードをpull(GitHubで管理している場合)
git pull origin main
# ボリュームを削除してビルドし直す
docker compose down -v
docker compose up -d --build-v でボリュームを削除しているのは、nextjs_static ボリュームに古いビルドの静的ファイルが残り続けるのを防ぐためだ。これをしないと古いJSファイルがNginxから配信され続け、画面が壊れることがある。
ダウンタイムを最小化したい場合
docker compose down -v の間は一時的にサービスが止まる。個人開発や副業プロジェクトであれば数秒のダウンタイムは許容範囲内だ。無停止デプロイが必要になったときは、Blue-Greenデプロイや docker compose up -d --scale を使う構成を検討すること。
GitHub Actionsで自動化する場合は以下のワークフローが基本形だ。
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to VPS
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: deploy
key: ${{ secrets.VPS_SSH_KEY }}
port: 2222
script: |
cd ~/myapp
git pull origin main
docker compose down -v
docker compose up -d --buildデプロイ用のSSH鍵はVPS側で生成しておく。普段ログインに使っている鍵をそのままGitHubに渡さないこと。
ssh-keygen -t ed25519 -f ~/.ssh/deploy_key -N ""
cat ~/.ssh/deploy_key.pub >> ~/.ssh/authorized_keys
cat ~/.ssh/deploy_key # この秘密鍵の全文を GitHub Secrets に登録する登録先は GitHubリポジトリの Settings > Secrets and variables > Actions。
| Secret名 | 値 |
|---|---|
VPS_HOST | VPSのIPアドレス |
VPS_USER | 作成した一般ユーザー名(例: deploy) |
VPS_SSH_KEY | デプロイ用SSH秘密鍵(全文) |
DBコンテナを同居させている場合、down -v は使わないこと
上の再デプロイ手順で -v を付けているのは nextjs_static の古い静的ファイルを消すためだが、
docker compose down -v はそのcompose内の全ボリュームを削除する。
PostgreSQLなどを同じcomposeで動かしていると、デプロイのたびにデータベースが消える。
DBを同居させるなら、静的ボリュームだけを名前指定で消すか、次のように差し替える。
docker compose build app && docker compose up -d && docker image prune -f
デプロイまで通ったあと、実際に動かし続けるために要る操作をまとめておく。
# 全コンテナのログを追跡
docker compose logs -f
# 特定コンテナのログのみ
docker compose logs -f app
# 最新100行だけ見る
docker compose logs --tail=100 appDockerを使い続けると未使用のイメージ・コンテナ・ビルドキャッシュが溜まる。VPSはディスクが100GB程度なので、放置するとビルドが失敗するようになる。定期的に掃除する。
# 停止中コンテナ・未使用イメージ・キャッシュを削除
docker system prune -f
# ボリュームも含めて削除(注意: DBのデータも消える)
docker system prune -f --volumes# コンテナ別の使用量をリアルタイム表示
docker stats
# サーバー全体の負荷
htop2GBプランでNext.jsのビルドをVPS上で走らせるとメモリが逼迫しやすい。docker stats で張り付くようなら、ビルドをGitHub Actions側で行ってイメージだけを配る構成に変えるとよい。
イメージ保存はサーバー全体を丸ごと保存する機能で、DB単体を日次で戻す用途には向かない。DBのバックアップは自分で用意するしかない。
docker compose exec db pg_dump -U postgres myapp > backup_$(date +%Y%m%d).sqlcronで自動化する場合はこうする。
# 毎日午前2時にバックアップ
0 2 * * * cd ~/myapp && docker compose exec -T db pg_dump -U postgres myapp > ~/backups/backup_$(date +\%Y\%m\%d).sqlcron内では % をエスケープする必要がある点に注意。-T を付けないとTTYが無くて失敗する。
XServer VPSにNext.jsをDockerで載せたとき、一番詰まったのはリバースプロキシの設定ではなく、Dockerのnetwork設定だった。コンテナ間通信が「なぜかつながらない」という状態が2時間続いて、原因はdocker-compose.ymlのネットワーク定義の書き方の問題だった。公式ドキュメントをちゃんと読むべきだったと反省した。
Nginxが起動しているのにNext.jsコンテナに繋がらない場合。
docker compose ps
docker compose logs nextjsNext.jsコンテナが起動していても502になる場合は HOSTNAME 環境変数を確認する。localhost バインドになっているとコンテナ外からアクセスできない。Dockerfileに ENV HOSTNAME=0.0.0.0 が設定されているかを確認する。
docker compose down -v
docker compose up -d --builddocker compose ps
sudo ss -tlnp | grep :80ufwだけでなくXserver VPSコントロールパネルのパケットフィルターも確認すること。両方でポートが開放されていないと外部からアクセスできない。
docker: command not foundnewgrp docker
# またはいったんログアウトして再ログインdocker compose logs --tail=100 nextjsよくある原因:
next.config.js に output: 'standalone' が設定されていない → ビルドは成功するが server.js が出力されない.next/static/ のCOPY命令が抜けている → スタイルが当たらないかビルドエラー.env の値がコンテナに渡っていない)マルチステージビルドとBuildKitのキャッシュを活用すると2回目以降のビルドが速くなる。
DOCKER_BUILDKIT=1 docker compose up -d --buildどちらでも使える。output: 'standalone' は Next.js のルーターに関係なく機能する。App RouterのServer ActionsやServer Componentsも含めてスタンドアロン出力に含まれる。
含まれる。/api/*(Pages Router)や Route Handlers(App Router)はすべて server.js に含まれる。外部APIへのプロキシや認証ロジックもそのまま動く。
public/ フォルダのファイルはNginxで配信しなくていいのか?このDocker Compose構成では public/ の配信はNext.jsコンテナ(server.js)が担当する。ファイル数・サイズが少なければ問題ない。OGP画像など大量の静的アセットがある場合は public/ も別ボリュームでNginxに共有する構成に拡張できる。
Vercelの無料プランはAPIルートのタイムアウト(10秒)やサーバーレス関数のコールドスタートがある。バックグラウンドジョブや長時間処理を伴うAPIを動かす場合、VPSの方が柔軟だ。月額固定コストで使い方に制限がなく、個人開発では管理しやすい。
開発環境は .env.local を使うが、Dockerコンテナには渡さないのが基本だ。VPS上では docker-compose.yml の environment に直接書くか、.env ファイルを env_file で読み込む。
services:
nextjs:
build: .
env_file:
- .env.production
environment:
NODE_ENV: production.env.production はGitにコミットせず .gitignore に追加しておく。
Next.js 14/15 は Node.js 18.17 以上が必要だ。LTS版を使うのが安全で、2026年時点では Node.js 20(Active LTS)または Node.js 22(Current)が推奨される。node:20-alpine を node:22-alpine に変えても動く。
Xserver VPSへのNext.jsスタンドアロン出力 + Docker Composeデプロイの手順をまとめた。
docker stats でメモリ監視しながらスケールアップを判断するoutput: 'standalone' を設定してスタンドアロンビルドを有効化するENV HOSTNAME=0.0.0.0 が重要。.next/static/ の COPY も忘れずに.next/static/ をNginxに共有し、キャッシュ効率を上げるdocker compose down -v && docker compose up -d --build でボリュームごとリセットするデータ転送量無制限・NVMe SSD というXserver VPSのスペックは、Next.jsアプリのホスティングに向いている。2GBプランが新規受付停止中のため入口は4GB(36ヶ月で月¥2,035)になるが、個人開発から副業プロジェクトまで固定コストで安心して動かせる環境を作ってほしい。
NVMe SSD・データ転送量無制限。2026年9月時点では2GBが新規受付停止中で、4GBプランが36ヶ月で月¥2,035。個人開発のNext.jsアプリをVPSで動かすなら有力な選択肢だ。最新の受付状況と価格は公式サイトで確認してほしい。
Xserver VPS のプランを確認する →※本リンクはアフィリエイトリンクです
筆者が実運用しているのは ConoHa VPS だけです。比較記事では、使ったことがある事業者と公式仕様しか見ていない事業者を分けて明記しています。どちらの情報を読んでいるのかが分かる形にしてあります。
VPS比較を読むConoHa VPSにUbuntu 24.04でDocker Composeを使ってPython APIサーバーを構築する完全手順。SSH公開鍵設定・ufw・DockerインストールからFastAPI構成・Nginxリバースプロキシ・自動起動まで、帯域制限の実体験も含めて解説する。
ConoHa VPSを2025年5月に契約し、副業先の社内システムと本番・検証環境で1年以上運用してきた実体験レビュー。帯域制限に気づくまでの数日間の時系列、サポート対応の実際、長期契約12ヶ月の判断まで、勧める人・勧めない人を煽らずに正直に書いた。
フリーランスエンジニアの税金・積立・口座管理を自動化するWebアプリ「フリーランス金銭プランナー」を個人開発した。所得税・住民税・消費税・国保を自動計算し、毎月の積立目標と使える金額をリアルタイムに算出する仕組みと技術スタックを紹介する。