Blog

DNG Webサイトの裏側

この記事は落合陽一研究室に所属している学生による、 Digital Nature Advent Calendar 2018 の23日目の記事です。

概要

Digital Nature Groupは落合陽一准教授が率いる筑波大学の研究室です。

当然ですが、研究成果やイベント情報などを、公式Webサイトで発信しています。

DNG Webサイト

このwebサイトは2017年度まで、外部の企業に依頼して管理してもらっていましたが、契約終了に基づき2018年度から学生で管理することになりました。

今回は、その移行の際に行ったことや注意した点を書いておこうと思います。

ちなみに、DNG WebサイトはWordPressで構築されています。

主にやったことは以下のとおりです。

  • サーバを移行
  • apacheからnginxに変更
  • php-fmの調整
  • 開発用にdocker環境を構築

私はインフラが専門でないので、なにか間違っていればこっそり教えてください…

サーバを移行

外部の企業さんの管理していたサーバが使えなくなるので、新たにサーバを確保する必要がありました。

ちなみに、以前は さくらのレンタルサーバ スタンダード でした。

DNG Webサイトは、大学の研究室のWebサイトとしては異例の(たぶん)、MAUが1万を超えるようなサイトです。

また、落合先生がテレビ等のメディアに出ると瞬間的にアクセスが激増する、意外とハードな環境でした。

そのため、2017年に放送された情熱大陸では、一時的にサーバが落ちてしまいました。

そこで今回は、もう少しスペックが高いサーバを見繕う必要がありました。

一方、大学の研究室ということもあり、無駄にお金をかけるわけも行かず、またあくまでも静的サイトがメインであることも考え、少しスペックを上げた さくらのVPS メモリ1G を選択し、ソフトウェア側でチューニングすることにしました。

apacheからnginxに変更

WordPressはapacheを標準で採用しており、DNG Webサイトも以前までapacheで動いていました。

一方、apacheは大量のリクエストを裁くのは得意ではなく、最近の多くのwebサイトはnginxで動いています。

先程述べたように、瞬間的にアクセスが増えることがあるため、nginxに思い切って移行することにしました。

WordPressのパーマリンクを使用していたので対応すると、最終的に以下のような設定をしました。

server {
    listen       80;
    server_name  localhost;

    root   /var/www;
    index  index.php index.html index.htm;

    client_max_body_size 20M;

    location ~* /wp-config.php {
            deny all;
    }

    location / {
        try_files $uri $uri/ @wordpress;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

    location ~ \.php$ {
        try_files $uri @wordpress;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass   app:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    location @wordpress {
        fastcgi_index index.php;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass  app:9000;
        fastcgi_param SCRIPT_FILENAME  $document_root/index.php;
        include       fastcgi_params;
    }

    error_page 404 /404.html;
        location = /40x.html {
    }
}

php-fpmの調整

nginxに切り替えてからも、短い時間に同時にアクセスがあると以下のエラーを吐いて、その後サーバが重くなることが多々ありました。

[pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 3 idle, and 21 total children

試行錯誤した結果、php-fpmの設定を以下のようにすることで、落ち着きました。

メモリが1GBしかないサーバのため、pm.max_childrenをかなり抑えめにするのが重要だったと思います。

[www]
user = nginx
group = nginx
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1

pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4

slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache

開発用にdocker環境を構築

外部の企業との契約が終了したということで、今後のメンテナンスは自分たちでやる必要がありました。

しかし、mysqlやnginxを入れて動かすのはなかなかめんどくさいので、今回はdocker-composeで一瞬で環境を作れるようにしました。

  • docker-compose.yml
version: '3'
services:
  web:
    image: nginx:1.14.0-alpine
    depends_on:
      - app
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www
    ports:
      - "80:80"
  app:
    build: ./app
    volumes:
      - .:/var/www
    depends_on:
      - db
  db:
    image: mysql:5.7.22
    environment:
      - MYSQL_ROOT_PASSWORD=password
    ports:
      - "3306:3306"
    volumes:
      - ./db/initial.sql:/docker-entrypoint-initdb.d/initial.sql
  • app/Dockerfile
FROM php:7.2.6-fpm-alpine
RUN apk add --no-cache freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install pdo_mysql mysqli mbstring gd

これで、 db/initial.sql に初期DBデータを配置し、 nginx/defaulty.conf にnginxの設定を配置すると、 docker-compose up をするだけで、local環境を作成することができます。

WordPressのコードを書き換えるときも快適にコーディング、レビューができるようになりました。

まとめ

サーバ移行と諸々の設定の結果、5.5秒ほどかかっていたロードが、2.5秒ほどまで短縮し、実質ロード時間を半分にすることに成功しました。

その他にも、https対応をしたり、google analyticsを導入したり、細々したことをしていました。

もう少し各場所でキャッシュをさせたり、できることはあると思うので、時間があればやろうと思います。

Webサイトも定期的に更新しているので、ぜひ御覧ください。

人気の記事

kotlin coroutinesのFlow, SharedFlow, StateFlowを整理する

Jetpack ComposeとKotlin Coroutinesを連携させる

Layout Composableを使って複雑なレイアウトを組む【Jetpack Compose】

テスト用Dispatcherの使い分け【Kotlin Coroutines】

Flow.combineの内部実装がすごい話

Jetpack ComposeのRippleエフェクトを深堀り、カスタマイズも