自宅サーバー構築譚：Ubuntu on ZFS in デスクトップパソコン(BIOS,MBR)

# 能書き

[自宅サーバー構築譚：基本構想](https://qiita.com/katz_engineer/items/cb592be44daa28a51d9b)に基づく自宅サーバー構築の続き。今度は実機にインストールします。

## 参考文献

参考文献1：[自宅サーバー構築譚：Ubuntu on ZFS in Hyper-V （第1世代）](https://qiita.com/katz_engineer/items/b6ccc3a4f1e03cf8415a)
参考文献2：[ルートパーティションをZFSにしてUbuntu 20.04 LTSをインストールしてみた - hnakamur's blog](https://hnakamur.github.io/blog/2020/04/26/ubuntu-20.04-root-on-zfs/)
参考文献3：[Ubuntu 20.04 Root on ZFS - OpenZFS Documentation - OpenZFS](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2020.04%20Root%20on%20ZFS.html)

# インストール環境の整備

ハードウェアの仕様は[昔書いた記事](https://qiita.com/katz_engineer/items/f032a24cb273c4eb6669)の通りです。将来的にはこれをセカンダリサーバにする予定ですが、今回はプライマリサーバとして構築します。

しかしこのマシンは古過ぎたようです。手順の通りでは、そもそもブートが途中で止まってしまうという体たらく。なぜかBIOS画面も表示できず、コンセントを抜いて数分待たないと戻らないという訳の分からない状態になってしまいました。原因はどうやらGPTにあった模様。

と言う訳で。[前回のHyper-Vを利用した手順確認](https://qiita.com/katz_engineer/items/b6ccc3a4f1e03cf8415a)とは少し異なり、GPTではなくてMBRでパーティションを切るようにしています。

## デスクトップインストーラーを起動しsshの環境整備

サーバーをインストールする場合でもデスクトップ版のisoを使用します。Ubuntuのサイトからダウンロードして、USBメモリに焼きます。
私は普段使いのWin10マシンで[Rufus](https://forest.watch.impress.co.jp/library/software/rufus/)というツールを使ってみましたが、ここはお好みでどうぞ。

このUSBメモリをインストール対象マシンに挿入して、ここから起動。

GUI インストーラーが立ち上がって Welcome という画面が表示されたら、 TAB キーを押して Try Ubuntu ボタンにフォーカスを移動して（ボタンにオレンジの枠がつきます） Enter キーを押します。

ウィンドウ環境に切り替わったらターミナルを起動しますが、マウスが繋がっていない場合はショートカットキー Ctrl+Alt+T でどうぞ。

主な作業はsshで接続して行いたいので、そのように準備します。sshで接続するのはコマンドをコピペできるから。私もやってみてわかりました。これ良いですな。

ターミナルで下記の2つのコマンドを実行。

```console
sudo apt-add-repository universe
sudo apt update
```

OpenSSHサーバーをインストール。

```console
sudo apt install --yes openssh-server
```

ssh接続用にユーザー ubuntu のパスワードを設定。

```console
passwd
```

ssh接続先のIPアドレスを確認します。

```console
ip a
```

## 別のマシンから対象のサーバーに ssh してインストール作業を続行

ssh はほとんどのOSで利用可能でしょう。Windows10でもコマンドプロンプトからsshコマンドを実行できます。

```console
ssh ubuntu@接続先のIPアドレス
```

インストール作業を同じマシンでやり直してたりすると、ここでエラーが出る事があります。そんな時には ```.ssh\known_hosts``` を削除してから、sshコマンドを実行します。

```console
del %USERPROFILE%\.ssh\known_hosts
```

rootユーザーになります。

```console
sudo -i
```

# ディスクのフォーマット

起動用のUSBメモリを挿します。ここにブートローダを仕込んで常時付けっ放しにしておく予定。

そのUSBメモリを含めたフォーマット対象ディスクを確認します。

```console
lsblk
```

今回は下記のように表示されます。

```console
root@ubuntu:~# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0    7:0    0     2G  1 loop /rofs
loop1    7:1    0   219M  1 loop /snap/gnome-3-34-1804/72
loop2    7:2    0    51M  1 loop /snap/snap-store/547
loop3    7:3    0  65.1M  1 loop /snap/gtk-common-themes/1515
loop4    7:4    0  55.4M  1 loop /snap/core18/2128
loop5    7:5    0  32.3M  1 loop /snap/snapd/12704
sda      8:0    0 465.8G  0 disk
├─sda1   8:1    0 465.8G  0 part
└─sda9   8:9    0     8M  0 part
sdb      8:16   0 465.8G  0 disk
├─sdb1   8:17   0 465.8G  0 part
└─sdb9   8:25   0     8M  0 part
sdc      8:32   1   7.5G  0 disk
├─sdc1   8:33   1   2.9G  0 part /cdrom
├─sdc2   8:34   1   3.9M  0 part
└─sdc3   8:35   1   4.6G  0 part /var/crash
sdd      8:48   1  14.9G  0 disk
├─sdd1   8:49   1     1G  0 part
└─sdd2   8:50   1   260M  0 part
sr0     11:0    1  1024M  0 rom
```

```loop0```～```loop5```はインストーラによる設定でしょうか。
```sda```と```sdb```が内蔵HDDで、以前入れたArchLinuxが残っています。
```sdc```が今回のUbuntuインストーラでしょう。
```sdd```はブートローダを仕込む為のUSBメモリです。
```sr0```はCR-ROMドライブと思われますが、今回は無関係です。

ディスクの指定にはIDを使います。

```console
ls -l /dev/disk/by-id
```

これを変数に設定するのがubuntu流らしいですが、ここは私の流儀で取得する事にします。

```console
BOOTDISK=$(cd /dev/disk/by-id; ls ata-* usb-* | while read d; do if [ "$(readlink -f $d)" = "/dev/sdd" ]; then echo "/dev/disk/by-id/$d"; fi; done)
```

```console
DISK1=$(cd /dev/disk/by-id; ls ata-* usb-* | while read d; do if [ "$(readlink -f $d)" = "/dev/sda" ]; then echo "/dev/disk/by-id/$d"; fi; done)
```

```console
DISK2=$(cd /dev/disk/by-id; ls ata-* usb-* | while read d; do if [ "$(readlink -f $d)" = "/dev/sdb" ]; then echo "/dev/disk/by-id/$d"; fi; done)
```

ブート用USBメモリのパーティションを全削除します。

```console
wipefs -a $BOOTDISK
```

パーティションを作成。GPTではなくてMBRにします。

```console
sfdisk $BOOTDISK <<___
,1G,bf
,
___
```

設定を確認するコマンドは下記になります。

```console
sfdisk -l $BOOTDISK
```

```$DISK1```と```$DISK2```はパーティションに分けません。

```console
wipefs -a $DISK1 $DISK2
```

いよいよzfsフォーマットします。ここが今回最大のコピペポイント！これをコピペする為にssh経由で接続していると言っても過言ではありません。

因みにこのzpool名は```bpool```固定らしい。

※なお2回目以降でエラーが出る際には、コマンドの末尾かどこかに ```-f``` オプションを付加します。

```console
zpool create -o ashift=12 -d \
    -o feature@async_destroy=enabled \
    -o feature@bookmarks=enabled \
    -o feature@embedded_data=enabled \
    -o feature@empty_bpobj=enabled \
    -o feature@enabled_txg=enabled \
    -o feature@extensible_dataset=enabled \
    -o feature@filesystem_limits=enabled \
    -o feature@hole_birth=enabled \
    -o feature@large_blocks=enabled \
    -o feature@spacemap_histogram=enabled \
    -o feature@userobj_accounting=enabled \
    -O acltype=posixacl -O canmount=off -O devices=off \
    -O normalization=formD -O relatime=on -O xattr=sa \
    -O mountpoint=/ -R /mnt bpool $BOOTDISK-part1
```

参考文献には下記のように書かれていました。

> ```normalization=formD``` は Unicode の normalization の NFD に相当します。 昔 Subversion で Windows は NFC, Mac OS X は NFD と違うせいで全角カナの濁点が分かれない、分かれるで苦労したので NFC にしようかと思いましたが、 formD でも Windows と mac から繋いで問題ないと聞いたので formD にしておきました。

私は最近この件で苦労したのでformCにしたいのですが、そもそものwikiには改変しない方が良いと書いてあったので止めておきます。

そして内蔵HDDもzfsフォーマットします。こちらはオプションがすっきりしてますが、2つ1組のHDDをミラーリングに設定します。

こちらのzpool名は何でも良いそうです。zfsの伝統に則って```tank```にしてみました。

```console
zpool create -o ashift=12 \
    -O acltype=posixacl -O canmount=off \
    -O dnodesize=auto -O normalization=formD -O relatime=on -O xattr=sa \
    -O mountpoint=/ -R /mnt tank mirror $DISK1 $DISK2
```

作成したプール一覧の確認は下記。このコマンドはコピペではなくて ```zpool list``` ```zpool status```と手打ちでお願いします。別に良いよねこの位は。

```console
root@ubuntu:~# zpool list
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
bpool   960M   576K   959M        -         -     0%     0%  1.00x    ONLINE  /mnt
tank    464G   600K   464G        -         -     0%     0%  1.00x    ONLINE  /mnt
root@ubuntu:~# zpool status
  pool: bpool
 state: ONLINE
  scan: none requested
config:

        NAME                                                      STATE     READ WRITE CKSUM
        bpool                                                     ONLINE       0     0     0
          usb-SanDisk__Cruzer_Fit_4C530000180129117161-0:0-part1  ONLINE       0     0     0

errors: No known data errors

  pool: tank
 state: ONLINE
  scan: none requested
config:

        NAME                                            STATE     READ WRITE CKSUM
        tank                                            ONLINE       0     0     0
          mirror-0                                      ONLINE       0     0     0
            ata-WDC_WD5003ABYX-50WERA1_WD-WMAYP7972470  ONLINE       0     0     0
            ata-WDC_WD5003ABYX-50WERA1_WD-WMAYP7949276  ONLINE       0     0     0

errors: No known data errors
```

# システムのインストール

## ディレクトリ構造に合わせたデータセット作成

ルート用データセットを作成します。

```console
zfs create -o canmount=off -o mountpoint=none tank/main
```

```console
zfs create -o canmount=noauto -o mountpoint=/ tank/main/ubuntu
```

```console
zfs mount tank/main/ubuntu
```

ブート用データセットを作成します。

```console
zfs create -o canmount=off -o mountpoint=none bpool/boot
```

```console
zfs create -o canmount=noauto -o mountpoint=/boot bpool/boot/ubuntu
```

```console
zfs mount bpool/boot/ubuntu
```

一般的なデータセットを作成します。

```console
zfs create -o canmount=off                 tank/sub0
zfs create -o mountpoint=/home             tank/sub0/home
zfs create -o mountpoint=/root             tank/sub0/root
zfs create -o canmount=off                 tank/sub0/var
zfs create -o canmount=off                 tank/sub0/var/lib
zfs create -o mountpoint=/var/log          tank/sub0/var/log
zfs create -o mountpoint=/var/spool        tank/sub0/var/spool
zfs create -o mountpoint=/var/snap         tank/sub0/var/snap
zfs create -o canmount=off                 tank/sub0/usr
zfs create -o mountpoint=/usr/local        tank/sub0/usr/local
zfs create -o com.sun:auto-snapshot=false -o mountpoint=/var/lib/docker tank/sub0/var/lib/docker
```

## debootstrap

```debootstrap```ではなくて```mmdebstrap```を使ってみようかと考えたのですが、残念ながら失敗しました。```mdebstrap```ではインストール先ディレクトリが空でなければならないようです。

参考文献：[第594回　mmdebstrapで最小のルートファイルシステムを作る - Ubuntu Weekly Recipe](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0594)

そういう訳で、```debootstrap```を入れてから Ubuntu 20.04 LTS 通称 focal をインストール。

```console
apt install --yes debootstrap
```

```console
debootstrap focal /mnt
```

終わったら以下のコマンドを実行します。

```console
zfs set devices=off tank
```

# システム設定

## マシン名

まずはマシン名を決めます。

```console
HOSTNAME=＜マシン名＞
```

```console
echo $HOSTNAME >/mnt/etc/hostname
```

## ネットワーク関連

hostsファイルを修正。

```console
sed -i -e"/^127.0.0.1/a 127.0.1.1\t$HOSTNAME" /mnt/etc/hosts
```

netplan のネットワーク設定ファイル```/mnt/etc/netplan/01-netcfg.yaml```を作成します。今回はIPv6は使わないようにするので下記のようにしてみました。

このマシンはNICを2枚持っています。片方はオンボードで、もう片方はギガビットイーサのPCIネットワークカードです。オンボードの方は遅いのでケーブルを外してあります。

```console
root@ubuntu:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp2s1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:16:01:5c:19:df brd ff:ff:ff:ff:ff:ff
    inet 172.16.2.22/16 brd 172.16.255.255 scope global dynamic noprefixroute enp2s1
       valid_lft 83861sec preferred_lft 83861sec
    inet6 2408:211:1283:500:1aa3:2163:dfcb:c720/64 scope global temporary dynamic
       valid_lft 602255sec preferred_lft 83327sec
    inet6 2408:211:1283:500:9cce:f37a:54a3:5efa/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 2591903sec preferred_lft 604703sec
    inet6 fe80::2fff:e4:2986:a19c/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: enp0s25: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 00:21:9b:1a:5f:94 brd ff:ff:ff:ff:ff:ff
```

[以前の記事](https://qiita.com/katz_engineer/items/04396d58add14cb63573#%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3)の通りにIPアドレスを割り振ります。

参考文献：[固定IPアドレスの割当(IPv4、IPv6) - Netplanの使い方 - komeの備忘録](https://www.komee.org/entry/2018/06/12/181400#%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E5%89%B2%E5%BD%93IPv4IPv6)

```console
cat > /mnt/etc/netplan/01-netcfg.yaml <<___
network:
  version: 2
  renderer: networkd
  ethernets:
    enp2s1:
      dhcp4: no
      addresses: [172.16.0.3/16]
      gateway4: 172.16.0.1
      nameservers:
        addresses: [172.16.0.1]
    enp0s25:
      dhcp4: no
      addresses: [172.16.0.4/16]
      gateway4: 172.16.0.1
      nameservers:
        addresses: [172.16.0.1]
___
```

参考文献には```/mnt/etc/apt/sources.list```の変更に言及がありますが、省略可との事ですし、今回は省略します。

## chroot

Live CD 環境の仮想ファイルシステムをバインドマウントして、上記でセットアップした環境に chroot します（ --bind ではなく --rbind を使っていることに注意）。

```console
mount --rbind /dev  /mnt/dev
mount --rbind /proc /mnt/proc
mount --rbind /sys  /mnt/sys
```

```console
chroot /mnt /usr/bin/env BOOTDISK=$BOOTDISK bash --login
```

chroot 環境内の apt のインデクスを更新します。

```console
apt update
```

## ロケール

en_US.UTF-8 と ja_JP.UTF-8 と、後は個人的な好みで。

```console
locale-gen --purge en_US.UTF-8 ja_JP.UTF-8 ja_JP.EUC-JP
```

```console
update-locale LANG=en_US.UTF-8 LANGUAGE=en_US
```

```console
dpkg-reconfigure --frontend noninteractive locales
```

## タイムゾーン

日本なら Asia/Tokyo です。

```console
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```

```console
dpkg-reconfigure -f noninteractive tzdata
```

## カーネルイメージなど

Linux のカーネルイメージと ZFS を chroot 環境にインストールします。

```console
apt install --yes --no-install-recommends linux-image-generic zfs-initramfs
```

上記のコマンド実行の出力の最後に以下のようなメッセージが出ます。 ```update-initramfs```が```/boot/initrd.img-5.4.0-26-generic```を生成したという点が重要だそうです。この後 grub のインストール時に必要になる為です。

```console
update-initramfs: Generating /boot/initrd.img-5.4.0-26-generic
```

## GRUB をレガシー BIOS 用にインストール

参考文献に従って以下のコマンドを実行。

```console
DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install grub-pc
```

## rootパスワード

パスワードを設定します。

```console
passwd
```

## zfsのzpool関係

tank_boot を確実にインポートするためのサービスのユニットファイルを作成します。

```console
cat >/etc/systemd/system/zfs-import-bpool.service <<___
[Unit]
DefaultDependencies=no
Before=zfs-import-scan.service
Before=zfs-import-cache.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/zpool import -N -o cachefile=none bpool

[Install]
WantedBy=zfs-import.target
___
```

このサービスの自動起動を有効にします。

```console
systemctl enable zfs-import-bpool.service
```

## tmpfs

次回起動時に tmpfs を /tmp にマウントするようにします。

```console
cp /usr/share/systemd/tmp.mount /etc/systemd/system/
systemctl enable tmp.mount
```

# GRUB のインストール

ZFS のブートファイルシステムが認識されていることを確認します。```zfs``` と出力されれば OK です。

```console
grub-probe /boot
```

grub の設定ファイルを修正します。sed コマンドにすると少々複雑ですが。

```console
sed -i -e '/^GRUB_TIMEOUT=/{s/=.*/=5/;a\
GRUB_RECORDFAIL_TIMEOUT=5
}
/^GRUB_CMDLINE_LINUX_DEFAULT=/s/quiet splash//
s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX="root=ZFS=tank/main/ubuntu"|
/^#GRUB_TERMINAL=console/s/#//
' /etc/default/grub
```

修正結果は下記の通り。

```console
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
#   info -f grub -n 'Simple configuration'

GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=5
GRUB_RECORDFAIL_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="root=ZFS=tank/main/ubuntu"

# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"

# Uncomment to disable graphical terminal (grub-pc only)
GRUB_TERMINAL=console

# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480

# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true

# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"

# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"
```

この設定変更を反映します。

```console
update-grub
```

が、この結果はエラーが発生します。osprober でbusyエラーが出ますが OK らしい。Found linux image と Found initrd image の行が出ていれば大丈夫との事。

```console
root@ubuntu:/# update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
cannot open 'bpool/BOOT/ubuntu': dataset does not exist
Found linux image: vmlinuz-5.4.0-26-generic in tank/main/ubuntu
Found initrd image: initrd.img-5.4.0-26-generic in tank/main/ubuntu
device-mapper: reload ioctl on osprober-linux-sda1  failed: Device or resource busy
Command failed.
device-mapper: reload ioctl on osprober-linux-sdb1  failed: Device or resource busy
Command failed.
grub-probe: error: cannot find a GRUB drive for /dev/sdd1.  Check your device.map.
done
```

レガシー BIOS 用に GRUB をインストールします。

```console
grub-install $BOOTDISK
```

ZFS のモジュールがインストールされていることを確認します。

```console
ls /boot/grub/*/zfs.mod
```

# 初回のブート

## スナップショット

初回インストールのスナップショットを作成しておきます。こういう事をしたいが為にZFSを使うのです。

```console
zfs snapshot bpool/boot/ubuntu@$(date +%Y%m%d_%H%M%S)_install
```

```console
zfs snapshot tank/main/ubuntu@$(date +%Y%m%d_%H%M%S)_install
```

```console
zfs snapshot -r tank/sub0@$(date +%Y%m%d_%H%M%S)_install
```

スナップショットの一覧を表示して確認します。

```console
zfs list -t snapshot
```

## リブート

chroot 環境から抜けて Live CD 環境に戻ります。

```console
exit
```

Live CD 環境でマウント中のファイルシステムを全てアンマウントします。

```console
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -n 1 -r umount -lf
```

```console
zpool export -a
```

なぜかエラーが出る事があります。

```console
root@ubuntu:~# zpool export -a
umount: /mnt: target is busy.
cannot unmount '/mnt': umount failed
```

そんな時にはもう一度実行。

```console
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -n 1 -r umount -lf
```

```console
zpool export -a
```

成功したらシャットダウン。

```console
shutdown -h now
```

その後、インストールメディアを取り出して、それからマシンの電源を入れます。

## rootログイン

ここからはsshは使えません。

サーバーのコンソールで root ユーザーでパスワードを入力してログインします。

## 日本語キーボード配列

記号を打ってみるとわかりますが、英語配列になっています。日本語配列に変更する手順は以下の参考文献を参照。バージョンは古いですが、画面キャプチャがあるのでわかりやすいです。

参考文献：[Ubuntuでキーボードレイアウト変更 - Ragnite Blue](https://thejuraku.com/pc/ubuntu%E3%81%A7%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E5%A4%89%E6%9B%B4/)

コマンドは下記。

```console
dpkg-reconfigure keyboard-configuration
```

設定後、次のコマンドを打つ必要があるようです。

```console
setupcon
```

## スワップ

[物理メモリを十分に積んでいてもスワップは重要](https://twitter.com/hnakamur2/status/1228885297917620226)だそうです。

容量（```4G```の箇所）はマシンの状況に合わせて検討して下さい。

```console
zfs create -V 4G -b $(getconf PAGESIZE) \
    -o logbias=throughput -o sync=always \
    -o primarycache=metadata -o secondarycache=none \
    -o com.sun:auto-snapshot=false tank/swap
```

次にスワップを設定します。

```console
mkswap -f /dev/zvol/tank/swap
echo /dev/zvol/tank/swap none swap discard 0 0 >> /etc/fstab
echo RESUME=none > /etc/initramfs-tools/conf.d/resume
```

スワップを有効にします。

```console
swapon -av
```

有効になったかどうか確認。

```console
swapon --show
```

# フルのソフトウェアインストール

ミニマムインストールをアップグレードします。

```console
apt dist-upgrade --yes
```

サーバ用としてコマンドライン環境のみをインストールします。

```console
apt install --yes ubuntu-standard
```

# 再起動して確認

```console
reboot
```

まだ一般ユーザーが居ないので、rootでログインします。
そして色々確認。

- キーボードが日本の配列になっている事。アットマーク @ を打ってみて確認。
- スワップが有効になっている事。上述の```swapon --show```コマンドで確認。
- ネットワ－クが有効になっている事。仮想環境など状況によってNICの名称が変わる事があり、その場合は上述の設定```/etc/netplan/01-network.yaml```のNIC名```eth0```を変更する必要があります。

ネットワークに関しては、次のようなコマンドを試してみればわかります。
※ example.com はドメインの例示の際に使うべしとRFC2606で定められています。何か適当なサーバーを選んで下さい。

```console
ping -c2 example.com
```

失敗した場合には、上述のネットワーク設定ファイル```/mnt/etc/netplan/01-netcfg.yaml```を修正します。その為のNIC名取得は下記のコマンドで。

参考文献：[Linux から認識されている、すべてのネットワークインターフェイス名だけを取得する - Qiita](https://qiita.com/p_cub/items/43c5c44886443087de09)

```console
for d in `find /sys/devices -name net | grep -v virtual`; do ls $d; done
```

手打ちのコマンドとしては```ip a```の方が簡単ですが、上記のコマンドならNIC名だけを取り出せますので自動化が可能です。

# 結び

これで本当に最小限のUbuntuサーバをセットアップできました。これからサーバとして育てていく予定です。:thumbsup_tone1: