vourja's blog

これはみすてむず いず みすきーしすてむず Advent Calendar 2023 18日目の記事です。

前日はたろさんのOSS選定時に個人的に考えていることでした。OSS選定難しいですよね。ほかの人から「選んだ根拠は?」って言われてもちゃんと答えれるようにするのは大事ですね。「今後問題が起こらないことを保証できるか?」って言われたら「うるせー!」って答えましょう。

はじめに

今回のテーマは、雑にミニPCでブログサイトを作ってみよう、です。

みんな、ミニPC買ってますか?買ってますね? なにをやるにもお金がかかる時代ですが、ミニPCを使えばクラウドの費用は一切かかりません(※1)。

※1注 ミニPC自体の費用がかかります。ドメイン費用と電気代と通信費が別途かかります。運用者自身に負担がかかります。 え、ブログぐらいなら無料で公開するサービスたくさんあるって?ちょっと黙ってて。

みすてむずでは自宅でお高いネットワーク機器を使ってサービス運用している強者がたくさんいるので、そういう人にはこの記事は退屈でしょう。
そういう方向けにうさぎの写真集を用意しておきましたのでぜひご覧ください。

設計と実装

雑にミニPCでブログサイトを作ってみる、でやることやらないこと

  • セキュリティ上の観点から、自宅のネットワーク環境のポートを開放しない。
  • コンテナについては今回は扱わない。
  • GithubActionsなどCI/CDサービスは利用しない。
  • なるべく自前のもの、みすてむず由来のものを利用する。

構成図

上記を考慮の上で、下記の仕組みにしました。

  • ブログサーバー: GMKTecの超絶かわいいミニPC NucBox 5
  • ルーター: Netgear Orb Wifi (MACアドレスでIP固定化できればなんでもいいです)
  • メインPC: denoとAnsibleが実行できるマシンならなんでも

なぜCloudFlareなん?

CloudFlareは自宅サーバーを簡単に安全に公開できる仕組みがあって、ついでにキャッシュやDDOS対策までやってくれて、もうめっちゃたくさん利点を享受できます。

なぜこれが無料で使えるのかわかりません。

ブログサーバーの立ち上げ

サーバーのホストマシンに直接ブログをアップロードすると、バックアップや複数のブログ運用とか思いついた時に手間です。 Proxmox VEを使ってブログサーバーを起動できるようにしましょう。

Proxmox VEをサーバーにインストールしましょう

公式サイトの先でイメージをダウンロードし、お家に転がっているUSBメモリに書き込んでミニPCにぶっさして電源を入れます。

こちらのサイトが詳しかったので、ぜひ見てください。
https://dareblo.com/proxmoxve-install/

Cloud-initで仮想マシンの作成を楽にしましょう

Cloud-Initを使うことで、仮想マシンを簡単にポコポコ増やすことができます。便利ですね。 僕はUbuntu以外のLinuxを知らないので、Ubuntuのイメージをベースにしましょう。

Proxmox VEをインストールしたホストにSSHでログインしたあと下記のコマンドでCloud-Initのイメージを作成します。

wget https://cloud-images.ubuntu.com/jammy/20231212/jammy-server-cloudimg-amd64.img
qm create 9000 --memory 2048 --net0 virtio,bridge=vmbr0
qm importdisk 9000 jammy-server-cloudimg-amd64.img local-lvm
qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9000-disk-0
qm set 9000 --ide2 local-lvm:cloudinit
qm set 9000 --boot c --bootdisk scsi0
qm set 9000 --serial0 socket --vga serial0
qm template 9000

Cloud-InitからVMを作成しましょう

Cloud-InitのVMを作ると、Proxmoxの画面上にVMのイメージが出てきますので、ここからクローンしてやります。

たかがブログなのでメモリは1GBもあれば十分でしょう。ストレージは20GBぐらいで足りるかと思います。 IP Configでは自宅のLANで利用できるIPアドレスを指定しておきます。DNSサーバーも"1.1.1.1"とかが良いと思います。

ルーターの設定

IPアドレスを固定化しましょう

ProxmoxのホストとVMのIPアドレスはご自宅のLAN内で固定化しておいたほうが運用が楽です。 我が家ではNetgearのルータの設定で固定化させることができました。

(これは設定例です)

これでいつでもサーバーに入ってアプリを乗せれるようになりました。

CloudFlare契約

CloudFlareの契約の仕方はいろんなところに記事があるので、特にここでは書きません。無料プランで作っていきます。

ついでにCloudFlareでドメインを取得しましょう。私のドメインはinunekousapon.ukです。 ドメインは有料になっています。ukのドメインは安かったから選びました(年に4ドルぐらいでした)。

ドメインにはWHOISという登録者の情報を照会できるサービスがあります。ドメインを取得したら個人情報がばれてしまうんじゃ…、と思うかもしれませんがWhois情報公開代行に相当する仕組みが標準であるため、個人情報は漏れません。安心してください。

Webサイトを追加しましょう

取得したドメインでサイトを追加しましょう。

最初は現在Webサイトはありません、と表示されるのでサイトを追加ボタンをクリックしましょう。 先ほど取得したドメインを入力したらプランを聞かれるので「Free」を選択します。 あとはデフォルトの設定を確認していけばOKです。

CloudFlare Tunnelを使いましょう

