はじめに

自宅サーバーを設置してから早くも3年近くが経ち、そろそろハードディスクが寿命かなと思っていると、何やら怪しげなメールが週数回の頻度で届くようになった。

This is an automatically generated mail message from mdadm
running on ubuntu-homeserver

A DegradedArray event had been detected on md device /dev/md/0.

Faithfully yours, etc.

P.S. The /proc/mdstat file currently contains the following:

Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 sda2[0]
      1949476864 blocks super 1.2 [2/1] [U_]
      bitmap: 11/15 pages [44KB], 65536KB chunk

unused devices: <none>


mdadm monitoring <root@ubuntu-homeserver>

とうとうハードディスク逝って不良セクターでまくってるー…ってことで、サーバーの更新を決意した。

今までは、Celeron J3455 + RAID1 2TB HDDという標準的なファイルサーバー構成で、wordpressのこのブログとowncloudをメインに動かしていたわけだが、クラウドでのファイル共有はDropboxに課金してしまったので不要になったため(だって、Dropboxの信頼性と便利さに自宅の簡易サーバーがかなうわけないし…)、とりあえずWordpressだけ動けばいいやと思うことにした。そこで、机の引き出しに打ち捨てられていたRaspberry Pi 2 Model Bを引っ張り出してきてサーバーにすることにした。

手のひらサイズになってコンパクトに

手順

ここでは、 Raspberry Pi 2 Model B にDockerで一発で起動できるWordpressサーバー構築を目指す。

OSインストール

Ubuntu Server 18.04 をインストールする。ここを参考に、ラズパイ用の公式インストールガイドにある Raspberry Pi 2: ubuntu-18.04.3-preinstalled-server-armhf+raspi2.img.xz のイメージをダウンロードした。

SDカードへの書き込みは、 balenaEtcher を使用した。このソフトを使うと、パーティション設定とかブート用のフラグとか何も考えずにワンクリックで書き込めて非常に楽。

初回起動後に、IPアドレスを固定アドレスにする。Ubuntu 18.04では、netplanでネットワーク系が一括管理されるようになったらしく、 /etc/netplan/50-cloud-init.yaml を編集して、$ sudo netplan applyすればリブートなしで設定が反映される。(参考)

Dockerのインストール

公式ドキュメントを参考にインストールする。一括インストールできるスクリプトがあって便利だった。ついでにdocker-composeもインストールする。

$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
$ sudo usermod -aG docker your-user
$ sudo apt-get install docker-compose

docker-compose.yml

このへんを参考にnginxのプロキシ経由でSSL化したwordpressサーバーをdocker-compose で起動させようとしたところ、exec format errorが出た。普通のimageはx86なので、Armのラズパイでは動かない。Dockerは設定ファイルだけ移してくればどこでも動くはず(個人の意見です)という幻想は、アーキテクチャの壁で阻まれた。

そこで、ここを参考に、エラーが出たイメージをArm用に再ビルドしたForkされたものに置き換えて、docker-compose.ymlが完成した。

version: '3'

services:
  wordpress:
    image: wordpress
    container_name: wordpress
    volumes:
      - "/home/ubuntu/server/wp:/var/www/html"
      - "/home/ubuntu/server/.docker/backup:/tmp/backup" 
      - "/home/ubuntu/server/.docker/log:/tmp/log" 
      - "/home/ubuntu/server/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini" 
    depends_on:
      - db
    working_dir: /var/www/html/wp
    expose:
      - 80
    restart: always
    environment:
      WORDPRESS_DB_PASSWORD: yourpassword
      WORDPRESS_DB_HOST: "db:3306"
      VIRTUAL_HOST: yourhost
      LETSENCRYPT_HOST: yourhost
      LETSENCRYPT_EMAIL: your@email

  db:
    image: hypriot/rpi-mysql
    container_name: mysql_wp
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: yourpassword

  nginx-proxy:
    image: alexanderkrause/rpi-nginx-proxy
    container_name: nginx_proxy_wp
    restart: always
    ports:
      - '80:80'
      - '443:443'
    volumes:
      - certs:/etc/nginx/certs:ro
      - vhost:/etc/nginx/vhost.d
      - nginx_static:/usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /home/ubuntu/server/max-size.conf:/etc/nginx/conf.d/max-size.conf
    labels:
      com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: ""

  nginx-letsencrypt:
    image: alexanderkrause/rpi-letsencrypt-nginx-proxy-companion
    container_name: nginx_proxy_certbot_wp
    restart: always
    volumes:
      - certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - vhost:/etc/nginx/vhost.d
      - nginx_static:/usr/share/nginx/html

volumes:
  db_data:
  certs:
  vhost:
  nginx_static:

また、アップロードファイル上限を変更するためのファイルとして、以下も用意する。さらに、ラズパイ処理遅すぎてnginxがタイムアウトするので、タイムアウトも延長した。

# max-size.conf

client_max_body_size 256M;
send_timeout 180;
proxy_connect_timeout 600;
proxy_read_timeout    600;
proxy_send_timeout    600;
# uploads.ini

file_uploads = On
upload_max_filesize = 256M
post_max_size = 256M

また、ファイル構成は以下のようにした。

server/
  ├ docker-compose.yml
  └ wp/
     ├ index.php (./wp/からのコピー)
     ├ .htaccess (./wp/からのコピー)
     ├ uploads.ini
     ├ max-size.conf
     └ wp/
        └ wordpressのファイル(wp-content等)

色々あって、WordPressはサブディレクトリ化してあるので、設定をしっかりしたあと、UpdraftPlusで復元した。

サーバーの自動起動設定

ここを参考に、systemctlのサービスを作って、有効化する。docker-compose.ymlは、/etc/docker/compose/wp-blogにハードリンクしておく。

# /etc/systemd/system/docker-compose-wp-blog.service
[Unit]
Description=wp-blog service with docker compose
Requires=docker.service
After=docker.service

[Service]
Restart=always

WorkingDirectory=/etc/docker/compose/wp-blog

# Remove old containers, images and volumes
ExecStartPre=/usr/bin/docker-compose down -
ExecStartPre=/usr/bin/docker-compose rm -f
ExecStartPre=-/bin/bash -c 'docker network ls -qf "name=%i_" | xargs docker network rm'
ExecStartPre=-/bin/bash -c 'docker ps -aqf "name=%i_*" | xargs docker rm'

# Compose up
ExecStart=/usr/bin/docker-compose up

# Compose down, remove containers
ExecStop=/usr/bin/docker-compose down

[Install]
WantedBy=multi-user.target

一つ注意したいのは、参考サイトにある手順では、再起動時にボリュームを削除してデータベースまで消してしまうので、-vオプションを排除すること。(一度失敗してボリューム消えて悲しい思いをしました。他人のソースコードをコピペしてくるときは、隅々まで全部読みましょう。予期せぬコードを実行する可能性があります。)

おわりに

これで、ラズパイでSSL化したWordpressがdocker-compose 一発で起動するようになった。

以前は、let’s encryptもapacheのモジュールでごちゃごちゃやったりして動かしてたけど、全部Dockerのコンテナにするとやっぱり便利。文明の利器に感謝。

ちなみに、前のサーバーのハードディスクはやっぱり片方おかしくなってた。ハードディスクは消耗品なので、バックアップ大事。

問題のHDD

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください