From ca831cec40cfaa2196f62136bfc3dc15335b4648 Mon Sep 17 00:00:00 2001
From: Yasuaki Uechi <y@uechi.io>
Date: Tue, 14 Dec 2021 17:13:26 +0900
Subject: [PATCH] chore: update

---
 package.json                                  |  10 +-
 .../_posts/2016/essentials-for-new-macbook.md |   2 +-
 source/_posts/2021/human-anatomy-atlas.md     |   3 +-
 source/_posts/2021/installing-arch-linux.md   | 218 +++++++++---------
 source/_posts/2021/oauth-jwt-rfcs.md          |   2 +-
 source/_posts/2021/server-2020.md             |  43 ++--
 source/_posts/2021/split-bill.md              |  12 +-
 source/_posts/2021/uco-oil-lantern.md         |  10 +-
 8 files changed, 154 insertions(+), 146 deletions(-)

diff --git a/package.json b/package.json
index 4d4f25e..303b6b8 100644
--- a/package.json
+++ b/package.json
@@ -9,19 +9,19 @@
     "test": "lint-staged"
   },
   "dependencies": {
-    "hexo": "^5.4.0",
-    "hexo-excerpt": "^1.1.6",
+    "hexo": "^6.0.0",
+    "hexo-excerpt": "^1.2.1",
     "hexo-feed": "^1.1.0",
-    "hexo-filter-mathjax": "^0.7.0",
+    "hexo-filter-mathjax": "^0.8.0",
     "hexo-generator-archive": "^1.0.0",
     "hexo-generator-category": "^1.0.0",
     "hexo-generator-index": "^2.0.0",
     "hexo-generator-tag": "^1.0.0",
-    "hexo-renderer-ejs": "^1.0.0",
+    "hexo-renderer-ejs": "^2.0.0",
     "hexo-renderer-pandoc": "^0.3.0",
     "hexo-renderer-sass": "^0.4.0",
     "hexo-renderer-stylus": "^2.0.0",
-    "hexo-server": "^2.0.0",
+    "hexo-server": "^3.0.0",
     "hexo-theme-landscape": "^0.0.3"
   },
   "devDependencies": {
diff --git a/source/_posts/2016/essentials-for-new-macbook.md b/source/_posts/2016/essentials-for-new-macbook.md
index 81c8930..e6add6e 100644
--- a/source/_posts/2016/essentials-for-new-macbook.md
+++ b/source/_posts/2016/essentials-for-new-macbook.md
@@ -132,7 +132,7 @@ Notes.app に移行しました。
 
 ## Flash
 
-ニコニコ動画が見れなくなるので泣く泣く導入していましたが、公式で HTML5 に対応したので不要になりました。
+ニコニコ動画が見られなくなるので泣く泣く導入していましたが、公式で HTML5 に対応したので不要になりました。
 
 ## [VirtualBox](https://www.virtualbox.org)
 
diff --git a/source/_posts/2021/human-anatomy-atlas.md b/source/_posts/2021/human-anatomy-atlas.md
index f7a2cd0..3de61d3 100644
--- a/source/_posts/2021/human-anatomy-atlas.md
+++ b/source/_posts/2021/human-anatomy-atlas.md
@@ -3,8 +3,7 @@ title: 解剖学アトラス
 date: 2021-06-08T00:00:00
 ---
 
-幅優先探索癖の再発です、ありがとう図書館。
-アトラスの用途は美術解剖と消化器系の構造理解。
+いつもの幅優先探索癖。アトラスの用途は美術解剖と消化器系の構造理解。
 
 # ノート
 
diff --git a/source/_posts/2021/installing-arch-linux.md b/source/_posts/2021/installing-arch-linux.md
index ceda428..c980ab6 100644
--- a/source/_posts/2021/installing-arch-linux.md
+++ b/source/_posts/2021/installing-arch-linux.md
@@ -1,22 +1,22 @@
 ---
-title: Installing Arch Linux
+title: Comprehensive Guide for Setting Up Arch Linux
 date: 2021-02-12T00:00:00
 ---
 
-This note includes all commands I typed when I set up Arch Linux on my new bare metal server.
+This note includes all commands I typed when I set up Arch Linux on my new server.
 
-> PSA: I published a GitHub repository containing a toolchain to create a clean-room docker environment for building AUR packages
-> https://github.com/uetchy/archpkgs
+> PSA: I published a toolchain for building AUR packages in a clean-room docker container
+> <https://github.com/uetchy/archpkgs>
 
 # Setup
 
-## wipe whole disk
+## Wipe whole disk
 
 ```bash
 wipefs -a /dev/sda
 ```
 
-## create partition
+## Create partition
 
 ```bash
 parted
@@ -31,7 +31,7 @@ set 1 esp on # flag partition 1 as ESP
 quit
 ```
 
-## install file-system
+## Install file-system
 
 ```bash
 mkfs.vfat -F 32 /dev/sda1 # EFI
@@ -40,7 +40,7 @@ mkfs.ext4 /dev/sda2 # Arch
 e2fsck -cc -C 0 /dev/sda2 # fsck
 ```
 
-## mount disk
+## Mount disk
 
 ```bash
 mkdir -p /mnt/boot
@@ -48,7 +48,7 @@ mount /dev/sda2 /mnt
 mount /dev/sda1 /mnt/boot
 ```
 
-## install base & Linux kernel
+## Install base & Linux kernel
 
 ```bash
 # choose between 'linux' or 'linux-lts'
@@ -62,13 +62,13 @@ pacman -S reflector
 reflector --protocol https --latest 30 --sort rate --save /etc/pacman.d/mirrorlist --verbose # optimize mirror list
 ```
 
-## install essentials
+## Install essentials
 
 ```bash
 pacman -S vim man-db man-pages git base-devel
 ```
 
-## locale
+## Locales
 
 ```bash
 ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
@@ -93,7 +93,7 @@ Find `<UUID>` from the output of `lsblk -f`.
 findmnt --verify --verbose # verify fstab
 ```
 
-## bootloader
+## Install bootloader
 
 ```bash
 pacman -S \
@@ -110,7 +110,7 @@ grub-mkconfig -o /boot/grub/grub.cfg
 
 - [GRUB/Tips and tricks - ArchWiki](https://wiki.archlinux.org/title/GRUB/Tips_and_tricks)
 
-## network
+## Setup network
 
 ```bash
 hostnamectl set-hostname takos
@@ -123,7 +123,7 @@ hostnamectl set-chassis server
 127.0.0.1 takos
 ```
 
-See https://systemd.network/systemd.network.html and https://wiki.archlinux.org/title/Systemd-networkd.
+See https://systemd.network/systemd.network.html and https://wiki.archlinux.org/title/Systemd-networkd, and <https://blog.ivansmirnov.name/set-up-pihole-using-docker-macvlan-network/>.
 
 ```ini /etc/systemd/network/wired.network
 [Match]
@@ -164,13 +164,13 @@ Scope=link
 Destination=10.0.1.100/30
 ```
 
-`ip` equivalent to the above settings:
+`ip` equivalent to the above config:
 
 ```bash
-ip link add dns-shim link enp5s0 type macvlan mode bridge # add macvlan shim
-ip a add 10.0.1.103/32 dev dns-shim # assign host ip to shim defined in docker-compose.yml
-ip link set dns-shim up # enable interface
-ip route add 10.0.1.100/30 dev dns-shim # route macvlan subnet to shim interface
+ip link add dns-shim link enp5s0 type macvlan mode bridge # add macvlan shim interface
+ip a add 10.0.1.103/32 dev dns-shim # assign the interface an ip address
+ip link set dns-shim up # enable the interface
+ip route add 10.0.1.100/30 dev dns-shim # route macvlan subnet (.100 - .103) to the interface
 ```
 
 ```bash
@@ -189,7 +189,7 @@ drill ddg.gg
 
 If `networkctl` keep showing `enp5s0` as `degraded`, then run `ip addr add 10.0.1.2/24 dev enp5s0 ` to manually assign static IP address for the workaround.
 
-## finalize
+## Finalize
 
 ```bash
 exit # leave chroot
@@ -204,7 +204,7 @@ timedatectl set-ntp true
 timedatectl status
 ```
 
-## shell
+## Shell
 
 ```bash
 pacman -S zsh
@@ -217,7 +217,7 @@ cd ~/.dotfiles
 reload
 ```
 
-## user
+## Setup operator user (i.e. user without superuser privilege)
 
 ```bash
 passwd # change root passwd
@@ -235,7 +235,7 @@ usermod -aG sudo <user> # add local user to sudo group
 visudo -c
 ```
 
-## ssh
+## SSH
 
 ```bash
 pacman -S openssh
@@ -265,7 +265,7 @@ cd yay
 makepkg -si
 ```
 
-## smartd
+## S.M.A.R.T.
 
 ```bash
 pacman -S smartmontools
@@ -275,7 +275,7 @@ smartctl -t short /dev/sda
 smartctl -l selftest /dev/sda
 ```
 
-## nvidia
+## NVIDIA drivers
 
 ```bash
 pacman -S nvidia-lts # 'nvidia' for 'linux' package
@@ -283,7 +283,7 @@ reboot
 nvidia-smi # test runtime
 ```
 
-## docker
+## Docker
 
 https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/arch-overview.html
 
@@ -340,7 +340,7 @@ services:
 
 # Additional setup
 
-## fail2ban
+## Fail2ban
 
 ```
 pacman -S fail2ban
@@ -385,10 +385,10 @@ banaction = iptables-allports
 
 ```bash
 systemctl enable --now fail2ban
-fail2ban-client status mailu
+fail2ban-client status sshd
 ```
 
-## telegraf
+## Telegraf
 
 ```bash
 yay -S telegraf
@@ -500,6 +500,8 @@ systemctl enable --now telegraf
 
 Dynamic DNS for Cloudflare.
 
+> Start [the GitHub repo](https://github.com/uetchy/cfddns) if you like :)
+
 ```
 yay -S cfddns sendmail
 ```
@@ -515,13 +517,14 @@ notification:
 ```ini /etc/cfddns/domains
 example.com
 dev.example.com
+example.org
 ```
 
 ```
 systemctl enable --now cfddns
 ```
 
-## backup
+## Backup
 
 ```bash
 pacman -S restic
@@ -554,7 +557,7 @@ WantedBy=timers.target
 
 ```bash /etc/backup/run.sh
 #!/bin/bash -ue
-
+# usage: run.sh
 # https://restic.readthedocs.io/en/latest/040_backup.html#
 
 export RESTIC_REPOSITORY=/path/to/backup
@@ -575,8 +578,8 @@ restic backup --tag system -v \
 
 # data
 restic backup --tag data -v \
-  --exclude 'appdata_*/preview' \
-  --exclude 'appdata_*/dav-photocache' \
+  --exclude 'appdata_*/preview' \ # nextcloud cache
+  --exclude 'appdata_*/dav-photocache' \ # nextcloud cache
   /mnt/data
 
 # prune
@@ -589,8 +592,54 @@ restic forget --prune --group-by tags \
 restic check
 ```
 
+```bash /etc/backup/show.sh
+#!/bin/bash
+# usage: show.sh <file|directory>
+# https://restic.readthedocs.io/en/latest/050_restore.html
+
+export RESTIC_REPOSITORY=/path/to/backup
+export RESTIC_PASSWORD=<passphrase>
+export RESTIC_PROGRESS_FPS=1
+
+TARGET=${1:-$(pwd)}
+MODE="ls -l"
+if [[ -f $TARGET ]]; then
+  TARGET=$(realpath ${TARGET})
+  MODE=dump
+fi
+
+TAG=$(restic snapshots --json | jq -r '[.[].tags[0]] | unique| .[]' | fzy)
+ID=$(restic snapshots --tag $TAG --json | jq -r ".[] | [.time, .short_id] | @tsv" | fzy | awk '{print $2}')
+
+>&2 echo "Command: restic ${MODE} ${ID} ${TARGET}"
+
+restic $MODE $ID ${TARGET}
+```
+
+```bash /etc/backup/restore.sh
+#!/bin/bash
+
+# https://restic.readthedocs.io/en/latest/050_restore.html
+
+export RESTIC_REPOSITORY=/path/to/backup
+export RESTIC_PASSWORD=<passphrase>
+export RESTIC_PROGRESS_FPS=1
+
+TARGET=${1:?Specify TARGET}
+TARGET=$(realpath ${TARGET})
+
+TAG=$(restic snapshots --json | jq -r '[.[].tags[0]] | unique | .[]' | fzy)
+ID=$(restic snapshots --tag $TAG --json | jq -r ".[] | [.time, .short_id] | @tsv" | fzy | awk '{print $2}')
+
+>&2 echo "Command: restic restore ${ID} -i ${TARGET} -t /"
+
+read -p "Press enter to continue"
+
+restic restore $ID -i ${TARGET} -t /
+```
+
 ```bash
-chmod 700 /etc/backup/run.sh
+chmod 700 /etc/backup/{run,show}.sh
 ln -sf /etc/backup/restic.{service,timer} /etc/systemd/system/
 systemctl enable --now restic
 ```
@@ -598,74 +647,22 @@ systemctl enable --now restic
 ## Kubernetes
 
 ```bash
-pacman -S kubeadm kubelet kubectl
-systemctl enable --now kubelet
-kubeadm init --pod-network-cidr='10.244.0.0/16'
-cp /etc/kubernetes/admin.conf ~/.kube/config
-
+pacman -S minikube kubectl
+minikube start --cpus=max
 kubectl taint nodes --all node-role.kubernetes.io/master- # to allow allocating pods to the master node
 
-# setup flannel network manager
-kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
-
-# setup nginx ingress controller
-# TODO
-
+minikube ip
 kubectl cluster-info
-kubectl get nodes
-kubectl get pods -A
 kubectl get cm -n kube-system kubeadm-config -o yaml
 ```
 
 - [Kubernetes - ArchWiki](https://wiki.archlinux.org/index.php/Kubernetes)
 - [Kubernetes Ingress Controller with NGINX Reverse Proxy and Wildcard SSL from Let's Encrypt - Shogan.tech](https://www.shogan.co.uk/kubernetes/kubernetes-ingress-controller-with-nginx-reverse-proxy-and-wildcard-ssl-from-lets-encrypt/)
 
-## wildcard certs
+## Audio
 
 ```bash
-pacman -S certbot certbot-dns-cloudflare
-echo "dns_cloudflare_api_token = <token>" > ~/.secrets/certbot/cloudflare.ini
-chmod 600 ~/.secrets/certbot/cloudflare.ini
-certbot certonly \
-  --email y@uechi.io \
-  --agree-tos \
-  --dns-cloudflare \
-  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
-  -d "*.uechi.io"
-openssl x509 -in /etc/letsencrypt/live/uechi.io/fullchain.pem -text
-certbot certificates
-```
-
-```ini /etc/systemd/system/certbot.service
-[Unit]
-Description=Let's Encrypt renewal
-
-[Service]
-Type=oneshot
-ExecStart=/usr/bin/certbot renew --quiet --agree-tos --deploy-hook "docker exec nginx-proxy-le /app/signal_le_service"
-```
-
-```ini /etc/systemd/system/certbot.timer
-[Unit]
-Description=Twice daily renewal of Let's Encrypt's certificates
-
-[Timer]
-OnCalendar=0/12:00:00
-RandomizedDelaySec=1h
-Persistent=true
-
-[Install]
-WantedBy=timers.target
-```
-
-- [Certbot - ArchWiki](https://wiki.archlinux.org/index.php/Certbot)
-- [Welcome to certbot-dns-cloudflare’s documentation! — certbot-dns-cloudflare 0 documentation](https://certbot-dns-cloudflare.readthedocs.io/en/stable/)
-- [docker-letsencrypt-nginx-proxy-companion/Standalone-certificates.md at master · nginx-proxy/docker-letsencrypt-nginx-proxy-companion](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/blob/master/docs/Standalone-certificates.md)
-
-## audio
-
-```bash
-pacman -S alsa-utils # maybe requires reboot
+pacman -S alsa-utils # maybe requires rebooting system
 usermod -aG audio <user>
 
 # list devices as root
@@ -730,18 +727,18 @@ pcm.!default {
 - [ALSA project - the C library reference: PCM (digital audio) plugins](https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html)
 - [Asoundrc - AlsaProject](https://www.alsa-project.org/wiki/Asoundrc)
 
-## firewall
+## Firewall
 
 ```bash
 pacman -S firewalld
-# TODO
+systemctl enable --now firewalld
 ```
 
 See [Introduction to Netfilter – To Linux and beyond !](https://home.regit.org/netfilter-en/netfilter/).
 
 # Maintenance
 
-## quick checkups
+## Quick checkups
 
 ```bash
 htop # show task overview
@@ -754,7 +751,7 @@ nvidia-smi # verify nvidia cards
 ps aux | grep "defunct" # find zombie processes
 ```
 
-## analyze logs
+## Delve into system logs
 
 ```bash
 journalctl -p err -b-1 -r # show error logs from previous boot in reverse order
@@ -766,29 +763,36 @@ journalctl _PID=2434 -e # filter logs based on PID and jump to the end of the lo
 journalctl -g 'timed out' # filter logs based on regular expression. if the pattern is all lowercase, matching is case insensitive
 ```
 
-```
-g - go to the first line
-G - go to the last line
-/ - search for the string
-```
+- g - go to the first line
+- G - go to the last line
+- / - search for the string
 
-## force override installation
+## Force overriding installation
 
 ```bash
 pacman -S <pkg> --overwrite '*'
 ```
 
-## fs issue checklist
+## Check memory modules
+
+```bash
+pacman -S lshw dmidecode
+
+lshw -short -C memory # lists installed mems
+dmidecode # shows configured clock speed
+```
+
+## File-system related issues checklist
 
 ```bash
 smartctl -H /dev/sdd
 
-# umount before this ops
+# umount the drive before this ops
 e2fsck -C 0 -p /dev/sdd1 # preen
 e2fsck -C 0 -cc /dev/sdd1 # badblocks
 ```
 
-# Common Issues
+# Common issues
 
 ## Longer SSH login (D-bus glitch)
 
@@ -846,6 +850,12 @@ This occurs after updating linux kernel.
 
 - Run `docker run --rm --gpus all --device /dev/nvidia0 --device /dev/nvidiactl --device /dev/nvidia-modeset --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools -it nvidia/cuda:10.2-cudnn7-runtime nvidia-smi` once.
 
+## `[sudo] Incorrect password` while password is correct
+
+```bash
+faillock --reset
+```
+
 # Useful links
 
 - [General recommendations](https://wiki.archlinux.org/index.php/General_recommendations#Users_and_groups)
diff --git a/source/_posts/2021/oauth-jwt-rfcs.md b/source/_posts/2021/oauth-jwt-rfcs.md
index 5ea7867..40da596 100644
--- a/source/_posts/2021/oauth-jwt-rfcs.md
+++ b/source/_posts/2021/oauth-jwt-rfcs.md
@@ -3,7 +3,7 @@ title: OAuth 2.0 と JWT 関連 RFC
 date: 2021-02-11
 ---
 
-個人的な調査のために OAuth 2.0 と JWT 関連 RFC を発行日順に並べています。
+個人的な調査のために OAuth 2.0 と JWT 関連 RFC を発行日順に並べた。
 
 ## [RFC6749](https://tools.ietf.org/html/rfc6749) — The OAuth 2.0 Authorization Framework
 
diff --git a/source/_posts/2021/server-2020.md b/source/_posts/2021/server-2020.md
index 62306a0..25cbd0a 100644
--- a/source/_posts/2021/server-2020.md
+++ b/source/_posts/2021/server-2020.md
@@ -3,51 +3,50 @@ title: 新しい自宅サーバーの構成
 date: 2021-02-13T00:00:00
 ---
 
-10 年ぶりにサーバーを更新しました。初めての AMD、初めての DDR4、初めての NVM Express です。
+10 年ぶりにサーバーを更新した。初めての AMD、初めての DDR4、初めての NVM Express!
 
 # 用途
 
-- セルフホスト (Docker)
-  - メールサーバー
-  - Nextcloud(ファイル、カレンダー、連絡先等)
-  - プライベート Docker レジストリ
-  - VPN 等
+- 各種セルフホスト (Docker)
+- Docker Swarm / K8s のマスター
 - 計算実験
-- Docker Swarm マスターノード
 - VS Code Remote SSH のホストマシン
+- VPN 他
 
 # スペック
 
-重いタスクを並列してやらせたいので最優先は CPU とメモリです。メモリはデュアルチャンネルにしたいので [DDR4-3200 32GBx2](https://shop.tsukumo.co.jp/goods/4582353591719/) を、CPU は昨今のライブラリのマルチコア対応を勘案して [Ryzen 9 3950X](https://www.amd.com/en/products/cpu/amd-ryzen-9-3950x) を選びました。CPU クーラーは Noctua の [NH-D15 Black](https://noctua.at/en/nh-d15) です。
+重いタスクを並列してやらせたいので最優先は CPU とメモリ。メモリは[DDR4-3200 32GBx2](https://shop.tsukumo.co.jp/goods/4582353591719/) を、CPU は昨今のライブラリのマルチコア対応を勘案して [Ryzen 9 3950X](https://www.amd.com/en/products/cpu/amd-ryzen-9-3950x) を選んだ。CPU クーラーは静音性を考えて Noctua の [NH-D15 Black](https://noctua.at/en/nh-d15) 。
 
-> 結果から言うとメモリはもっと必要でした。巨大な Pandas データフレームを並列処理なんかするとサクッと消えてしまいます。予算に余裕があるなら 128GB ほど用意したほうが良いかもしれません。
+> 結果から言うとメモリは 64GB では足りなかった。巨大な Pandas データフレームを並列処理したり、DeepSpeed でモデルの重みをオフロードするたびに OOM が発動してしまう。最終的に 128GB まで増やす羽目になった。
 
-> 追記: メモリ異常を起因とするシステム誤動作により、`/sbin` 以下がゼロ上書きされカーネルが起動しなくなるなど様々な厄災に襲われました。後日 Hynix 製のチップを搭載した V-color 社の ECC 付き U-DIMM に交換してからは、サーバーが安定動作するようになり現在に至ります。やはり 365 日稼働し続けるサーバーには最初からケチらずに ECC 付きメモリを選んでおいた方が賢明です。
+> 追記: メモリ異常を起因とするシステム誤動作により、`/sbin` 以下がゼロ上書きされカーネルが起動しなくなる災害が起きた。後日 ECC 付きのメモリに交換してからは、現在に至るまでメモリ関連の異常は発生していない。常時稼働するサーバーには最初から ECC メモリを選ぼう。
 
-GPU は古いサーバーに突っ込んでいた NVIDIA GeForce GTX TITAN X (Maxwell)を流用しました。グラフィックメモリが 12GB ちょっとですが、最大ワークロード時でも 5GB は残るので今のところ十分です。必要になったタイミングで増やします。
+GPU は古いサーバーに突っ込んでいた NVIDIA GeForce GTX TITAN X (Maxwell)を流用した。グラフィックメモリが 12GB ちょっとしかないが、最大ワークロード時でも 5GB は残るので今のところ十分。
 
-記憶装置は WD HDD 3TB 2 台と Samsung 970 EVO Plus 500GB M.2 PCIe、そして古いサーバーから引っこ抜いた Samsung 870 EVO Plus 500GB SSD です。NVMe メモリは OS 用、SSD/HDD はデータとバックアップ用にします。
+> 結果から言うと GPT-J や Megatron-LM を始めとした億パラメータ級のモデルを学習・推論させるには、DeepSpeed の助けがあったとしても最低 16GB の VRAM が必要だった。
 
-マザーボードは、X570 と比較して実装されているコンデンサーやパーツがサーバー向きだと感じた[ASRock B550 Taichi](https://www.asrock.com/mb/AMD/B550%20Taichi/) にしました。
+記憶装置は WD HDD 3TB 2 台と Samsung 970 EVO Plus 500GB M.2 PCIe、そして古いサーバーから引っこ抜いた Samsung 870 EVO Plus 500GB SSD 。NVMe メモリは OS 用、SSD/HDD はデータとバックアップ用にする。
 
-電源は今後 GPU を追加することを考えて [Seasonic PRIME TX 850](https://seasonic.com/prime-tx) を選びました。実際にサーバーを稼働させながら使用電力を計測したところ、アイドル時に 180W 前後、フル稼働時でも 350W を超えない程度でした。今後 UPS を買う場合はその付近+バッファを考慮したグレードを選ぶことにします。
+マザーボードは、X570 と比較して実装されているコンデンサーやパーツがサーバー向きだと感じた[ASRock B550 Taichi](https://www.asrock.com/mb/AMD/B550%20Taichi/) にした。
 
-ケースは Fractal Design の [Meshify 2](https://www.fractal-design.com/products/cases/meshify/meshify-2/Black/) です。
+電源は今後 GPU を追加することを考えて [Seasonic PRIME TX 850](https://seasonic.com/prime-tx) を選んだ。実際にサーバーを稼働させながら使用電力を計測したところ、アイドル時に 180W 前後、フル稼働時でも 350W を超えない程度だった。
 
-OS は長年付き合ってきた Ubuntu と袂を分かち、[Arch Linux](https://archlinux.org/) を選びました。ミニマルなところが好きです。本当に何も用意してくれません。セットアップウィザードとかないです。`which`すらインストールしなければ使えません。
+ケースは Fractal Design の [Meshify 2](https://www.fractal-design.com/products/cases/meshify/meshify-2/Black/) 。
 
-Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/installing-arch-linux/)を書いたので読んでください。入力したコマンドを全て記録しました。
+OS は長年付き合ってきた Ubuntu と袂を分かち、[Arch Linux](https://archlinux.org/) を選んだ。ミニマルと実用の間のバランスが取れていて好み。
 
-また、AUR (Arch User Repository)にパッケージを公開したい人向けに、Docker 自動ビルド・テストツールを[GitHub で公開](https://github.com/uetchy/archpkgs)しました。そちらもご覧ください。
+Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/installing-arch-linux/)を書いた。
+
+また、AUR (Arch User Repository)にパッケージを公開したい人向けに、Docker 自動ビルド・テストツールを[GitHub で公開](https://github.com/uetchy/archpkgs)した。
 
 # パーツ選定時のポイント
 
+- [WikiChip](https://en.wikichip.org/wiki/WikiChip)で CPU のモデルやスペックを調査する
 - [PCPartPicker](https://jp.pcpartpicker.com/)でパーツのコスト計算をする
 - [Bottleneck Calculator](https://pc-builds.com/calculator/)で CPU と GPU の組み合わせを選び、そのうちどちらが性能のボトルネックになるか調べる
 - [UserBenchmark](https://www.userbenchmark.com/)でユーザーが投稿したベンチマーク結果を眺める
-- パーツ購入前に [Linux Hardware Database](https://linux-hardware.org/) を見て、インストールする予定の Linux ディストリと相性が良いかチェックする
+- [Linux Hardware Database](https://linux-hardware.org/) を見て、インストールする予定の Linux ディストリとパーツの相性をチェックする
 - CPU クーラーは大口径の方が静か
-- メモリはデュアルチャンネルによる高速化を目指し 2 枚構成にする
 - PSU は Seasonic が評判良い
 - 東芝 D01 が HGST の系譜
 - [B550](https://www.amd.com/en/chipsets/b550) は長期運用に向いている(らしい)
@@ -57,7 +56,7 @@ Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/insta
 
 # 組立ての勘所
 
-- 半年間はすべての箱・書類を取っておく
+- 少なくとも 1 年間はすべての箱・書類を取っておく(特にメモリは箱自体が保証書代わりになっている場合がある)
 - 筐体は無視してまずマザボ、CPU、クーラー、(オンボードグラフィックが無い CPU なら)グラボ、そして電源を繋いで通電・動作テストをする
   - [MemTest86](https://www.memtest86.com/)でメモリの動作テストを最後までやる(エラーが出たら交換依頼)
   - USB ブートで OS の起動確認
@@ -68,4 +67,4 @@ Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/insta
   - 駄目ならマザボまたはアダプターメーカーからアップデートを探す
 - 安い筐体のネジは柔いことがあるため、強く押し込みながら少しずつ回す
   - 山が潰れてきたらゴムシートを挟む
-- すべて動いたら、[Probe を送信](https://linux-hardware.org/index.php?view=howto)してデータベースに貢献
+- すべて動いたら、[Linux Hardware Database に Probe を送信](https://linux-hardware.org/index.php?view=howto)して貢献
diff --git a/source/_posts/2021/split-bill.md b/source/_posts/2021/split-bill.md
index a2b7288..79d399d 100644
--- a/source/_posts/2021/split-bill.md
+++ b/source/_posts/2021/split-bill.md
@@ -3,12 +3,12 @@ title: 最小送金回数で精算する割り勘アルゴリズム
 date: 2021-02-14T00:00:00
 ---
 
-大人数でキャンプを楽しんだあとに待っているのは耐え難き送金処理です。
-次回から楽をするためにも、送金回数を最小化する制約で精算表を作る方法を考えましょう。
+大人数で旅行を楽しんだあとに待っているのは耐え難き精算・送金処理だ。
+次回から楽をするためにも、送金回数を最小化する制約で精算表を作る方法を考えよう。
 
 # tl;dr
 
-アイディアは「最も支払わなかった人が最も支払った人に払えるだけ払う ⇢ 債権を再計算して繰り返す」です。
+アイディアは「最も支払わなかった人が最も支払った人に払えるだけ払う ⇢ 債権を再計算して繰り返す」
 
 1. 全員の出費を算出(払い過ぎは正、払わなさすぎは負の数)
 2. 降順でソート(出費過多が先頭)
@@ -17,7 +17,7 @@ date: 2021-02-14T00:00:00
 
 # 実験
 
-実際にコードを書いて本当に望んでいる結果が得られるのかを検証します。
+実際にコードを書いて本当に望んでいる結果が得られるのかを検証する。
 
 ```js split-bill.js
 const history = [
@@ -122,7 +122,7 @@ for (const [_, { name, consumption }] of data) {
 }
 ```
 
-`history`に支払い履歴を書き込んで実行すると、「送金表」「履歴」「実質支払総額」が得られます。
+`history`に支払い履歴を書き込んで実行すると、「送金表」「履歴」「実質支払総額」が得られる。
 
 ```md
 # Transaction table
@@ -145,4 +145,4 @@ B virtually paid ¥81 in total
 C virtually paid ¥76 in total
 ```
 
-プログラムに落とし込むことができたら、あとはスプレッドシートのマクロにするなり自由です。面倒なことは全部コンピューターにやらせよう。
+プログラムに落とし込むことができたら、あとはスプレッドシートのマクロにするなり自由だ。面倒なことは全部コンピューターにやらせよう!
diff --git a/source/_posts/2021/uco-oil-lantern.md b/source/_posts/2021/uco-oil-lantern.md
index fa2d41a..cfa42b5 100644
--- a/source/_posts/2021/uco-oil-lantern.md
+++ b/source/_posts/2021/uco-oil-lantern.md
@@ -3,7 +3,7 @@ title: 手のひらサイズのオイルランタン
 date: 2021-06-08T00:00:00
 ---
 
-UCO キャンドルランタンを改造して手のひらサイズのオイルランタンを作りました。
+UCO キャンドルランタンを改造して手のひらサイズのオイルランタンを作った。
 
 ![](lantern.jpeg)
 
@@ -17,7 +17,7 @@ UCO キャンドルランタンを改造して手のひらサイズのオイル
 
 # 材料
 
-ほとんどのパーツはドラッグストアやホームセンターで調達できます。
+ほとんどのパーツはドラッグストアやホームセンターで調達できる。
 
 1. 大正漢方胃腸薬(30 ml)
    ![](taisho.png)
@@ -70,8 +70,8 @@ UCO キャンドルランタンを改造して手のひらサイズのオイル
 - M8 ボルトが通り、外径がガラス内径に近い低めの瓶を探す
 - ガスケットで密封?
 
-## M6 ボルトは微妙
+## 失敗例: M6 ボルトは微妙
+
+ネットで広く紹介されている M6 ボルトを使う方法だと、炎がロウソク並に小さくなってしまった。あまりオススメできない。
 
 ![](comparison.jpeg)
-
-ネットで広く紹介されている M6 ボルトを使う方法だと、炎がロウソク並に小さくなってしまう。