LarkboxにAlpine Linuxを入れて自宅サーバにした

# はじめに

<a href="https://www.indiegogo.com/">INDIGOGO</a>のクラウドファンディングで<a href="https://www.chuwi.com/jp/product/items/Chuwi-LarkBox.html">CHUWI LarkBox</a>を入手。筐体サイズ：61x61x43(H)mm、重量：127ｇの極小サイズPC。Windows10 Homeがプリインストールされている。スペックは以下。

|Device|Spec|
|:--|:--|
|CPU|Intel Celeron J4115|
|RAM|6GB LPDDR4|
|ストレージ|128GB eMMC|
|Wi-Fi|802.11a/ac/b/g/n|
|Bluetooth|5.1|

ほかに、2242サイズのSATA SSDスロットがあり、2TBまで増設可。
2万円程度の価格で通販サイトで売っている。クラウドファンディングの投資額は1万6000円程度だったので少しお得。

LarkBoxと似たコンセプトの極小PCは、Amazonで「NUC」で検索すると山のように出てくる。クラウドファンディングでお安く入手したいなら、2020/9の時点では、<a href="https://www.indiegogo.com/projects/gmk-nucbox-most-powerful-palm-sized-4k-mini-pc/x/23959314#/">INDIGOGOでGMK NucBoxを公募</a>しているので応募してみてはいかがか。

LarkBoxは、Windows PCとして使用するにはしょぼいスペックなので、<a href="https://alpinelinux.org/">Alpine Linux</a>を入れて自宅サーバとして使う。
TDP 10Wなので、発熱も消費電力も極小でサーバ向きだと思う。ただ、有線LANポートが無いので、サーバとしては致命的ではあるが。。。
巷では、ラズパイ4を自宅サーバにしている方もおられるようで、ラズパイ4は有線LANポートはあるものの、CPUが非力で、ファイルサーバ程度ならいいのでしょうが、さすがにWebアプリをガンガン動かすのは無理と思えます。LarkBoxだとどの程度までできるのかは確認したいところです。

本記事は、LarkBoxにAlpine Linuxを入れた手順の備忘録です。

あまり物欲をそそるショットではないけれど写真上げときます。単3乾電池4本と同程度のフットプリント。

![larkbox.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483341/350e33fa-55be-9c34-b48a-d7efff41ab15.jpeg)

# Larkboxのセットアップ

自宅サーバでは、Macのバックアップ用のTimeCapsuleも稼働させたいので、ストレージ128GBでは不足。
そこで、1TB M2.SSDを増設する。裏蓋を開けて、スロットに挿したらおしまいだが。
筐体は放熱性能が低そうな樹脂製で、樹脂製の裏蓋を開けるとさらに樹脂製の中蓋があり、その中に基盤がある構造。SSDは中蓋と裏蓋の間の全く空気が流れない狭い空間に閉じ込められることになり、放熱がかなり不安だ。

BIOSへの入り方は、電源ボタンを押下後、エスケープキーを連打する。

# Alpine Linuxのインストール

<a href="https://alpinelinux.org/downloads/">Alpine Linuxのサイト</a>からEXTENDEDパッケージをダウンロードし、インストールする。はじめは、STANDARDパッケージをインストールしようとしたのだけど、STANDARDパッケージは最小限すぎてpingすら入っていない状態であまりにも使いにくい。Alpine Linuxに対して、128GBのストレージはあまりにも広大なので、ここはEXTENDEDパッケージのほうがいいと思う。

ダウンロードしたISOファイルalpine-extended-3.12.0-x86_64.isoをUSBメモリに焼いて、そこからブートする。
rootでログインする。（rootのパスワードは無し）

~~~
# setup-alpine
~~~

によりインストールを開始する。Alpine Linuxのインストーラは、メジャーなデストリビューションのインストーラのようにいけてない。１つ１つ対話的に設問に応答していく必要がある。

eMMCにはWindows Homeがプリインストールされていたが、迷わず削除。ここにルートとswapを置き、SSD1TBに/var(250GB)と /home(750GB)を置くことにする。直接インストールするのはdockerだけで、必要なアプリはdocker-composeでインストールするように考えている。そのため、dockerが使う/varは大き目に確保する。
ルートは遅いeMMCではなく、SSDに入れるべきという考えもあると思う。当方もそう思いやってはみたもののあまり変わらなかったので、eMMCがルートで大丈夫だと思う。

インストール時の応答は以下。

~~~
Select keyboard layout: jp
Available variants: jp
Enter system hostname: larkbox
Which one do you want to initialize?: wlan0
Type the wireless network name to connect to: *******
Type the "*******" network Pre-Shared Key: *******
Ip address for wlan0: 192.168.1.xx
Netmask?: 255.255.255.0
Gateway: 192.168.1.1
DNS domain name?
DNS nameserver(s)?: 192.168.1.1
New password: *******
Retype Password: *******
Which timezone are you in?: Asia/Tokyo
TP/FTP proxy URL?: none
Enter mirror number (1-43) or URL to add: f
Which SSH server? (‘openssh’, ‘dropbear’ or ‘none’): openssh
Which NTP client to run? (‘busybox’, ‘openntpd’, ‘chrony’, or ‘none’):chrony
Which disk(s) would you like to use?: mmcblk0
How would you like to use it?: sys 
~~~

インストールには、以下の記事を参考にした。
https://qiita.com/mo_chiee/items/f539df1bd172f41bc85a
Alpine Linux 3.10.3インストール手順

https://qiita.com/tohka383/items/e7d758a6281fa45e5e16
Docker on Alpine Linux on VirtualBox

インストールの全設問に応答したら、パッケージのリポジトリを更新しておく。

/etc/apk/repositoriesを以下のように修正

~~~conf
#/media/cdrom/apks
http://sjc.edge.kernel.org/alpine/v3.12/main
#http://sjc.edge.kernel.org/alpine/v3.12/community
#http://sjc.edge.kernel.org/alpine/edge/main
http://sjc.edge.kernel.org/alpine/edge/community
#http://sjc.edge.kernel.org/alpine/edge/testing
~~~

次のコマンドで更新。

~~~
# apk update
# apk upgrade
~~~

## Dockerを入れる

~~~
# apk add docker docker-compose
# service docker start
# rc-update add docker boot
~~~


## sudo の許可

~~~
# apk add sudo
~~~

~~~
# visudo
~~~

~~~
# %wheel ALL=(ALL) ALL
~~~
を

~~~
%wheel ALL=(ALL) ALL
~~~
に変更


## 自分のログインアカウントの追加

~~~
# addgroup wheel
# adduser 自分のログインアカウント
# adduser  自分のログインアカウント wheel
# adduser ログインアカウント docker
~~~


一旦電源OFF

~~~
# poweroff
~~~

shutdownじゃないんだね。

USBメモリを抜いてeMMCからブートするようにBIOSの設定を変更。
ブートすると、あらら、ネットワークがつながっていない！
インストール直後に設定の永続化をしなければならなかったのか？

# インストールの続き

## ネットワーク設定

最初の一連のインストールは setup-alpine スクリプトで行ったが、個別の項目だけインストールする setup-xxxx スクリプトが用意されている。
インストールスクリプトのうち、ネットワークの設定部分は

~~~
# setup-interfaces
~~~

により再度Wifiに接続する。

~~~
Which one do you want to initialize?: wlan0
Type the wireless network name to connect to: *******
Type the "*******" network Pre-Shared Key: *******
Ip address for wlan0: 192.168.1.xx
Netmask?: 255.255.255.0
Gateway: 192.168.1.1
~~~

今度は忘れずに、接続を永続化しておく。

~~~
# rc-update add wpa_supplicant boot
~~~

## ディスクの設定

初期のインストールでは、eMMCにルートとswapのパーティションを切り、システムをインストールしたが、増設した1TB SSDは手つかずのまま。そこで、次に1TB SSDを有効化する。

~~~
# setup-disk
~~~

SSD1TBに/var(250GB)と /home(750GB)を置くように設定したいのだが、setup-diskスクリプトでは、１つのパーティションしか切れないようだ。

~~~
Available disks are:
  sda   (1024.2 GB ATA      NT-1TB-TM       )
Which disk(s) would you like to use? (or '?' for help or 'none') [sda]
How would you like to use it? ('sys', 'data', 'lvm' or '?' for help) [?] data
~~~

これで、ディスクどうなったか見てみると、

~~~
# df -h
Filesystem                Size      Used Available Use% Mounted on
devtmpfs                 10.0M         0     10.0M   0% /dev
shm                       2.8G         0      2.8G   0% /dev/shm
/dev/mmcblk0p3          110.2G      1.2G    103.4G   1% /
tmpfs                   576.6M    228.0K    576.4M   0% /run
/dev/mmcblk0p1          511.0M    272.0K    510.7M   0% /boot/efi
/dev/sda2               934.0G         0    934.0G   0% /var
cgroup_root              10.0M         0     10.0M   0% /sys/fs/cgroup
~~~

SSD1TB(sda)に/varが作成された。
一旦/varパーティションを削除し、あらためて/var(250GB)と /home(750GB)を作成する。

パーティション作成ツールを取得

~~~
# apk add -U gptfdisk sgdisk
~~~

~~~
# gdisk /dev/sda
~~~

