UbuntuにLXDをインストールしてUbuntuコンテナを動かしLinuxGSMを用いたHeadless Factorioの世界で太陽系外縁を目指す手順

# はじめに
いまさらながら、[Factorio Space Age](https://store.steampowered.com/app/645390/Factorio_Space_Age/)をじっくりやるためと、おうちの仮想サーバ環境の作り直しを兼ねて作業の備忘録を書く。

前半は仮想サーバのつくりかた。後半はFactorioゲームサーバーのつくりかた。

## 目的
ESXiは逝った。Proxmoxは悪くないがちょっと大げさ。正直WebUIとかそんなに要らない。なので、LXDに手を出してみることにした。ちょろっと動かすならRPiとかmac（UTM）のARM版でも動くしつぶしが効く。

FactorioはHeadlessで、いわゆるDedicatedサーバとして自分でゲームサーバを立てることができる。
設定次第で、オフライン中でもゲーム内の時間は経過させることができるので、のんびり半放置でやりたい自分にとっては、ゲームを起動していない間も黙々と製作が進んでくれるのがありがたい。ついでにSatisfactoryも黙々と進ませることができる。

ピースフルにしていないと工場が滅びたけれど。

## 使用する環境について

今回自分が使ったものは、10年ほど前に組んだPC。単純な性能だけならN100のが上だろう。
[Intelがやらかしてi7相当になってしまったCPU](https://akiba-pc.watch.impress.co.jp/docs/news/news/611506.html)に、ほかの古いPCで使っていたものも回収して32GBのメモリ。
[かつて変態マザー製造所と言われたメーカーの、この世代なのにnvmeブート対応なマザー](https://www.asrock.com/mb/Intel/Z87M%20Extreme4/index.jp.asp)にNVMe SSDとHDDを突っ込み、
オンボードNICのほかに、どこかで入手した2ポートGbEアダプタで計3ポートのNIC。DHCPでグローバルIPv4アドレスが降ってくる地域なので活用してみる。

最近は中古PC市場でもこれより上のスペックのものが安く手に入るので、自宅サーバに手を出してみたい人には出しやすい世の中である。自宅サーバの需要があるか知らんけど。少なくともゲームの専用サーバであればスペックが要るので、VPSを使うよりかは安く済む気がする。

こんな古いPCでも、FactorioとSatisfactoryは同時に動かせるし、一時期はARKとConan exilesも動いてた。
とりあえず必要なのはそこそこのCPUとたっぷりのメモリとストレージ。

:::note info
本記事ではとりあえず、4C以上のCPU、8GB以上のメモリ、500GB以上のSSDストレージ、2ポート以上のNICが必要。
途中のネットワーク設定が複数ポートある前提の内容になっているので、1ポートの場合は1ポート用の手順にする必要がある。
:::

:::note warn
記事中は面倒なのでわりとrootでやっている。危ないのでsudo使おう。
:::

:::note alert
本記事ではサーバの公開を想定せず、セキュリティ対策について記述しない。本当のマルチプレイをしたい場合はそこんとこ注意。
:::

## Ubuntuのインストール

よしなにインストールする。
インストール時に、NICのうち1つだけをIP固定としておく。
これは、このサーバへのSSH接続などを行ったり、サーバ自体がインターネットアクセスを行うためのNICとなる。
それ以外のNICは、仮想マシンとコンテナが利用するポートとするため、ここでは無効（disabled）にしておく。

![01_Ubuntu_NIC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143797/94b65631-9722-855b-6601-0f7835b498b8.png)
イメージ図

### Ubuntuのインストール後初期設定

パッケージのアップグレードがてらネットワーク接続確認でもする。
好みに合わせて設定する。とりあえずタイムゾーンの変更とmdnsの有効化。

### NIC設定

:::note warn
本項の設定は複数NICをもつ環境でホストの通信とコンテナ・仮想マシンの通信を別ポートとするための設定となる。
1NICの場合かつ、コンテナ・仮想マシンを物理ネットワークとブリッジ接続させたい場合は、別の手法が必要。

[LXDコンテナをホストのネットワークにぶら下げる@みつきんのメモ](https://mickey-happygolucky.hatenablog.com/entry/2023/01/08/231239) とか

:::

インストール時にdisabledとしたNICを起こす。
後ほどLXDのブリッジインターフェースとするため、起こすだけで何も設定が入っていない状態にする。

以下の場合、enp2s0f0とenp2s0f1が対象となる。

```shell:設定前
# networkctl
IDX LINK     TYPE     OPERATIONAL SETUP
  1 lo       loopback carrier     unmanaged
  2 enp0s25  ether    routable    configured
  3 enp2s0f0 ether    off         unmanaged
  4 enp2s0f1 ether    off         unmanaged

4 links listed.

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
（中略）
2: enp0s25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
（中略）
3: enp2s0f0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:15:2a:6e:71:16 brd ff:ff:ff:ff:ff:ff
4: enp2s0f1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:15:2a:6e:71:17 brd ff:ff:ff:ff:ff:ff
```

netplanの設定を開き、該当インターフェースの設定を追記する。

```yaml:/etc/netplan//etc/netplan/
network:
    ethernets:
        enp0s25:
            （中略）
        enp2s0f0:
            addresses: []
            dhcp4: false
            dhcp6: false
            accept-ra: false
            link-local: []
            ignore-carrier: true
            optional: true
        enp2s0f1:
            addresses: []
            dhcp4: false
            dhcp6: false
            accept-ra: false
            link-local: []
            ignore-carrier: true
            optional: true
    version: 2
```

アドレスを設定しない、DHCPを利用しない、RAを受け取らない、リンクローカルアドレスを設定しない、設定されていなくても気にしない、起動時に待機しない。とにかく何も設定しないよう設定する。
``` activation-mode ``` オプションでもっと短くできそうな気がしなくもないんだけども。

```netplan apply``` で設定を反映し、状態を確認する。
インタフェースが起きてきて、アドレスが何も設定されていなければよい。
networkctlでconfiguredとなり、ip aで ```state UP``` に変化していることとアドレスが無いことを確認する。

```shell:設定後
# networkctl
IDX LINK     TYPE     OPERATIONAL SETUP
  1 lo       loopback carrier     unmanaged
  2 enp0s25  ether    routable    configured
  3 enp2s0f0 ether    carrier     configured
  4 enp2s0f1 ether    carrier     configured

4 links listed.

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
（中略）
2: enp0s25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
（中略）
3: enp2s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:（中略）:16 brd ff:ff:ff:ff:ff:ff
4: enp2s0f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:（中略）:17 brd ff:ff:ff:ff:ff:ff
```

## LXD

### LXDインストール

```snap install lxd``` でインストールする。

```shell:snap install lxd
# snap install lxd
lxd (5.21/stable) 5.21.2-084c8c8 from Canonical✓ installed
```

:::note info
[incus](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0796)もだいたい同じなのでお好みで。
:::

### LXD初期設定

```lxd init``` で初期設定を行う。

```shell:lxd init
# lxd init
Would you like to use LXD clustering? (yes/no) [default=no]: no
Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
Name of the new storage pool [default=default]: default
Name of the storage backend to use (zfs, btrfs, ceph, dir, lvm, powerflex) [default=zfs]: btrfs
Create a new BTRFS pool? (yes/no) [default=yes]: yes
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]: no
Size in GiB of the new loop device (1GiB minimum) [default=30GiB]: 250GiB
Would you like to connect to a MAAS server? (yes/no) [default=no]: no
Would you like to create a new local network bridge? (yes/no) [default=yes]: yes
What should the new bridge be called? [default=lxdbr0]: lxdbr0
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto
Would you like the LXD server to be available over the network? (yes/no) [default=no]: yes
Address to bind LXD to (not including port) [default=all]: all
Port to bind LXD to [default=8443]: 8443
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]: yes
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: yes
```

デフォルト値からの変更箇所
- デフォルトプールのファイルシステムをzfsではなくbtrfsを指定
    - 好みと思い込みの問題なのでzfsでもいい
- デフォルトプールのサイズを30GiBではなく250GiBに拡大
    - 30GiBだと足りないので、500GBストレージの半分あたりまで拡大
- LXDサーバのリモート操作を無効から有効に変更
    - おいおい別PCから操作することがあるため
- 設定内容をYAMLで表示
    - とりあえず作業結果の吐き出し
    - ```lxd init --preseed``` でYAMLを食わせることができる

```yaml:lxd init preseed
config:
  core.https_address: '[::]:8443'
networks:
- config:
    ipv4.address: auto
    ipv6.address: auto
  description: ""
  name: lxdbr0
  type: ""
  project: default
storage_pools:
- config:
    size: 250GiB
  description: ""
  name: default
  driver: btrfs
storage_volumes: []
profiles:
- config: {}
  description: ""
  devices:
    eth0:
      name: eth0
      network: lxdbr0
      type: nic
    root:
      path: /
      pool: default
      type: disk
  name: default
projects: []
cluster: null
```

### LXD ブリッジネットワークの作成

まず、以下の条件でネットワークを作成する
- IPv4/v6ともに
    - アドレスを持たない
    - アドレスを配信しない（DHCP・RAを喋らない）
    - NATを利用しない
    - 物理インタフェースの接続はあとまわし
        - 一度ワンライナーでやった際に誤ってRAを喋らせてしまい、おうちネットワーク内でRA汚染が起きたので
- インターフェースの数ぶん作成
    - 今回の場合、WAN用のenp2s0f0に対するlxdbr1と、LAN用のenp2s0f1に対するlxdbr2を作成する

```shell:lxdネットワーク作成
# lxc network create lxdbr1 ipv4.address=none ipv6.address=none ipv4.dhcp=false ipv6.dhcp=false ipv4.nat=false ipv6.nat=false
Network lxdbr1 created

# lxc network create lxdbr2 ipv4.address=none ipv6.address=none ipv4.dhcp=false ipv6.dhcp=false ipv4.nat=false ipv6.nat=false
Network lxdbr2 created
```

コマンド実行後、lxdbr1とlxdbr2が追加され、IPV4とIPV6がnoneとなっていることを確認する。
```shell:確認
# lxc network list
+----------+----------+---------+----------------+---------------------------+-------------+---------+---------+
|   NAME   |   TYPE   | MANAGED |      IPV4      |           IPV6            | DESCRIPTION | USED BY |  STATE  |
+----------+----------+---------+----------------+---------------------------+-------------+---------+---------+
| enp0s25  | physical | NO      |                |                           |             | 0       |         |
+----------+----------+---------+----------------+---------------------------+-------------+---------+---------+
| enp2s0f0 | physical | NO      |                |                           |             | 0       |         |
+----------+----------+---------+----------------+---------------------------+-------------+---------+---------+
| enp2s0f1 | physical | NO      |                |                           |             | 0       |         |
+----------+----------+---------+----------------+---------------------------+-------------+---------+---------+
| lxdbr0   | bridge   | YES     | 10.203.78.1/24 | fd42:bb05:c704:5b37::1/64 |             | 1       | CREATED |
+----------+----------+---------+----------------+---------------------------+-------------+---------+---------+
| lxdbr1   | bridge   | YES     | none           | none                      |             | 0       | CREATED |
+----------+----------+---------+----------------+---------------------------+-------------+---------+---------+
| lxdbr2   | bridge   | YES     | none           | none                      |             | 0       | CREATED |
+----------+----------+---------+----------------+---------------------------+-------------+---------+---------+
```

### LXD ブリッジネットワークと物理IFの紐づけ

作成したネットワークにオプションを追加し紐づけを行う。

```shell:IF紐づけ
# lxc network set lxdbr1 bridge.external_interfaces=enp2s0f0
# lxc network set lxdbr2 bridge.external_interfaces=enp2s0f1
```

:::note
このコマンドで紐づけるNICは、何もネットワーク設定が無いNICでなければならない。
何か設定が入っていると実行時に ```Error: Only unconfigured network interfaces can be bridged``` とエラーが出る。
:::

必要なオプション7つが ```config``` に入っていることを確認する。

```shell:確認
# lxc network show lxdbr1
name: lxdbr1
description: ""
type: bridge
managed: true
status: Created
config:
  bridge.external_interfaces: enp2s0f0
  ipv4.address: none
  ipv4.dhcp: "false"
  ipv4.nat: "false"
  ipv6.address: none
  ipv6.dhcp: "false"
  ipv6.nat: "false"
used_by: []
locations:
- none
```

lxdbr2も同様


### ブリッジネットワークを利用する設定のプロファイルを作成

```shell:プロファイル作成
# lxc profile create bridge_wan
Profile bridge_wan created

# lxc profile device add bridge_wan root disk path=/ pool=default
Device root added to bridge_wan

# lxc profile device add bridge_wan eth0 nic name=eth0 network=lxdbr1
Device eth0 added to bridge_wan

```

上から順に「プロファイル[bridge_wan]作成」「プロファイル[bridge_wan]にストレージ追加」「プロファイル[bridge_wan]にeth0としてlxdbr1を追加」となる。
nicの追加については、 ``` lxc network attach-profile lxdbr1 bridge_wan eth0 eth0 ``` のコマンドでもよく、むしろこちらの書式のほうが覚えやすいかもしれない。

同様に、[bridge_lan]プロファイルを作成し、nicとしてlxdbr2を設定しておく。

```shell:確認
# lxc profile show bridge_wan
name: bridge_wan
description: ""
config: {}
devices:
  eth0:
    name: eth0
    network: lxdbr1
    type: nic
  root:
    path: /
    pool: default
    type: disk
used_by: []

# lxc profile show bridge_lan
name: bridge_lan
description: ""
config: {}
devices:
  eth0:
    name: eth0
    network: lxdbr2
    type: nic
  root:
    path: /
    pool: default
    type: disk
used_by: []
```

descriptionをコマンドでつける方法がわからないので、 ``` lxc profile edit bridge_wan ``` でごまかす。

:::note info
ほかに手っ取り早い方法として、 ``` lxc profile copy default bridge_wan ``` のようにdefautプロファイルをコピーし、コピー後のプロファイルをeditでnetworkの部分を書き換える手もある。
:::

### 動作確認

各プロファイルのコンテナを作成し、割り当てられたアドレスを確認する。

```shell
# lxc launch ubuntu:noble machine1 --profile default --ephemeral
Creating machine1
Starting machine1

# lxc launch ubuntu:noble machine2 --profile bridge_wan --ephemeral
Creating machine2
Starting machine2

# lxc launch ubuntu:noble machine3 --profile bridge_lan --ephemeral
Creating machine3
Starting machine3

# lxc list -c n46P
+----------+------------------------+-----------------------------------------------+------------+
|   NAME   |          IPV4          |                     IPV6                      |  PROFILES  |
+----------+------------------------+-----------------------------------------------+------------+
| machine1 | 10.203.78.180 (eth0)   | fd42:bb05:c704:5b37:216:3eff:fe26:ea97 (eth0) | default    |
+----------+------------------------+-----------------------------------------------+------------+
| machine2 | 20x.xxx.xxx.xxx (eth0) | 2409:xxxx:xxxx:xxxx:216:3eff:ff4:90 (eth0)    | bridge_wan |
+----------+------------------------+-----------------------------------------------+------------+
| machine3 | 192.168.11.129 (eth0)  | 2409:xxxx:xxxx:xxxx:216:3eff:fec:82 (eth0)    | bridge_lan |
+----------+------------------------+-----------------------------------------------+------------+
```

見せられないところはとりあえず伏せているが
machine1: lxdbr0に設定されているレンジのアドレスが割り当てられている。
machine2: グローバルのIPv4アドレスとIPv6アドレスが割り当てられている。
machine3: LAN内で利用しているローカルIPv4アドレスとグローバルのIPv6アドレスが割り当てられている。

ついでに、各コンテナからインターネット側へpingを打って通信確認もしておく。

```shell
# lxc exec machine1 -- ping dns.google -c 4 -4
PING dns.google (8.8.8.8) 56(84) bytes of data.
64 bytes from dns.google (8.8.8.8): icmp_seq=1 ttl=116 time=8.32 ms
64 bytes from dns.google (8.8.8.8): icmp_seq=2 ttl=116 time=6.21 ms
64 bytes from dns.google (8.8.8.8): icmp_seq=3 ttl=116 time=8.44 ms
64 bytes from dns.google (8.8.8.8): icmp_seq=4 ttl=116 time=5.49 ms

# lxc exec machine1 -- ping dns.google -c 4 -6
PING dns.google (2001:4860:4860::8844) 56 data bytes
64 bytes from dns.google (2001:4860:4860::8844): icmp_seq=1 ttl=113 time=6.87 ms
64 bytes from dns.google (2001:4860:4860::8844): icmp_seq=2 ttl=113 time=4.81 ms
64 bytes from dns.google (2001:4860:4860::8844): icmp_seq=3 ttl=113 time=4.76 ms
64 bytes from dns.google (2001:4860:4860::8844): icmp_seq=4 ttl=113 time=4.55 ms

（以下省略）
```
:::note info
machine1はIPv6にULAを用いるNATネットワークであり、ULAは標準で優先度が低く、-6オプションを指定しないとIPv6で通信をしてくれない。
逆に、machine2と3はグローバルIPv6であり、IPv4よりも優先度が高いので、-4オプションを指定しないとIPv6での通信となる。
:::

IPv4/v6ともに疎通が取れている。
テスト用コンテナはephemeralを指定して作ったので止めれば消える。

```shell
# lxc stop machine1 machine2 machine3
# lxc list
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+
```

### おまけ編 ～やらなくてもいいけどとりあえずやってみた～

#### ストレージプールの追加

とりあえずHDDを積んでいるので、それを追加しておく。

https://lxd-ja.readthedocs.io/ja/latest/howto/storage_pools/

```shell:ディスクの初期化
# fdisk /dev/sda

Welcome to fdisk (util-linux 2.39.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
The size of this disk is 2.7 TiB (3000592982016 bytes). DOS partition table format cannot be used on drives for volumes larger than 2199023255040 bytes for 512-byte sectors. Use GUID partition table format (GPT).

Created a new DOS (MBR) disklabel with disk identifier 0x46db00c7.

Command (m for help): g
Created a new GPT disklabel (GUID: 1309D307-5CB5-4412-8647-794F4E39F58D).

Command (m for help): n
Partition number (1-128, default 1): 1
First sector (2048-5860533134, default 2048): 2048
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-5860533134, default 5860532223): 5860532223

Created a new partition 1 of type 'Linux filesystem' and of size 2.7 TiB.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

root@x1225:~# ls /dev/sda*
/dev/sda  /dev/sda1
```

```shell:LXDストレージの追加と結果確認
# lxc storage create pool_hdd btrfs source=/dev/sda1
Storage pool pool_hdd created

# lxc storage list
+----------+--------+--------------------------------------------+-------------+---------+---------+
|   NAME   | DRIVER |                   SOURCE                   | DESCRIPTION | USED BY |  STATE  |
+----------+--------+--------------------------------------------+-------------+---------+---------+
| default  | btrfs  | /var/snap/lxd/common/lxd/disks/default.img |             | 4       | CREATED |
+----------+--------+--------------------------------------------+-------------+---------+---------+
| pool_hdd | btrfs  | 0aea9e0e-d976-4579-944b-d9a88d08a417       |             | 0       | CREATED |
+----------+--------+--------------------------------------------+-------------+---------+---------+
```

これで速度は要らないけど容量が欲しい時に、HDDへ投げることができる。使う機会あるか知らんけど。

#### WindowsからLXDのリモート操作をできるように設定

今回、インストールしたのがUbuntu ServerでGUI環境を持っていない。
そのためコンテナではなく仮想マシンを動かす場合に画面表示をしようとするとリモート操作を行う必要がある。

ブラウザでやる方法は以下の通りにやれば問題ない。

https://gihyo.jp/admin/serial/01/ubuntu-recipe/0769

ここに記載するのはWindows版のlxcコマンドと、Virt Viewerを利用した方法である。

https://lxd-ja.readthedocs.io/ja/latest/howto/server_expose/

- [lxcコマンドの実行ファイルを入手](https://github.com/canonical/lxd/releases)し、展開・パスを通す
- Virt Viewerをインストールする
    - [公式サイトからインストーラをダウンロード](https://virt-manager.org/download.html)してもよいし、Wingetでインストールもできる
- サーバ側でトークンを発行し、コピーしておく
```shell:トークン発行
# lxc config trust add --name [CLIENT_NAME]
Client [名前] certificate add token:
44G+44GC56K644GL44Gr44GE44Gh44GE44Gh44Ko44Oz44Kz44O844OJ44GL44G+44GX44Gm5rqW5YKZ44GZ44KL5pa544KC5rqW5YKZ44GZ44KL5pa544Gg44GR44Gp44CB44KP44GW44KP44GW44Gn44Kz44O844OJ44GX44Gm6Kqt44G+44Gq44GP44Gm44KC44GE44GE44Gn44GX44KH44GG44Gr44G744KT44Go44Gr44KC44GG44O744O744O7
```
- Windows側でlxcコマンドを利用してremote追加を行う
```shell:remote追加（Windows）
>lxc remote add [SERVER_ADDRESS]
Certificate fingerprint: [HASH]
ok (y/n/[fingerprint])? y
Admin password (or token) for [SERVER_ADDRESS]:
※コピーしておいたトークンを張り付けてエンター※

Client certificate now trusted by server: [SERVER_ADDRESS]
```
- 結果確認
```shell:確認（Windows）
>lxc remote list
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
|         NAME         |                        URL                        |   PROTOCOL    |  AUTH TYPE  | PUBLIC | STATIC | GLOBAL |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
| [SERVER_ADDRESS]     | https://[SERVER_ADDRESS]:8443                     | lxd           | tls         | NO     | NO     | NO     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
| images               | https://images.lxd.canonical.com                  | simplestreams | none        | YES    | NO     | NO     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
| local (current)      | unix://                                           | lxd           | file access | NO     | YES    | NO     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu               | https://cloud-images.ubuntu.com/releases          | simplestreams | none        | YES    | YES    | NO     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu-daily         | https://cloud-images.ubuntu.com/daily             | simplestreams | none        | YES    | YES    | NO     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu-minimal       | https://cloud-images.ubuntu.com/minimal/releases/ | simplestreams | none        | YES    | YES    | NO     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu-minimal-daily | https://cloud-images.ubuntu.com/minimal/daily/    | simplestreams | none        | YES    | YES    | NO     |
+----------------------+---------------------------------------------------+---------------+-------------+--------+--------+--------+
```

```shell:確認（サーバ）
# lxc config trust list
+--------+---------------+--------------------------------------+---------------+------------------------------+------------------------------+
|  TYPE  | NAME          |             COMMON NAME              |  FINGERPRINT  |          ISSUE DATE          |         EXPIRY DATE          |
+--------+---------------+--------------------------------------+---------------+------------------------------+------------------------------+
| client | [CLIENT_NAME] |[CLIEN_NAME]/[USER_NAME]@[CLIENT_NAME]| [FINGERPRINT] | May 12, 2024 at 4:12pm (UTC) | May 10, 2034 at 4:12pm (UTC) |
+--------+---------------+--------------------------------------+---------------+------------------------------+------------------------------+
```
- 操作対象切り替え
    - 以下のコマンドを実行することで、操作対象がリモートサーバに切り替わる
    - 切り替わったかどうかの確認は ```  (current) ``` がついているかで判別
```shell:動作確認（Windows）
>lxc remote switch [SERVER_ADDRESS]
```

- テスト用仮想マシンの作成
    - サーバ側で仮想マシンを作る
    - 以下のコマンドは空っぽのマシン
    - 時間と帯域に余裕があれば、何かデスクトップ向けマシンを入れてもいい
```shell:空の仮想マシン作成
# lxc init vmachine --empty --vm
Creating vmachine
```

- Windows側で仮想マシンの確認と起動、画面接続
    - 正常に設定ができており、仮想マシンが起動すればvirtviewerが立ち上がる
    - 空のマシンなのでEFIで止まる
    - 画面表示を確認したらアプリは終了してかまわない
```shell
>lxc list
+----------+---------+------+------+-----------------+-----------+
|   NAME   |  STATE  | IPV4 | IPV6 |      TYPE       | SNAPSHOTS |
+----------+---------+------+------+-----------------+-----------+
| vmachine | STOPPED |      |      | VIRTUAL-MACHINE | 0         |
+----------+---------+------+------+-----------------+-----------+

>lxc start vmachine --console=vga

(remote-viewer.exe:24204): GSpice-CRITICAL **: 00:28:56.711: _usbdk_hider_update: assertion 'priv->usbdk_api != NULL' failed

（以下、ログが流れる）
```
![virtview_win.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143797/56c57f62-2245-14aa-3840-1d8a9deca198.png)

- 仮想マシンの停止と削除
    - サーバ側、Windows側どちらでやってもいい
    - 正常に起動していない場合、通常停止だと詰まることが体感多いので強制削除
```shell
lxc delete vmachine --force
```

## Factorio Headressサーバの構築

Linux GSMを利用することで面倒なアップデートや自動起動をお任せしたい。

### 下準備

これから構築するUbuntuコンテナのcloud-initの設定を作っておく。
内容は以下の通りで、ほかで使いまわせるよう汎用的な感じに。Factorioの構築に特化したものは手動で。


- タイムゾーンをAsia/Tokyoに設定
- ロケールは英語
- aptのリポジトリを日本のミラーに設定
- 追加でインストールするパッケージを指定
    - どちらもVM用で書いており、コンテナなら要らないと思う
    - ほか必要なパッケージはLinuxGSMに任せ、ここでは記述しない
- 初回にaptのupdate, upgradeを行い、再起動が必要であれば再起動する
    - upgradeの完了と再起動のタイミングが読めない場合もあるので、これらは無効として手動でやってもいい
- ユーザー「fctrserver」を追加
- パスワードログインを無効化
- SSH鍵を記述

```yaml:factorio-init.yaml
#cloud-config
timezone: Asia/Tokyo
locale: en_US.utf8

apt:
  primary:
    - arches: default
      uri: http://jp.archive.ubuntu.com/ubuntu
  security:
    - arches: default
      uri: http://security.ubuntu.com/ubuntu
  #proxy: http://xxxxxxx:3142/

packages:
  - apt:
    - qemu-guest-agent
    - spice-vdagent
package_update: true
package_upgrade: true
package_reboot_if_required: true

users:
- name: fctrserver
  gecos: Factorio
  groups: users, admin
  #sudo: ALL=(ALL) NOPASSWD:ALL
  shell: /bin/bash
  lock_passwd: true
  passwd: $6$THISISSALT$prmsbx3r15NGXhHY7wshZksSVtVjhnk0YcxkSCYo2gzuj.4TC/bZxxMf3dpKwxuFTI1eXJqc7ZKDShsy/Da1S1
  ssh_authorized_keys:
    - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```
ついでにIPを固定するためにnetplanも用意しておく。factorioのためだけならば別に固定必須でもなく省略してもいい。これを当てない場合はDHCPで割り当たる。

```yaml:netplan.yaml
network:
    ethernets:
        eth0:
            addresses:
            - 192.168.11.50/24
            ipv6-address-token: '::192:168:11:50'
            nameservers:
                addresses:
                - 2001:4860:4860::8888
                - 2001:4860:4860::8844
                - 8.8.8.8
                - 8.8.4.4
                search: []
            routes:
            -   to: default
                via: 192.168.11.254
    version: 2
```

コンテナを作成し、二つの設定ファイルを食わせる。ワンライナーは面倒なのでコマンドを分けている。

Ubuntu 24.04でfactorioの名前のコンテナとし、プロファイルはbridge_lanを指定。
コンテナ作成後、cloud-initの設定を食わせてから起動。

```shell:コンテナ作成
$ lxc init ubuntu:noble factorio --profile bridge_lan
Creating factorio

$ lxc config set factorio cloud-init.user-data - < factorio-init.yaml

$ lxc config set factorio cloud-init.network-config - < netplan.yaml

$ lxc start factorio
$ lxc list
+----------+---------+----------------------+-----------------------------------------------+-----------+-----------+
|   NAME   |  STATE  |         IPV4         |                     IPV6                      |   TYPE    | SNAPSHOTS |
+----------+---------+----------------------+-----------------------------------------------+-----------+-----------+
| factorio | RUNNING | 192.168.11.50 (eth0) | 2409:xxxx:xxxx:xxxx:216:3eff:febb:5675 (eth0) | CONTAINER | 0         |
|          |         |                      | 2409:xxxx:xxxx:xxxx:192:168:11:50 (eth0)      |           |           |
+----------+---------+----------------------+-----------------------------------------------+-----------+-----------+
```

コンテナが起動しSTATE RUNNINGとなり、設定したIPアドレスとなっていることを確認する。

### Linux GSMの導入

手順はほぼ以下に記載のとおり。

https://linuxgsm.com/servers/fctrserver/

作成したコンテナにfctrserverユーザーで入る。
ホストや連携した他PCから入る場合は以下の通り。SSHで入ってもいい。

```shell
$ lxc shell factorio
root@factorio:~# su - fctrserver
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

fctrserver@factorio:~$
```
:::note info
パッケージアップグレードを自動化していない場合はここでやっておく。
fctrserverアカウントのパスワードを設定していない場合はここでやっておく。
:::

途中でi386パッケージのインストールを求められるので以下のコマンドにてアーキテクチャを追加しておく。

https://developer.valvesoftware.com/wiki/SteamCMD#Ubuntu

```shell
$ sudo dpkg --add-architecture i386
[sudo] password for fctrserver:

$ dpkg --print-foreign-architectures
i386
```

Linux GSMを落とし、Factorioのインストールを行う。

:::note info
一行目のコマンド群末尾にある ``` linuxgsm.sh fctrserver ``` を ``` linuxgsm.sh install ``` や ``` linuxgsm.sh list ``` とすれば、ほかのゲームを閲覧・選択することができる。
[こっち見た方が早いけど](https://linuxgsm.com/servers/)
:::

:::note warn
インストール時点で最新のバージョンが降ってくる。
過去のビルドとしたい場合など、インストールさせるゲームバージョンを指定する場合は、 ``` ./fctrserver install ``` の前に以下の作業を行う
- ``` ./fctrserver update-lgsm ``` を行い、 ``` lgsm/config-lgsm/fctrserver/_default.cfg ``` を生成させる
- ``` _default.cfg ``` を ``` fctrserver.cfg ``` にコピーする
- ``` fctrserver.cfg ``` を編集し、 ``` branch ``` にstable, experimental[またはバージョン番号を入れる](https://docs.linuxgsm.com/game-servers/factorio)
- ``` ./fctrserver install ``` 以降を行う
:::

```shell
$ curl -Lo linuxgsm.sh https://linuxgsm.sh && chmod +x linuxgsm.sh && bash linuxgsm.sh fctrserver
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   167  100   167    0     0   2051      0 --:--:-- --:--:-- --:--:--  2061
100 18430  100 18430    0     0   126k      0 --:--:-- --:--:-- --:--:--  126k
Installed Factorio server as fctrserver

./fctrserver install

$ ./fctrserver install
（中略）
=================================
LinuxGSM_
by Daniel Gibbs
Version: v24.3.2
Game: Factorio
Website: https://linuxgsm.com
Contributors: https://linuxgsm.com/contrib
Sponsor: https://linuxgsm.com/sponsor
=================================
fetching GitHub install_server_dir.sh...OK

Server Directory
=================================
/home/fctrserver
Continue? [Y/n] Y

mkdir: created directory '/home/fctrserver/serverfiles'
fetching GitHub install_logs.sh...OK

Creating Log Directories
=================================
installing log dir: /home/fctrserver/log...OK
installing LinuxGSM log dir: /home/fctrserver/log/script...OK
creating LinuxGSM log: /home/fctrserver/log/script/fctrserver-script.log...OK
installing console log dir: /home/fctrserver/log/console...OK
creating console log: /home/fctrserver/log/console/fctrserver-console.log...OK
creating symlink to game log dir: /home/fctrserver/log/server -> /home/fctrserver/serverfiles...OK
fetching GitHub check_deps.sh...OK

Checking Factorio Dependencies
=================================
fetching GitHub ubuntu-24.04.csv...OK
bc
binutils
bsdmainutils
bzip2
ca-certificates
cpio
curl
distro-info
file
gzip
hostname
jq
lib32gcc-s1
lib32stdc++6
netcat-openbsd
pigz
python3
tar
tmux
unzip
util-linux
uuid-runtime
wget
xz-utils
Warning! Missing dependencies: binutils bsdmainutils bzip2 lib32gcc-s1 lib32stdc++6 libsdl2-2.0-0:i386 pigz unzip
```

ここで、先にアーキテクチャの追加でsudoをやっていてパスワード入力していれば勝手に進むが、そうでない場合はsudoのためにパスワードを聞いてくる。 ``` ALL=(ALL) NOPASSWD:ALL ``` を設定していても聞いてくる。要らないものも混じっている気がするけど。気になる場合は不足パッケージを手動で入れてからLinuxGSMとFactorioのインストールをすればいい。


インストールが成功したかどうかを聞いてくるが、正直そんなもんスクリプト側で判断するよう作れと突っ込みたいが、とりあえずYを押して進める。
その後、LinuxGSMの開発元に情報を共有するか聞いてくるがお好みでNを入れて進める。

```shell
（中略）
   2.134 Goodbye

=================================
Was the install successful? [Y/n] Y

（中略）

LinuxGSM Stats
=================================
Assist LinuxGSM development by sending anonymous stats to developers.
Collected data is publicly available: https://linuxgsm.com/data/usage
More info: https://docs.linuxgsm.com/configuration/linuxgsm-stats
The following info will be sent:
* game server
* distro
* game server resource usage
* server hardware info
Allow anonymous usage statistics? [Y/n] N

fetching GitHub install_complete.sh...OK

=================================
Install Complete!

To start server type:
./fctrserver start
```

これでLinuxGSMとFactorioのインストールが完了となる。

### Factorioのテスト起動

とりあえず起動してみる

```shell
$ ./fctrserver start
fetching GitHub linuxgsm.sh...OK
fetching GitHub command_start.sh...OK
[ .... ] Starting fctrserver: fetching GitHub check_root.sh...OK
fetching GitHub check_system_dir.sh...OK
fetching GitHub check_executable.sh...OK
fetching GitHub check_logs.sh...OK
fetching GitHub check_config.sh...OK
[ WARN ] Starting fctrserver: Default RCON password detected
fetching GitHub check_status.sh...OK
fetching GitHub core_logs.sh...OK
[  OK  ] Starting fctrserver: Name of the game as it will appear in the game listing
```

ここで、RCONのパスワードが初期値であると警告が出る。後で変えるので気にしない。とりあえず現時点ではLAN内からしかアクセスできないのでセキュリティリスクはあんまり無いはず。

サーバのステータスを確認する。

```bash
$ ./fctrserver details

Distro Details
================================================================================================================================================================
Date:         Sat Nov 23 07:06:49 PM JST 2024
Distro:       Ubuntu 24.04.1 LTS
Arch:         x86_64
Kernel:       6.8.0-49-generic
Hostname:     factorio
Environment:  lxc
Uptime:       0d, 0h, 13m
tmux:         3.4
glibc:        2.39

Server Resource
================================================================================================================================================================
CPU
Model:      Intel(R) Xeon(R) CPU E3-1225 v3 @ 3.20GHz
Cores:      8
Frequency:  2400.000MHz
Avg Load:   0.09, 0.05, 0.07

Memory
Mem:       total  used   free  cached  available
Physical:  32GB   417MB  31GB  1.6GB   31GB
Swap:      0B     0B     0B

Storage
Filesystem:  /dev/loop4
Total:       250G
Used:        2.2G
Available:   247G

Network
IP:           0.0.0.0
Internet IP:  2409:XXXX:XXXX:XXXX:192:168:11:50

Factorio Resource Usage
================================================================================================================================================================
CPU Used:  0%
Mem Used:  1%  333MB

Storage
Total:        367M
Serverfiles:  366M

Factorio Server Details
================================================================================================================================================================
Server name:        Name of the game as it will appear in the game listing
Branch:             stable
Server IP:          0.0.0.0:34197
Internet IP:        2409:XXXX:XXXX:XXXX:192:168:11:50:34197
Server password:    NOT SET
RCON password:      CHANGE_ME
Maxplayers:         0
Server Version:     2.0.20
Auth Token:         NOT SET
Savegame Interval:  10
Version Count:      5
Status:             STARTED

fctrserver Script Details
================================================================================================================================================================
Script name:       fctrserver
LinuxGSM version:  v24.3.2
glibc required:    2.18
Discord alert:     off
Email alert:       off
Gotify alert:      off
IFTTT alert:       off
Pushbullet alert:  off
Pushover alert:    off
Rocketchat alert:  off
Slack alert:       off
Telegram alert:    off
Update on start:   off
User:              fctrserver
Location:          /home/fctrserver
Config file:       /home/fctrserver/serverfiles/data/fctrserver.json

Backups
================================================================================================================================================================
No Backups created

Command-line Parameters
================================================================================================================================================================
 ./factorio --bind 0.0.0.0 --start-server /home/fctrserver/serverfiles/save1.zip --server-settings /home/fctrserver/serverfiles/data/fctrserver.json --port 34197 --rcon-port 34198 --rcon-password CHANGE_ME

Ports
================================================================================================================================================================
Change ports by editing the parameters in:
/home/fctrserver/lgsm/config-lgsm/fctrserver

Useful port diagnostic command:
ss -tuplwn | grep factorio

DESCRIPTION  PORT   PROTOCOL  LISTEN
Game         34197  udp       2
RCON         34198  tcp       1

Status: STARTED
```

最後の行が「Status: STARTED」となっていれば起動している。

ゲームをプレイするPCのFactorioを起動し、マルチプレイ → LANゲームを見る を選択する。
ぽつんとデフォルト名である「Name of the game as it will appear in the game listing」が出てくる。
![factorio_LAN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143797/5bfdd581-184b-f15b-040e-52aa4284f500.png)

いったん、Factorioを終了させFactorioサーバも終了させる。

```shell
$ ./fctrserver stop
fetching GitHub command_stop.sh...OK
[ WARN ] Stopping fctrserver: Default RCON password detected
[  OK  ] Stopping fctrserver: Graceful: CTRL+c: 2: OK
```

### Factorioサーバーの設定変更

https://docs.linuxgsm.com/game-servers/factorio

#### 起動オプション

先ほど表示させたdetailsにあるサーバ起動コマンドの引数として、今回の例においてはFactorioの設定ファイルは ``` /home/fctrserver/serverfiles/data/fctrserver.json ``` で、セーブファイルは ``` /home/fctrserver/serverfiles/save1.zip ``` を利用している。

起動コマンドに先ほど怒られたRCONのパスワードも平文で入っている。CHANGE_MEと。
まず、この起動コマンドのRCONパスワードを変更する。

この設定は ``` /home/fctrserver/lgsm/config-lgsm/fctrserver ``` にある ``` _default.cfg ``` へ初期値が書き込まれているが、ファイルの冒頭に記述されているようにLinuxGSMのアップデート等によりこのファイル自体は書き戻されるものとなっている。

まず、 ``` _default.cfg ``` で同じディレクトリにある ``` fctrserver.cfg ``` を上書きする。このファイルが注釈にある ``` [instance].cfg ``` である。

```shell
$ cp /home/fctrserver/lgsm/config-lgsm/fctrserver/_default.cfg /home/fctrserver/lgsm/config-lgsm/fctrserver/fctrserver.cfg
```

そして ``` fctrserver.cfg ``` を編集する。ざっくり以下の点。

- 冒頭の注釈は不要なので消す
- RCONを使うのであれば ``` rconport ``` と ``` rconpassword ``` を適宜変更する
    - 使わないのであれば ``` rconpassword ``` を変更したうえで、 さらに ``` startparameters ``` からRCONのオプションを削っておく
- もし、セーブファイルの名前を変えておきたいのであれば、 ``` startparameters ``` を変更しておく
- ``` branch ``` はstable, experimentalのほか、バージョン番号を入れることでバージョンの固定ができる
    - 過去バージョンにするときは、新規で構築しなおして前述の注釈通りにやるか、 ``` serverfiles ``` ディレクトリを消してから ``` ./fctrserver install ``` とやった方がいいかもしれない
        - 特にダウングレードさせると何が起こるかわからない、こわい
- 他、 ``` startparameters ``` については以下に記述がある
    - https://wiki.factorio.com/Command_line_parameters
    - サーバ管理者を指定する時、BANリスト指定、許可リストを指定する場合などに使う

:::note info
起動時の警告は ``` rconpassword ``` の変数だけを見て出してくるので、オプションから削ったとしても変えておかないと警告が残る
:::

#### Factorio ゲームサーバ設定

初期設定は同一ディレクトリに ``` server-settings.example.json ``` で保存されているため、直接 ``` /home/fctrserver/serverfiles/data/fctrserver.json ``` を弄っていい。

とりあえず、触るのは以下あたりか。

- name
    - サーバーの名前、ゲーム内でサーバー一覧に出ていたアレ
- description
    - サーバーの概要、公開する時に適宜つければいい
- tags
    - [乱用はおやめください](https://factorio.com/blog/post/fff-304)
- max_players
    - デフォルト値の0だと無制限なので公開時に注意
- visibility, username, password, token
    - サーバーを一覧に表示するかの設定と、公開サーバーに表示する際のfactorio.com認証情報
    - この記事では詳細を取り扱わないが、factorio.comにいってログインしてトークンをコピペ、それだとパスワード要らずで安全なはず
- game_password
    - 立てたサーバーのゲームへ参加する際に必要となるパスワード
    - 参加者共通
    - 一人ぼっちサーバなら設定するとかえって邪魔
- autosave_interval, autosave_slots
    - サーバー側での自動セーブ間隔（分）、自動セーブ数
    - これを含め、セーブ系は基本としてサーバー側で行われるのでサーバーのスペックにより調整
- auto_pause
    - プレイヤーがいなくなったときにポーズを掛けるか
    - ``` false ``` とすることで、だれもいなくても世界は動く、バイターも動く

設定を変えたら、サーバーを起動し変更が反映されているか確認する。

```
$ ./fctrserver st
[  OK  ] Starting fctrserver: 俺俺、俺だよ母ちゃん俺だっつーのサーバー

$ ./fctrserver dt

Distro Details
================================================================================================================================================================
Date:         Sat Nov 23 08:01:49 PM JST 2024
Distro:       Ubuntu 24.04.1 LTS
Arch:         x86_64
Kernel:       6.8.0-49-generic
Hostname:     factorio
Environment:  lxc
Uptime:       0d, 1h, 8m
tmux:         3.4
glibc:        2.39

Server Resource
================================================================================================================================================================
CPU
Model:      Intel(R) Xeon(R) CPU E3-1225 v3 @ 3.20GHz
Cores:      8
Frequency:  2798.882MHz
Avg Load:   0.02, 0.01, 0.00

Memory
Mem:       total  used   free  cached  available
Physical:  32GB   437MB  31GB  1.6GB   31GB
Swap:      0B     0B     0B

Storage
Filesystem:  /dev/loop4
Total:       250G
Used:        2.2G
Available:   247G

Network
IP:           0.0.0.0
Internet IP:  2409:XXXX:XXXX:XXXX:192:168:11:50

Factorio Resource Usage
================================================================================================================================================================
CPU Used:  0%
Mem Used:  1.1%  353MB

Storage
Total:        367M
Serverfiles:  366M

Factorio Server Details
================================================================================================================================================================
Server name:        俺俺、俺だよ母ちゃん俺だっつーのサーバー
Branch:             stable
Server IP:          0.0.0.0:34197
Internet IP:        2409:XXXX:XXXX:XXXX:192:168:11:50:34197
Server password:    0000
RCON password:      ab19f8f9-c547-453c-96f7-4f7865c11b44
Maxplayers:         0
Server Version:     2.0.20
Auth Token:         NOT SET
Savegame Interval:  10
Version Count:      5
Status:             STARTED

fctrserver Script Details
================================================================================================================================================================
Script name:       fctrserver
LinuxGSM version:  v24.3.2
glibc required:    2.18
Discord alert:     off
Email alert:       off
Gotify alert:      off
IFTTT alert:       off
Pushbullet alert:  off
Pushover alert:    off
Rocketchat alert:  off
Slack alert:       off
Telegram alert:    off
Update on start:   off
User:              fctrserver
Location:          /home/fctrserver
Config file:       /home/fctrserver/serverfiles/data/fctrserver.json

Backups
================================================================================================================================================================
No Backups created

Command-line Parameters
================================================================================================================================================================
 ./factorio --bind 0.0.0.0 --start-server /home/fctrserver/serverfiles/save1.zip --server-settings /home/fctrserver/serverfiles/data/fctrserver.json --port 34197

Ports
================================================================================================================================================================
Change ports by editing the parameters in:
/home/fctrserver/lgsm/config-lgsm/fctrserver

Useful port diagnostic command:
ss -tuplwn | grep factorio

DESCRIPTION  PORT   PROTOCOL  LISTEN
Game         34197  udp       2
RCON         34198  tcp       0

Status: STARTED
```

:::note info
RCONを無効にできているかの確認は、details後部のRCONポートのLISTENが0であることで良しとすればいいのか
:::

![factorio_LAN2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143797/a932a453-44e6-d145-e98d-a5d50717f075.png)

### ゲームサーバーの自動起動と自動アップデートの設定

https://docs.linuxgsm.com/configuration/running-on-boot

Linux GSMを用いることで、Factorioアップデートが ``` ./fctrserver update ``` のコマンド一発でできる。
systemdに登録するよりも、crontabを設定する方が素直で楽。たぶん。

```shell
$ crontab -e
@reboot /home/fctrserver/fctrserver start > /dev/null 2>&1
*/5 * * * * /home/fctrserver/fctrserver monitor > /dev/null 2>&1
*/30 * * * * /home/fctrserver/fctrserver update > /dev/null 2>&1
0 0 * * 0 /home/fctrserver/fctrserver update-lgsm > /dev/null 2>&1
```

起動時にFactorioゲームサーバーを起動
5分ごとにゲームサーバーの死活確認をして、死んでたら起こしてみる
30分ごとにFactorioのアップデートチェックをしてアップデートがあれば上げる
1日ごとにLinuxGSMのアップデートチェックをしてアップデートがあれば上げる、だったっけか。

なお、 ``` @reboot ``` での自動起動は無くてもいい気がする。
``` ./fctrserver start ``` コマンドを打ったかどうかを内部で保持しており、もしゲームサーバー実行中にOS再起動を掛けたとしても、再起動後最初のmonitorコマンドでゲームサーバーが起きてくる。逆にstopで止めているときにOS再起動しても起きてくることがない。

### ワールドデータの作成について

セーブデータが無い状態でゲームサーバーを起動すると、サーバー内の設定に従って新規ゲームを作成する。
この設定を書き換えて思い通りのゲームを開始するのもいいけど、もうちょっと難易度を下げてやりたかったり、MODを導入するのであれば以下の手順がたぶん楽。
同じやり方で、シングルプレイで進行中のゲームをサーバーへ移植もできる。

:::note warn
この作業をやる時はかならずゲームサーバーを停止していることを確認してからやらないと、無駄に時間を食う。食った。
:::

- ゲームをプレイするPCでシングルゲームを作成する
    - 必要なMODをインストールした状態で、マップオプションやMOD設定も一通りそこで済ませる
- 作成完了し、墜落船の横に立ったら即セーブ
- そのセーブデータで、サーバ上にある ``` /home/fctrserver/serverfiles/save1.zip ``` を置き換える
    - Windowsの場合はたぶん ``` %APPDATA%\Factorio\saves ``` にある
- PCのmodsフォルダの中身をサーバー上のmodsフォルダにコピーする
    - Windowsの場合はたぶん ``` %APPDATA%\Factorio\mods ``` にいる
    - サーバーは ``` /home/fctrserver/serverfiles/mods ``` になる
- ゲームサーバーを起動し、ゲームに参加する

## バックアップ

- ホストのUbuntu環境ごと丸ごとバックアップ
    - 楽だけど面倒なので省略
    - 要するにClonezillaとかでがばっと
- ホストのLXD環境をバックアップ
    - [公式サイト](https://lxd-ja.readthedocs.io/ja/latest/backup/)
- 作成したコンテナをスナップショット
    - ``` lxc snapshot ``` で取り、 ``` lxc restore ``` で書き戻せる
    - 取ったスナップショットは ``` lxc export ``` でファイル化可能
    - スナップショットについては[公式サイトに記載あり](https://lxd-ja.readthedocs.io/ja/latest/howto/instances_snapshots/)
    - 新環境にインポートする際は、同名のプロファイルが必要
- Linux GSMのバックアップ機能
    - ``` ./fctrserver backup ``` で、ゲームサーバディレクトリをバックアップできる
    - ファイルは ``` ./lgsm/backup ``` ディレクトリに保存される
    - これを展開した後、 ``` ./fctrserver install ``` からの手順で
        - 新環境での依存パッケージ自動インストール目的
    - 設定や自動化については[公式サイトに記載あり](https://docs.linuxgsm.com/commands/backup)
    - cronによるスケジュール設定はもちろんやり直さなければいけない
- セーブデータだけ
    - 最低限、セーブファイルのバックアップだけ取っておけば何とかなる
    - Factorioの管理者に自身を設定しておいたり、設定ファイルでローカルセーブを許可しておけば、プレイしているPCにセーブを作ることができるので、手動でやるのも一つの手