余ってたN100ミニPCでサイトを自宅公開した
余っていたN100のミニPCをサーバーにして、このサイトを自宅から公開しました。ルーターのポートは1つも開けていません。やったことを順番にまとめておきます。
構成
ブラウザ
→ Cloudflare(TLS / DNS)
→ Cloudflare Tunnel(サーバー側から外向きに接続)
→ N100 ミニPC(Rocky Linux)
→ Podman(rootless)
→ nginx:alpine(127.0.0.1:8080)
- マシン: Intel N100 / メモリ12GB / SSD 256GB
- OS: Rocky Linux(SELinux は有効のまま)
- Web: nginx:alpine を podman-compose で起動
- 公開: cloudflared を systemd サービスとして常駐
使ったマシン

ACEMAGIC の N100 ミニPC です。2万円くらいでした。最近は N100 のミニPCも値上がりしていて、今だと同じ値段では買えなさそうです。
N100 は省電力の CPU(TDP 6W)で、ミニPC全体でもアイドル時は 10W 前後と言われています。仮に 10W で24時間つけっぱなしにしても、1か月で約 7kWh、電気代は 200円ちょっとです(1kWh = 31円で計算)。静かで場所も取らないので、自宅サーバーに向いています。
ただ、このメーカーは過去に、出荷時の Windows にマルウェアが入っていたことがあります。手元の個体も、Windows がボリュームライセンスで認証されていて少し気になりました。どのみち Windows は消して Linux を入れるので、問題ないと判断しました。
OS選び
Windows ではなく Linux にした理由
- サーバーとして動かすだけなので、余計な機能はいらない。Linux は軽く、そのぶんメモリや CPU をサイトに回せる
- 勝手に再起動する更新や、おすすめ・広告のような機能がない。最近の Windows は機能を増やしすぎていて、使っていて不快だった
- nginx、Podman、SSH など、サーバーで使うものが揃っていて無料
Rocky Linux にした理由
- 今まで Debian 系しか触ってこなかったので、Red Hat 系も触ってみたかった
- RHEL 互換で、サポート期間が長く堅牢。SELinux も最初から有効になっている
手順
1. Rocky Linux を入れる
公式サイトから ISO をダウンロードして USB メモリに書き込み、ミニPCにインストールします。終わったら更新して、SSH を有効にします。
sudo dnf update -y
sudo reboot
sudo systemctl enable --now sshd
ip a # サーバーの IP アドレスを確認
ここから先は、メインのPCから ssh ユーザー名@IPアドレス で入って作業しました。
2. ドメインを取る
masu.uk は Cloudflare Registrar で取りました。Cloudflare は原価で売っているので、取得も更新も年5ドルくらいです。DNS もそのまま Cloudflare で管理できるので、あとで Cloudflare Tunnel を使うときに楽です。
3. nginx をコンテナで動かす
Podman と podman-compose を入れます。
sudo dnf install -y podman python3-pip
pip install --user podman-compose
mkdir ~/nginx && cd ~/nginx
~/nginx/docker-compose.yml を作ります。
services:
web:
image: docker.io/library/nginx:alpine
container_name: nginx-masu
ports:
- "127.0.0.1:8080:80"
volumes:
- /home/usr01/blog/public:/usr/share/nginx/html:ro,Z
- ./default.conf:/etc/nginx/conf.d/default.conf:ro,Z
restart: always
127.0.0.1:8080にだけ公開して、LAN にも外にも出さない。外との通信はトンネルだけにする- Hugo のビルド結果(
public/)をそのままマウントする。ビルドすれば、コンテナを触らずにサイトが更新される - ボリュームに
:Zを付ける。SELinux が有効だと、これがないとコンテナからファイルが読めない
nginx の設定 ~/nginx/default.conf では、キャッシュの扱いだけ変えています。
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
error_page 404 /404.html;
# HTML・RSS など: 毎回サーバーに更新を確認させる
location / {
try_files $uri $uri/ =404;
add_header Cache-Control "no-cache";
}
# CSS: ファイル名にハッシュが入るので長期キャッシュでOK
location /css/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
}
起動して、200 OK が返ってくれば成功です。
~/.local/bin/podman-compose up -d
curl -I http://127.0.0.1:8080
4. Cloudflare Tunnel でつなぐ
cloudflared を入れて、サービスとして登録します。
curl -fsSL https://pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo
sudo dnf install -y cloudflared
sudo cloudflared service install <トークン>
トークンは、Cloudflare の Zero Trust の画面でトンネルを作ると表示されます。画面に出るコマンドをそのまま貼ればOKです。トークンを知られるとトンネルを乗っ取られるので、人に見せないようにします。
最後に、トンネルの公開ホスト名で masu.uk を http://localhost:8080 に向ければ、外から見られるようになります。
5. ログアウトしても止まらないようにする
公開できたと思ったら、しばらくして 502 Bad Gateway になりました。
$ podman ps -a
STATUS
Exited (0) 11 minutes ago
rootless の Podman だと、SSH からログアウトしたタイミングでユーザーのプロセスごとコンテナが止まります。次の2つで解決しました。
sudo loginctl enable-linger $USER
systemctl --user enable --now podman-restart.service
enable-linger でログアウト後もユーザーのサービスが動き続けるようになり、podman-restart.service で再起動後に restart: always のコンテナが立ち上がります。sudo reboot して、何もしなくてもサイトが戻ることを確認しました。
6. ブログを書いて公開する
ブログは Hugo で作っています。テーマは使わず、テンプレートと CSS は自分で書きました。
pip install --user hugo
記事は Markdown で書いて、./deploy.sh を実行すると公開されます。中でやっていることは次の2つです。
hugo --minify --cleanDestinationDir # public/ にサイトを書き出す
chcon -R -t container_file_t public # nginx コンテナから読めるように SELinux のラベルを付ける
nginx は public/ をそのまま配信しているので、ビルドすればすぐ反映されます。データベースもない、ただの HTML ファイルなので、N100 でも余裕です。