により、sdaのパーティションを切りなおす。gdiskの使い方はfdiskと同じ。

元のパーティション

~~~
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         8390655   4.0 GiB     8200
   2         8390656      2000409230   949.9 GiB   8300
~~~

変更後のパーティション

~~~
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         8390655   4.0 GiB     8200
   2         8390656       506395300   237.5 GiB   8300  Linux filesystem
   3       506396672      2000409230   712.4 GiB   8300  Linux filesystem
~~~

一旦リブートし

~~~
# reboot
~~~

ディスクをフォーマット

~~~
# mkfs.ext4 /dev/sda2
# mkfs.ext4 /dev/sda3
~~~

ディスクの UUID を確認

~~~
# blkid
/dev/mmcblk0p3: UUID="4594ac58-ef59-420e-93f1-423b09cb92ee" TYPE="ext4"
/dev/mmcblk0p2: UUID="387d4b96-060b-4906-80a7-0c066015d468" TYPE="swap"
/dev/mmcblk0p1: UUID="801B-8E71" TYPE="vfat"
/dev/sda3: UUID="346cbfb9-e881-430b-9005-41881ef5bf1c" TYPE="ext4"
/dev/sda2: UUID="14c53e65-b833-4961-b760-3697ea52acbb" TYPE="ext4"
/dev/sda1: UUID="0fe2b3e9-1468-4a73-aa41-a8eed52f91a8" TYPE="swap"
~~~

/etc/fstabにマウントポイント追加

~~~
UUID=14c53e65-b833-4961-b760-3697ea52acbb       /var            ext4    defaults 1 2
UUID=346cbfb9-e881-430b-9005-41881ef5bf1c       /home            ext4    defaults 1 2
~~~

リブート

~~~
# reboot
~~~

確認

~~~
# df -h
Filesystem                Size      Used Available Use% Mounted on
devtmpfs                 10.0M         0     10.0M   0% /dev
shm                       2.8G         0      2.8G   0% /dev/shm
/dev/mmcblk0p3          110.2G      1.2G    103.3G   1% /
tmpfs                   576.6M    228.0K    576.4M   0% /run
/dev/mmcblk0p1          511.0M    272.0K    510.7M   0% /boot/efi
/dev/sda2               232.7G     60.4M    220.8G   0% /var
/dev/sda3               700.2G     72.0M    664.5G   0% /home
cgroup_root              10.0M         0     10.0M   0% /sys/fs/cgroup
~~~

システムのインストール完了。

# パッケージのインストール

直にインストールするのは、docker, nginx, sambaのみ。nginxは複数のWebアプリを束ねるリバースプロキシとして使う。sambaはdockerで動かすと細かな資格情報制御がややこしいので直入れする。

dockerはシステムのインストール時に導入済み。

## samba

sambaのインストール

~~~
# apk add samba
~~~

/etc/samba/smb.conf設定

~~~conf
[global]
   unix charset = UTF-8
   dos charset = CP932
   workgroup = WORKGROUP
   server string = %h server (Samba, Alpine)
   dns proxy = no
   interfaces = 127.0.0.0/8 192.168.1.0/24
   bind interfaces only = yes
   map to guest = Bad User
   log file = /var/log/samba/log.%m
   max log size = 1000
   syslog = 0
   panic action = /usr/share/samba/panic-action %d
   server role = standalone server
   passdb backend = tdbsam
   obey pam restrictions = yes
   unix password sync = no
   passwd program = /usr/bin/passwd %u
   passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
   pam password change = yes
   map to guest = bad user
   usershare allow guests = yes
   fruit:metadata = netatalk
   fruit:encoding = native

[larkbox]
   path = /home/samba/share/
   writable = yes
   browseable = yes
   guest ok = no
   guest only = no
   create mode = 0664
   directory mode = 0775
   valid user = 自分のアカウント

[TimeCapsule]
   comment = Backup for Mac Computers
   path = /home/samba/timecapsule
   writable = yes
   browsable = yes
   guest ok = no
   fruit:time machine = yes
   uit:time machine max size = 500M
   valid user = 自分のアカウント
~~~

ユーザ登録

~~~
# pdbedit -a -u 自分のアカウント
~~~

samba再起動

~~~
# service samba restart
~~~

起動設定

~~~
# rc-update add samba
~~~

### ホスト名の名前解決ができるよう設定

~~~
# apk add avahi
# apk add dbus
# rc-update add dbus
# rc-update add avahi-daemon
# service avahi-daemon restart
~~~

/etc/avahi/services設定

~~~xml
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
    <name replace-wildcards="yes">%h</name>
    <service>
        <type>_smb._tcp</type>
        <port>445</port>
    </service>
