UmamiをVPSにセルフホストする手順|Docker Compose・HTTPS化・バックアップまで【2026年版】
2026-09-24
※内容は2026年9月24日時点の情報(Umami v3.4.0)をもとにしています。
「Umamiを自分のVPSで動かしたいけれど、ネットで見つかる手順が古くて、そのとおりにやっても動かない」。そんな経験はありませんか。
この記事では、Google Analyticsの代わりになるオープンソースのアクセス解析ツールUmamiを、VPSにセルフホストする手順を、最初から最後まで解説します。当サイトOSSMatchを含む自社の5つのWebサービスは、実際にVPS上のUmamiで計測しています。その運用をもとに、構築・HTTPS化・計測タグの設置・バックアップ・アップデートまで、つまずきやすい点を先回りして避ける順番でまとめました。
Umamiを選んだ理由や、Umami Cloudとの違い、VPSの選び方は、前の記事にまとめています。
Google Analyticsの代わりにUmamiを選んだ理由|5サイトを1画面で見る運用とVPSの選び方
Umamiのセルフホストで失敗しやすい理由
Umamiは構成がシンプルで、手順どおりに進めれば短時間で動きます。それでも失敗する人が多いのは、次のような理由です。
- 古い手順がそのまま残っている:Umami v3からデータベースはPostgreSQLのみの対応になり、MySQLは使えなくなりました。v2時代の「MySQLで構築する」記事どおりに進めると起動しません
- 作業の順番を間違える:設定ファイルを作る前にDockerを起動すると、ファイルの代わりに同じ名前のフォルダが作られ、HTTPS用のWebサーバーが動かなくなります
- ファイアウォールを過信する:Dockerで公開したポートは、ufwなどのファイアウォールの設定を素通りします。閉じたつもりのポートが外から見える状態になりがちです
- バックアップが取れていない:コマンドの失敗に気づかず、中身が空のバックアップを取り続けているケースがあります
この記事の手順は、これらを最初から避ける形にしています。
この記事で作る構成と必要なもの
VPSの上に、Dockerで次の3つを動かします。
- Umami:アクセス解析の本体
- PostgreSQL:計測データを保存するデータベース
- Caddy:HTTPS化を自動でしてくれるWebサーバー。外からのアクセスはここだけで受ける

用意するものは次のとおりです。
| 必要なもの | 目安 |
|---|---|
| VPS | メモリ1GB以上(512MBでも動くが、スワップが必須) |
| OS | Ubuntu 24.04 LTS |
| ドメイン | 計測用のサブドメイン(例:analytics.example.com) |
| 作業環境 | SSHでVPSに接続できるパソコン |
メモリの目安は、私たちの実測(5サイト計測で、Umami本体が約350MB、データベースが約48MB)をもとにしています。
手順1:DNSとVPSの初期設定
DNSにAレコードを追加する
ドメインの管理画面で、計測用のサブドメイン(例:analytics.example.com)のAレコードに、VPSのIPアドレスを設定します。反映を確認してから次に進むのがポイントです。反映前にHTTPS化を始めると証明書の取得に失敗し、失敗を繰り返すとLet’s Encryptの制限で、しばらく証明書が取れなくなります。
自分のパソコンで次を実行し、VPSのIPアドレスが返ってくれば反映済みです。
dig +short analytics.example.com
IPv6(AAAAレコード)も設定している場合は、VPSがIPv6で届く設定になっているか確認してください。届かないなら、AAAAレコードは設定しないほうが安全です。
パッケージを更新し、ファイアウォールを設定する
VPSにSSHでログインし、まずパッケージを最新にします。
sudo apt update && sudo apt upgrade -y
次にファイアウォールを設定します。開けるのはSSH(22番)、HTTP(80番)、HTTPS(443番)だけです。必ずSSHを許可してから有効にしてください。順番を逆にすると、自分がログインできなくなります。
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
sudo ufw enable
sudo ufw status
有効にしたら、今の接続は切らずに、別のターミナルからSSHでログインできることを確認します。VPSの管理画面にもフィルター機能(ConoHaの「セキュリティグループ」、Xserver・シンVPSの「パケットフィルター」など)がある場合は、同じ方針で設定しておきます。
512MBプランの場合はスワップを追加する
メモリ512MBのプランでは、Umamiの起動時にメモリが足りなくなることがあります。1GBのスワップを追加しておきます(1GB以上のプランなら不要です)。
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -h
手順2:Dockerをインストールする
Docker公式の手順(aptリポジトリを使う方法)でインストールします。古いDocker(docker.ioなど)が入っている場合は、先に公式手順の「古いバージョンの削除」を行ってください。
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world
最後のhello-worldでメッセージが表示されれば成功です。
ここで大事な注意点が1つあります。Dockerで公開(publish)したポートは、ufwで閉じていても外からアクセスできてしまいます。この記事の構成では、Caddyの80番・443番以外は公開しません。
手順3:設定ファイルを3つ作ってから起動する
Umamiの構築で一番大事なのが、設定ファイルを3つとも作ってから起動することです。作るのは次の3つです。
- .env:パスワードなどの秘密の値
- docker-compose.yml:Umami・PostgreSQL・Caddyの構成
- Caddyfile:HTTPS化とUmamiへの転送の設定
パスワードなどを.envに作る
作業用のフォルダを作り、パスワードなどをランダムな値で生成して保存します。公式の初期値(umamiなど)のまま使うのは危険なので、必ず自分用の値にします。
mkdir -p ~/umami && cd ~/umami
cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 16)
APP_SECRET=$(openssl rand -hex 32)
TWO_FACTOR_ENCRYPTION_KEY=$(openssl rand -hex 32)
EOF
chmod 600 .env
値は英数字だけで生成しているので、データベースの接続設定に入れても記号の問題が起きません。この.envファイルは、あとでバックアップと一緒に大切に保管します。
docker-compose.ymlを作る
nano docker-compose.ymlでファイルを開き、次の内容を貼り付けて保存します。Umami公式のdocker-compose.ymlをもとに、次の3点を変えています。
- パスワードなどを.envから読み込む
- Umamiの3000番ポートを外に公開しない(Caddy経由でだけアクセスする)
- HTTPS化のためのCaddyを追加する
services:
umami:
image: ghcr.io/umami-software/umami:latest
environment:
DATABASE_URL: postgresql://umami:${POSTGRES_PASSWORD}@db:5432/umami
APP_SECRET: ${APP_SECRET}
TWO_FACTOR_ENCRYPTION_KEY: ${TWO_FACTOR_ENCRYPTION_KEY}
depends_on:
db:
condition: service_healthy
init: true
restart: always
healthcheck:
test: ["CMD-SHELL", "curl http://localhost:3000/api/heartbeat"]
interval: 5s
timeout: 5s
retries: 5
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- umami-db-data:/var/lib/postgresql/data
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
caddy:
image: caddy:2
restart: always
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
depends_on:
- umami
volumes:
umami-db-data:
caddy_data:
caddy_config:
バージョンを固定したい場合は、ghcr.io/umami-software/umami:latestをghcr.io/umami-software/umami:3.4.0のように書き換えます(先頭に「v」は付けません)。
Caddyfileを作る
nano Caddyfileでファイルを開き、次の3行を保存します。analytics.example.comは自分のサブドメインに置き換えてください。
analytics.example.com {
reverse_proxy umami:3000
}
Caddyは、DNSがVPSを向いていて80番・443番に届けば、証明書の取得と更新を自動で行ってくれます。
起動して確認する
3つのファイルがそろっていることを確認してから起動します。
ls -l .env docker-compose.yml Caddyfile
sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs -f umami
ls -lの結果で、3つとも「ファイル」として表示されていればOKです。ログにエラーが出ていなければ、ブラウザでhttps://analytics.example.comを開けます。
念のため、自分のパソコンから、Umami(3000番)とデータベース(5432番)に外から接続できないことも確認しておきます。どちらも接続に失敗すれば正しい状態です。
nc -vz VPSのIPアドレス 3000
nc -vz VPSのIPアドレス 5432
もし先に起動してしまい、Caddyfileがフォルダになっていた場合は、次の手順で作り直せます。
sudo docker compose down
rm -r Caddyfile
nano Caddyfile
sudo docker compose up -d
手順4:初期設定と計測タグの設置
管理画面にログインしてパスワードを変える
ブラウザでUmamiを開き、初期アカウント(ユーザー名:admin、パスワード:umami)でログインします。ログインしたら、すぐにパスワードを変更してください。Settings(設定)のProfileから変更できます。Securityでは2段階認証も設定できます。
サイトを登録してタグを貼る
Settings(設定)のWebsitesからサイトを追加し、Tracking codeに表示されるタグを、計測したいサイトの<head>内に貼り付けます。
<script defer src="https://analytics.example.com/script.js" data-website-id="発行されたID" data-domains="example.com,www.example.com"></script>
- data-domains:指定したドメインでだけ計測します。テスト環境の計測を防げます。wwwの有無は別のドメインとして扱われるので、両方書いておきます
- WordPressの場合:ヘッダーにタグを入れられるプラグインか、子テーマの
wp_headで出力すると、テーマを更新しても消えません
自分のアクセスを除外する
自分の閲覧を計測から外すには、計測しているサイトをブラウザで開き、開発者ツールのコンソールで次を実行します。サイトごと・ブラウザごとに必要です。
localStorage.setItem('umami.disabled', 1)
解除するときはlocalStorage.removeItem('umami.disabled')を実行します。

手順5:バックアップを自動化する
計測データはデータベースに入っています。毎日自動でバックアップしておきましょう。ポイントは、コマンドが途中で失敗したら、失敗として止まるようにすることです。単純に「pg_dumpの結果をgzipで圧縮」するだけだと、pg_dumpが失敗しても中身が空のファイルができてしまうことがあります。
nano ~/umami/backup.shで次のスクリプトを作ります。
#!/bin/bash
# Umami のデータベースを毎日バックアップし、14日分残す
set -euo pipefail
cd "$(dirname "$0")"
DIR="$HOME/backup"
mkdir -p "$DIR" && chmod 700 "$DIR"
FILE="$DIR/umami-$(date +%F).sql.gz"
docker compose exec -T db pg_dump -U umami umami | gzip > "$FILE.tmp"
gzip -t "$FILE.tmp"
mv "$FILE.tmp" "$FILE"
chmod 600 "$FILE"
find "$DIR" -name 'umami-*.sql.gz' -mtime +14 -delete
実行できるようにして、手動で1回動かし、バックアップファイルができることを確認します。
chmod 700 ~/umami/backup.sh
sudo ~/umami/backup.sh && sudo ls -lh /root/backup
バックアップはroot権限で実行するため、保存先は/root/backupになります。毎日自動で動かすには、sudo crontab -eで次の1行を追加します(毎日4時15分に実行)。「ユーザー名」は、VPSでwhoamiと入力して表示される名前に置き換えてください。
15 4 * * * /home/ユーザー名/umami/backup.sh >> /root/backup/backup.log 2>&1
バックアップの運用では、次の3つも大切です。
- VPSの外にも保管する:VPSごと壊れたときに備え、各社のバックアップ機能や別の保存先も使う(ConoHaの512MBプランは公式の自動バックアップが使えないので、特に重要です)
- .envも一緒に保管する:データベースのパスワードなどが入っているため、他人が読めない場所に置く
- 一度は試しに復元してみる:ファイルがあるだけでは、本当に戻せるかは分かりません
復元の手順(移行や障害のときだけ)
新しいVPSへ移すときや、データベースが壊れたときの手順です。YYYY-MM-DDは、戻したい日付のバックアップファイル名に置き換えます。今のデータベースを消してから入れ直すので、普段は実行しないでください。
cd ~/umami
sudo docker compose stop umami
sudo docker compose exec -T db psql -U umami -d postgres -c "DROP DATABASE IF EXISTS umami;" -c "CREATE DATABASE umami OWNER umami;"
set -o pipefail
sudo gunzip -c /root/backup/umami-YYYY-MM-DD.sql.gz | sudo docker compose exec -T db psql -X -v ON_ERROR_STOP=1 -U umami -d umami
sudo docker compose exec db psql -U umami -d umami -c "ANALYZE;"
sudo docker compose start umami
復元したら、ログインできること、過去のデータが表示されること、新しいアクセスが計測されることを確認します。別のVPSに移す場合は、.envも元のものを使ってください。
手順6:アップデートの方法
Umamiは活発に開発されていて、アップデートも頻繁です。更新するときは、先にバックアップを取ってから、新しいイメージを取得して起動し直します。
cd ~/umami
sudo ~/umami/backup.sh
sudo docker compose pull
sudo docker compose up -d
sudo docker image prune -f
- 更新中は、数秒から数十秒ほど計測が止まります
- docker compose down -vは使わないでください。-vを付けると、データベースのデータごと消えてしまいます
- 大きなバージョンアップ(v2からv3など)のあとは、公式の推奨どおり、データベースの統計情報を更新しておくと、画面の表示が速くなります
sudo docker compose exec db psql -U umami -d umami -c "ANALYZE;"
更新の前には、リリースノートで変更点を確認しておくと安心です。OSSMatchのUmamiページでは、最新リリースの内容を日本語で確認できます。
私たちの運用構成(参考)
最後に、私たちが実際に使っている構成を紹介します。
- サーバー:XserverのVPS(メモリ6GB)に、ほかのサービスと同居
- 構成:DockerでUmamiとPostgreSQLを動かし、HTTPS化はTraefik(複数のサービスを同じVPSで動かしているため)
- 計測:自社のWebサービス5つを、1つのUmamiでまとめて計測(このサイトOSSMatchも含む)
- 成果の計測:自作のWordPressプラグインで、広告リンクのクリックやツールの利用、フォームの送信などをイベントとして記録
- 通知:毎朝の日報メールと、アクセスの急増や計測の停止を知らせるメールを自動で送信
- バックアップ:毎日データベースを保存し、14日分を保持
Umamiだけを動かすならCaddyのほうが設定が少なく、はじめての方にはおすすめです。複数のサービスを同じVPSで動かすようになったら、Traefikのような仕組みも選択肢になります。構築・運用で大きく困ったことは、今のところ特にありません。

まとめ:UmamiのセルフホストはVPS1台から始められる
Umamiのセルフホストは、手順の順番とセキュリティの注意点さえ押さえれば、メモリ1GBのVPS1台で、複数サイトのアクセス解析をまとめて運用できます。
- DNSの反映を確認してから始める
- 設定ファイルを3つ作ってから起動する
- Caddy以外のポートは外に出さない
- バックアップは自動化し、一度は復元を試す
- アップデートの前にはバックアップを取る
これからVPSを用意する方は、Umamiだけならメモリ1GBのプランで十分です。
| VPS | プラン | 月額(税込) | 条件 |
|---|---|---|---|
| シンVPS | 1GB | 451円 | 長期契約時の月額換算 |
| ConoHa VPS | 512MB | 460円 | キャンペーン表示(2026年10月1日まで)・スワップ必須 |
※料金は2026年9月24日時点の各社公式サイトの表示です。申し込み前に最新の条件をご確認ください。
Umami以外のアクセス解析ツールと比べたい方は、Google Analyticsの代替ツール一覧もご覧ください。