CloudFlare Tunnelは自宅サーバー公開の要となるサービスで、自宅のネットワークを外部に晒さずにサービスを運用できる機能です。この機能なしでは自宅サーバーの運用を行おうとは思いませんでした。wolfさんもちょうどその記事を書いていますね!

使うにはCloudFlareのログイン後トップページの Zero Trust > Access > Tunnels からです。

Create a tunnelというボタンがありますので押します。トンネル名を聞かれるのでブログっぽい名前を設定しましょう。

環境を選べって言われます。Ubuntuに入れるのでここはDebian > 64bitを選びましょう。 下に出てくるコマンドは後で使いますので、左のほうのコマンドを控えておいてください。

次に公開ドメイン名と、ローカルでつなげるための設定を書きます。 このブログの設定例です。 Serviceの'HTTP://localhost:8000'の設定は、Ubuntuでブログにアクセスするためのものです。

以上で、CloudFlare Tunnelの設定はおしまいです。

ブログコンテンツの制作

ブログを作っていきましょう。

オススメはみすてむずのTypeScriptの魔術師いかそば先生dejamuです。ちなみにこのブログもdejamuで作られています。

作っていきましょう

作り方は簡単。まずはdenoをインストールしましょう。
https://docs.deno.com/runtime/manual/getting_started/installation

プロジェクトを下記のように新規作成します。

deno run -rA https://raw.githubusercontent.com/ikasoba/dejamu/main/scripts/init.ts

あとは実行するだけ!

deno task serve

あとは自分の好きなようにカスタマイズしてブログを書いていきましょう!

デプロイ環境の作成

ブログをデプロイしてみましょう。僕はPythonが好きなのでAnsibleでデプロイします。

Ansibleの実行環境を準備しましょう

pythonの仮想環境の話だけで本が書けちゃうぐらいの内容があるので、好きな仮想環境使ってください。

僕はpyenvを利用することが多いです。minicondaも稀に使います。 pyenvのインストールはこちら

インストール後は下記のように適当なバージョンのPythonをインストールし、そこから仮想環境をつくってactivateして使います。

pyenv install 3.10.4
pyenv global 3.10.4

dejamuをインストールしたディレクトリに'ansible'というディレクトリを作成します。 僕はその中で仮想環境を作ることが多いです。

python -m venv venv
. venv/bin/activate
pip install ansible

Ansibleのリソースを書いていきましょう

最終的にはこのようなディレクトリ構成になります。

ansible
├── dejamu.yml
├── host.yml
├── venv
└── templates
    └── nginx.conf.j2

まずはhost.ymlを仕上げます。

group_name:
  vars:
    ansible_user: vourja
    ansible_cert: /home/vourja/.ssh/id_rsa
    cloudflare_token: << Cloudflare tunnel作ったときのトークン >>
  hosts:
    dejamu:
      ansible_host: 10.0.0.153
      document_root: /var/www
      app_root: blog
      server_name: "{{ ansible_default_ipv4.address }} blog.inunekousapon.uk"

ansible_user, ansible_certはproxmoxでVM作った時のVMに入ることのできるユーザーと秘密鍵です。
cloudflare_tokenは、tunnel作った時に生成されたトークンを書きます。
ansible_hostはデプロイするサーバーのIPアドレス。
server_nameは自分のブログサイトを書いておいてください。(書かなくても動きます)

次にnginx.conf.j2です。

server {
  listen 8000;

  server_name {{ server_name }};
  root {{ document_root }}/{{ app_root }};
  index index.html index.htm;
  
  location / {
    default_type "text/html";
    try_files $uri.html $uri $uri/ =404;
  }
}

最低限の記述ですが、これはこのままにします。

最後はdejamu.ymlです。(ファイル名は自由に変えてもらって構いません)

- name: Dejamu Deploy Playbook
  hosts: all
  become: yes
  tasks:
    - name: Execute apt autoremove
      command: apt autoremove -y

    - name: Update apt cache
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: install nginx
      apt:
        name: nginx
        state: latest

    - name: install cloudflared
      shell:
        cmd: |
          curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
          sudo dpkg -i cloudflared.deb
      tags: cloudflared

    - name: setup cloudflare tunnel
      shell:
        cmd: |
          sudo cloudflared service install {{ cloudflare_token }}
      tags: cloudflared

    - name: copy dejamu outputs
      ansible.builtin.copy:
        src: ../.out/
        dest: /var/www/blog
        mode: preserve

    - name: apply nginx template
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: restart nginx

    - name: enable new site
      file:
        src: /etc/nginx/sites-available/default
        dest: /etc/nginx/sites-enabled/default
        state: link
      notify: restart nginx

  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted

デプロイをしちゃいましょう

下記のコマンドで一発でデプロイしちゃいます。

ansible-playbook -i host.yml dejamu.yml

2回目以降はcloudflaredのインストールで失敗するため下記のコマンドでデプロイするとよいです。

ansible-playbook -i host.yml dejamu.yml --skip-tags cloudflare

これでブログを公開することができました! めでたしめでたし!

え、なんでわかるって?このブログがそうやってデプロイされているからです。

まとめ

ちょっと長くなりましたが、意外と簡単に自宅サーバーのコンテンツが公開できることが分かったかと思います。別にブログじゃなくても個人サービスなどを運用するにも、ミニPCじゃなくてVPSであってもこの内容は役に立つと思います。

なんか分からないよ~、とか、これってどうなん?って質問あればぜひみすてむずに来て質問してみてください。

明日はまめぴさんの記事です!正座して待っていましょう。