この記事はこんな人向けです
- シンクラウドVPSをはじめて借りた方
- ElixirやPhoenixでWebアプリを作っていて、本番公開に挑戦したい方
- VPS設定の全体像を把握したい方
手順は Ubuntu 26.04 + Phoenixアプリ を想定しています。
はじめに:全体の流れ
VPSを借りてからWebアプリが公開されるまで、大きく以下のステップを踏みます。
SSH設定 → ファイアウォール設定 → DNS設定
→ PostgreSQL・Elixir・Nginxインストール
→ アプリのデプロイ → systemd常駐化 → HTTPS化
一つ一つ順番に進めていきましょう。
1. Ubuntu 26.04 の SSH 自動起動設定
VPSを借りてコンソールにログインしたら、まず SSH サービスが自動起動するように設定します。
Ubuntu 26.04 以降では、SSHの起動方式が従来と変わっています。ssh.socket という「socket activation(ソケット起動)」方式が採用されたため、以下のコマンドで有効化します。
# Ubuntu 26.04以降はsocket方式で有効化します
sudo systemctl enable --now ssh.socket
sudo systemctl disable --now ssh
# Ubuntu 24.04以前の場合はこちらです
# sudo systemctl enable --now ssh
有効になったか確認します。
# Active: active (running) / enabled となればOKです
sudo systemctl status ssh
ポイント:
enable --nowは「今すぐ起動」+「次回起動時も自動起動」を同時に行うオプションです。enableだけだと今すぐは起動しないので注意しましょう。
2. コントロールパネルのパケットフィルター設定(SSH用)
⚠️ ここは見落としやすい重要ポイントです!
シンクラウドVPSでは、Ubuntu側の ufw(ファイアウォール)とは別に、コントロールパネル側でもポート開放が必要です。これを忘れると、外部からのアクセスが一切届きません(pingすら通りません)。
- シンクラウドVPSのコントロールパネルにログイン
- 左サイドメニュー →「パケットフィルター設定」
- 以下のルールを追加します
| プロトコル | ポート | 送信元IP |
|---|---|---|
| TCP | 22(後で変更推奨) | 0.0.0.0/0 |
もし設定後もSSHが繋がらない場合、まずここを確認しましょう。
3. 一般ユーザーの作成
セキュリティ上、rootユーザーでの作業は最小限にとどめましょう。一般ユーザーを作成し、sudo権限を付与します。
# 一般ユーザーを作成します(対話的にパスワード等の入力を求められます)
adduser sasami
# sudoグループに追加して管理者権限を付与します
usermod -aG sudo sasami
adduser コマンドを実行すると、パスワードや名前などを対話的に入力するよう求められます。パスワードはしっかり設定しましょう。
4. SSH鍵を一般ユーザーに設定
次回からは一般ユーザーでSSHログインできるよう、SSH鍵を設定します。rootの鍵をそのままコピーする方法が手軽です。
# .sshディレクトリを作成します
mkdir -p /home/sasami/.ssh
# rootのauthorized_keysをコピーします
cp /root/.ssh/authorized_keys /home/sasami/.ssh/
# 所有者をsasamiに変更します
chown -R sasami:sasami /home/sasami/.ssh
# パーミッションを設定します(重要!)
chmod 700 /home/sasami/.ssh # .sshディレクトリ:所有者のみ読み書き実行
chmod 600 /home/sasami/.ssh/authorized_keys # 鍵ファイル:所有者のみ読み書き
パーミッションについて:SSHは鍵ファイルのパーミッションに厳格です。設定が甘いとSSHが鍵を無視して認証に失敗します。上記の値を正確に設定してください。
5. sshd_config の設定強化
SSHの設定ファイルを編集して、セキュリティを高めます。
sudo nano /etc/ssh/sshd_config
以下の項目を変更します。
# ポートを変更します(1024〜65535の任意の番号を選びます)
Port 2222
# rootでの直接ログインを禁止します
PermitRootLogin no
# 公開鍵認証を有効にします
PubkeyAuthentication yes
⚠️ 重大な注意点:sshdを再起動する前に、必ず別のターミナルを開いて、新しいユーザー(sasami)でSSH接続できることを確認してください!
確認せずに再起動してしまうと、鍵の設定ミスなどで自分がサーバーに入れなくなる可能性があります。
接続確認ができたら、sshdを再起動します。
sudo systemctl restart ssh
6. ufw(ファイアウォール)設定
Ubuntu組み込みのファイアウォール ufw を設定します。
⚠️ 順番が非常に重要です! 必ず「ルール追加 → 有効化」の順番で行ってください。有効化を先にしてしまうと、SSH接続が遮断されてサーバーにアクセスできなくなります。
# ①先にSSHの新しいポートを許可します(順番を守ってください)
sudo ufw allow 2222/tcp
# ②ufwを有効化します(自動起動も同時に設定されます)
sudo ufw enable
# 設定内容を確認します
sudo ufw status verbose
7. コントロールパネルのSSHポートも更新
手順5でSSHポートを22→2222に変更したので、コントロールパネルのパケットフィルターも更新します。
| プロトコル | ポート | 送信元IP |
|---|---|---|
| TCP | 2222 | 0.0.0.0/0 |
古い22番ポートのルールは削除してOKです。
8. DNS設定
XserverのDNS管理パネルで、ドメインをVPSのIPアドレスに向けます。
ネームサーバーに ns1.xdomain.ne.jp を使用している場合、Xserverのコントロールパネルから以下のAレコードを追加します。
| ホスト名 | 種別 | 内容 | TTL |
|---|---|---|---|
| sa-3.me | A | VPSのIPアドレス | 3600 |
| www.sa-3.me | A | VPSのIPアドレス | 3600 |
設定後、DNSの反映には数分〜数時間かかります。以下のコマンドで反映を確認しましょう。
# IPアドレスが正しく返ってくれば反映完了です
nslookup sa-3.me
9. PostgreSQLのインストール
Phoenixアプリのデータベースとして PostgreSQL をインストールします。
# PostgreSQLと追加モジュールをインストールします
sudo apt install -y postgresql postgresql-contrib
# 自動起動を設定して即時起動します
sudo systemctl enable --now postgresql
# 動作確認をします
sudo systemctl status postgresql
DBユーザーの作成
# postgresユーザーとしてpsqlを起動します
sudo -u postgres psql
psqlのプロンプト(postgres=#)が表示されたら、以下を実行します。
-- アプリ用ユーザーを作成します
CREATE USER sasami WITH PASSWORD 'パスワード';
-- DB作成権限を付与します
ALTER USER sasami CREATEDB;
-- psqlを終了します
\q
パスワードについて:本番環境のDBパスワードは十分に複雑なものを設定し、後で環境変数に設定します。メモしておきましょう。
10. Elixir / Erlangのインストール(asdf経由)
Elixirのバージョン管理には asdf というツールを使います。複数のバージョンを簡単に切り替えられる便利なツールです。
まず依存パッケージをインストールします。
# Erlangのコンパイルに必要な依存パッケージをインストールします
sudo apt install -y curl git build-essential libssl-dev libncurses5-dev \
libwxgtk3.2-dev libwxgtk-webview3.2-dev libgl1-mesa-dev libglu1-mesa-dev \
libpng-dev libssh-dev unixodbc-dev xsltproc fop
続いてasdfをインストールします。
# asdfをホームディレクトリにcloneします
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.1
# シェルの設定ファイルにasdfを読み込む設定を追加します
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
# 現在のシェルに設定を反映します
source ~/.bashrc
ErlangとElixirをインストールします。
# Erlangプラグインを追加します
asdf plugin add erlang
# Elixirプラグインを追加します
asdf plugin add elixir
# Erlangをインストールします(ソースからコンパイルするため10〜20分かかります)
asdf install erlang 27.3.4
asdf global erlang 27.3.4
# Elixirをインストールします
asdf install elixir 1.18.3-otp-27
asdf global elixir 1.18.3-otp-27
# バージョンを確認します
elixir --version
⏳ 注意:Erlangのインストールはソースコードからのコンパイルのため、10〜20分程度かかります。処理が止まって見えることがありますが、正常な動作です。気長にお待ちください。
11. Nginxのインストール
WebサーバーとしてNginxをインストールします。後でPhoenixアプリへのリバースプロキシとして使用します。
# パッケージリストを更新します
sudo apt update
# Nginxをインストールします
sudo apt install nginx -y
# 自動起動を設定して即時起動します
sudo systemctl enable --now nginx
# 動作確認をします
sudo systemctl status nginx
12. ufw・パネルにHTTP/HTTPSを追加
WebサーバーへのアクセスのためにHTTP(80番)とHTTPS(443番)のポートを開放します。
ufw側:
# HTTP(80番)を許可します
sudo ufw allow 80/tcp
# HTTPS(443番)を許可します
sudo ufw allow 443/tcp
# 設定を反映します
sudo ufw reload
コントロールパネル側にも同様に追加します:
| プロトコル | ポート | 送信元IP |
|---|---|---|
| TCP | 80 | 0.0.0.0/0 |
| TCP | 443 | 0.0.0.0/0 |
13. GitHubのSSH鍵設定
サーバーからGitHubにアクセスしてリポジトリをcloneするために、SSH鍵を設定します。
# Ed25519形式のSSH鍵ペアを生成します
ssh-keygen -t ed25519 -C "GitHubのメールアドレス"
# 公開鍵を表示します(この内容をGitHubに登録します)
cat ~/.ssh/id_ed25519.pub
表示された公開鍵を GitHub → Settings → SSH and GPG keys → New SSH key に登録します。
# GitHubへの接続を確認します
# "Hi ユーザー名! You've successfully authenticated..." と表示されればOKです
ssh -T git@github.com
14. git設定 & リポジトリのclone
# gitのユーザー名を設定します
git config --global user.name "GitHubのユーザー名"
# gitのメールアドレスを設定します
git config --global user.email "GitHubのメールアドレス"
# SSH URLでcloneします(HTTPSよりSSH URLを推奨します)
git clone git@github.com:ユーザー名/リポジトリ名.git
15. 環境変数の設定
Phoenixアプリで使う秘密情報を環境変数として設定します。
まずローカル環境で秘密鍵を生成します。
# ローカルのPhoenixプロジェクトで実行してください
mix phx.gen.secret
サーバーの ~/.bashrc に環境変数を追記します。
# データベース接続URLを設定します
echo 'export DATABASE_URL="ecto://sasami:パスワード@localhost/sa3me_prod"' >> ~/.bashrc
# アプリの秘密鍵を設定します(mix phx.gen.secretで生成した値を使います)
echo 'export SECRET_KEY_BASE="生成した値"' >> ~/.bashrc
# 公開するホスト名を設定します
echo 'export PHX_HOST="sa-3.me"' >> ~/.bashrc
# 現在のシェルに設定を反映します
source ~/.bashrc
# 設定を確認します
echo $DATABASE_URL
echo $SECRET_KEY_BASE
セキュリティについて:
SECRET_KEY_BASEはPhoenixのセッション暗号化などに使われる重要な値です。絶対に他人に見せたり、GitHubにpushしたりしないようにしましょう。
16. Phoenixアプリのビルド&デプロイ
# cloneしたディレクトリに移動します
cd リポジトリ名
# 1. 本番用の依存関係をインストールします
mix deps.get --only prod
# 2. ソースコードをコンパイルします
MIX_ENV=prod mix compile
# 3. アセット(CSS・JSなど)をビルドします
MIX_ENV=prod mix assets.deploy
# 4. DBを作成してマイグレーションを実行します
MIX_ENV=prod mix ecto.create
MIX_ENV=prod mix ecto.migrate
# 5. 動作確認をします(http://サーバーのIP:4000 でアクセスできるか確認します)
MIX_ENV=prod mix phx.server
# 6. 動作確認できたらCtrl+Cで止めて、本番用バイナリをビルドします
MIX_ENV=prod mix release
releaseビルドについて:
mix releaseでビルドすると、Elixirがインストールされていない環境でも動く自己完結型バイナリが生成されます。systemdから起動する際はこのバイナリを使います。
17. systemdで常駐化
アプリをサーバー常駐プロセスとして登録します。これでサーバー再起動後も自動でアプリが立ち上がります。
sudo nano /etc/systemd/system/sa3me.service
以下の内容を貼り付けます。
[Unit]
# サービスの説明
Description=sa3me Phoenix App
# このサービスが依存するサービス(ネットワークとPostgreSQLが起動した後に開始します)
After=network.target postgresql.service
[Service]
# プロセスの起動方法
Type=exec
# 実行ユーザー(rootではなく一般ユーザーで実行します)
User=sasami
# 作業ディレクトリ
WorkingDirectory=/home/sasami/リポジトリ名
# 起動コマンド
ExecStart=/home/sasami/リポジトリ名/_build/prod/rel/sa3me/bin/sa3me start
# 停止コマンド
ExecStop=/home/sasami/リポジトリ名/_build/prod/rel/sa3me/bin/sa3me stop
# 異常終了時に自動再起動します
Restart=on-failure
# 環境変数を設定します
Environment=DATABASE_URL=ecto://sasami:パスワード@localhost/sa3me_prod
Environment=SECRET_KEY_BASE=生成した値
Environment=PHX_HOST=sa-3.me
Environment=MIX_ENV=prod
[Install]
WantedBy=multi-user.target
# systemdにサービスファイルの変更を通知します
sudo systemctl daemon-reload
# サービスを有効化して即時起動します
sudo systemctl enable --now sa3me
# 状態を確認します
sudo systemctl status sa3me
18. Nginxリバースプロキシ設定
PhoenixアプリはポートB4000で動いています。外部からのHTTPアクセス(80番ポート)をPhoenixに転送するリバースプロキシを設定します。
sudo nano /etc/nginx/sites-available/sa-3.me
以下を貼り付けます。
server {
listen 80;
server_name sa-3.me www.sa-3.me;
location / {
# Phoenixアプリ(ポート4000)にリバースプロキシします
proxy_pass http://localhost:4000;
proxy_http_version 1.1;
# WebSocket対応(Phoenix LiveView用に必須です)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# クライアントの実IPをPhoenixに伝えます
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;
}
}
# シンボリックリンクを作成してサイトを有効化します
sudo ln -s /etc/nginx/sites-available/sa-3.me /etc/nginx/sites-enabled/
# 設定ファイルの構文チェックを行います
sudo nginx -t
# → "syntax is ok" と "test is successful" が出ればOKです
# 問題なければNginxをリロードします
sudo systemctl reload nginx
WebSocketについて:Phoenix LiveViewはWebSocketを使ってリアルタイム通信を行います。
UpgradeとConnectionヘッダーの設定がないとLiveViewが動作しないので、忘れずに設定しましょう。
19. HTTPS化(Let’s Encrypt)
最後にHTTPS化です。DNS反映が確認できてから実行してください。
# certbotとNginxプラグインをインストールします
sudo apt install certbot python3-certbot-nginx -y
# 証明書を取得してNginxの設定を自動更新します
sudo certbot --nginx -d sa-3.me -d www.sa-3.me
対話的にメールアドレスや利用規約への同意を求められます。完了すると、NginxのHTTPS設定が自動で書き換えられます。
トラブルシューティング
| 症状 | 原因 | 対処 |
|---|---|---|
| pingが通らない | パネルのパケットフィルター未設定 | コントロールパネルでポート開放 |
| SSHが繋がらない(再起動後) | ssh.serviceがdisabled |
systemctl enable --now ssh を実行 |
| ufwで締め出された | enable前にルール追加し忘れ |
ブラウザコンソールから ufw disable |
| “Protocol major versions differ” と表示される | ログの残骸(無害) | 無視してOK |
まとめ
手順が多く感じるかもしれませんが、一度やってしまえば次からはずっとスムーズになります。特に以下の3点は多くの方がハマりやすいポイントです。
- コントロールパネルのパケットフィルターはOSのufwとは別に設定が必要です
- ufwはルール追加してから有効化(順番を逆にすると締め出されます)
- sshd再起動前に新ユーザーでの接続確認を必ず行いましょう
次の記事では、このサーバーに OpenSMTPDでメールサーバーを構築する手順を解説します。