</service-group>
~~~

サービス再起動

~~~
# service avahi-daemon restart
~~~

## nginx

nginxをインストール

~~~
# apk add nginx
~~~

/etc/nginx/conf.d/default.confを作成

~~~conf
server {
    listen 80;

    server_name larkbox;
    client_max_body_size 128m;

    index index.html index.htm index.php;

    location / {
        proxy_pass http://localhost:8080/;
        access_log off;
    }

}
~~~

nginxを起動。

~~~
# /etc/init.d/nginx start
~~~

起動設定

~~~
# rc-update add nginx
~~~


# Webアプリのインストール

入れたいWebアプリは、片っ端からdocker-composeで入れる。

とりあえず、apacheとdocker管理ツールPortainerを入れてみる。

## Apache+php+MySQL

apacheには8080ポートでアクセスするように設定しているが、nginxリバースプロキシ経由で80ポートでアクセスできる。
iPhoneから自宅LAN内のサーバにアクセスする場合、iPhoneではhostsファイルを設定できないのでプロキシサーバで名前解決する必要がある。そのため、apacheにプロキシサーバ機能も持たせる。プロキシポート番号は8888とした。


docker-compose.yaml

~~~yml
version: '3'

services:
  php:
    image: php:7.2-apache
    volumes:
      - ./php.ini:/usr/local/etc/php/php.ini
      - ./html:/var/www/html
      - ./apache2/apache2.conf:/etc/apache2/apache2.conf
      - ./apache2/proxy-html.conf:/etc/apache2/proxy-html.conf
      - ./apache2/hosts:/etc/hosts
    ports:
      - 8080:80
      - 8888:8888
    restart: always
  mysql:
    image: mysql:5.7
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=test
      - MYSQL_USER=test
      - MYSQL_PASSWORD=test
    restart: always
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql
      - PMA_USER=test
      - PMA_PASSWORD=test
    links:
      - mysql
    ports:
      - 4040:80
    volumes:
      - ./phpmyadmin/sessions:/sessions
    restart: always
~~~

./apache2/apache2.conf

~~~conf
LoadModule proxy_html_module /usr/lib/apache2/modules/mod_proxy_html.so
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_connect_module /usr/lib/apache2/modules/mod_proxy_connect.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
 
<IfModule proxy_html_module>
  Include /etc/apache2/proxy-html.conf
</IfModule>
~~~

./apache2/proxy-html.conf

~~~conf
<IfModule mod_proxy.c>
  ProxyRequests On
  ProxyVia On
  Listen 8888
  <Proxy *>
    Order deny,allow
    Deny from all
    Allow from all
  </Proxy>
</IfModule>
~~~

./apache2/hosts

~~~conf
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.27.0.2      450ce809bc23
192.168.1.2     centos7
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.27.0.2      450ce809bc23
192.168.1.x     larkbox
192.168.1.1     自宅ルーター名
~~~

起動

~~~
$ docker-compose up -d
~~~

これで、
http://larkbox:8080/
でapacheにアクセスできるようになるが、nginxのリバースプロキシにより
http://larkbox/
でアクセスできるようになる。

## Portainer

docker-compose.yaml

~~~yml
version: '2'
services:
  portainer:
    image: portainer/portainer
    ports:
      - 9000:9000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
	  - ./data:/data
    restart: always
~~~

起動

~~~
$ docker-compose up -d
~~~

これで、
http://larkbox:9000/
でアクセスできるようになるが、
nginxの設定ファイル/etc/nginx/conf.d/default.confを以下のように書き加えると、

/etc/nginx/conf.d/default.conf

~~~conf
server {
    ...
    location /portainer/ {
        proxy_pass http://localhost:9000;
        rewrite /portainer/(.*)$ /$1 break;
        access_log off;
    }
~~~

http://larkbox/portainer
でアクセスできるようになる。

# 肝心のサーバとしての性能は？

Larkbox導入前は、Corei7-8559UのNuc(memory32GB)上のWindowsPro上のVirtualBox上のCentOS7(memory8GB)をサーバにしていたが、体感的にはこれとあまり変化はない。有線LANが無いサーバだけどそこそこ使える印象。

+ TimeCapsuleのバックアップは、MacBookProの200GBの1回目バックアップが3時間程度だった。
+ Gatsby.jsのサイトはキビキビ動く。
+ 画像たっぷりのWordPressサイトもキビキビ動く。

クソ重いアプリでも試してみた。試しにFess13をインストールしてクロールしてみたが、Fess13のトップページを表示させるだけでもクソ重い。でも動かないわけでもない。クロールもできた。

不安だった放熱も大丈夫っぽい。

いけてるサーバが出来上がった。