beta

Cockpit CMSをDockerコンテナで永続運用する

捨て置きレンサバでテスト運用していたCockpit CMSが問題なく使えそうだったので、クラウドサーバーでDockerコンテナで永続運用しはじめました。今回の簡単にやり方をまとめます。

公開日:2021年12月10日

サーバーレスではCockpit CMSは動かなかった

PHPが動くサーバーレスは少ないんですが、サーバーレスだと無料で使えるところが多いのでサーバーレスで運用できないかをテストしてみました。DBは外部のMySQL DBを使う前提です。

Heroku、Vercelでトライしてみましたが、Cockpit CMSが、

  1. SQLitがないとダメ
  2. /tmp/にアクセスできないとダメ

という仕組みなっていたので、サーバーレスでの運用は断念しました。ひょっとしたらMongo DBならいけたかもしれないですが、/tmp/へのライトで多分つまづくだろうと思ってやめました。

Cockpit CMSはサーバーへのインストールも、「レポジトリをダウンロードして、FTPしろ」的なドキュメントになってますし、意外とレンサバ向けな作りになっている気がしました。

クラウドサーバーでDockerコンテナで運用する

ということで、素直にクラウドサーバーでDockerコンテナで運用することにしました。

やったことは3つで、

  1. Cockpitコンテナを作成
  2. Cockpitのデータを永続化
  3. https-portalコンテナでHTTPS化

という感じです。

Cockpitコンテナを作成 && Cockpitのデータを永続化

ここは、公式サイトのドキュメントの通りです。今回は、ドメインのSSL化とCockpitコンテナの接続を、https-portalとの連携で実現させるので、docker-composeを使います。

Docker | Cockpit CMS

version: '3'
services:
  cockpit-cms:
    image: agentejo/cockpit
    environment:
      COCKPIT_SESSION_NAME: cockpit
      COCKPIT_SALT: __salt__ // type uuidgen
    ports:
      - "80"     
    volumes:
      - ./cockpit-data/storage:/var/www/html/storage
      - ./cockpit-data/config:/var/www/html/config
      - ./cockpit-data/migration:/var/www/html/migration

ポイントはいくつかありますが、「COCKPIT_SALT」はターミナルで

uuidgen

と打つと適当なSALTが生成されるのでそれをコピペします。

肝となるのは「volumes」のところで、Cockpit CMSはデフォルトでSQLiteでデータベースを作成していて、

/storage/

の中にデータを追加して行っています。

Dockerはコンテナを破壊するとデータも削除されてしまうので、永続化しておかないとVMの再起動だったり、なんかのタイミングでコンテナが削除されたタイミングで「/storage/」のデータが完全に喪失します。

CMSなのでデータの喪失は死活問題なので、きちんと永続化して保護しておきましょう。

configはオプション設定の保管場所、migrationはcpコマンドでデータのexport、importをした時のためのディレクトリです。

https-portalコンテナでHTTPS化

最近はサーバーレスを使うことが多くて久しぶりにDockerを使ってみたら、HTTPS化に手頃な「https-portal」というコンテナがあるのを発見したので、そちらを使いました。

https-portal:
  image: steveltn/https-portal:1
  ports:
    - '80:80'
    - '443:443'
  environment:
    DOMAINS: 'hogehoge.com -> http://cockpit-cms:80'
    STAGE: 'production'
  volumes:
    - https-portal-data:/var/lib/https-portal

こちらの注意点は2点ほど。

environmentのDOMAINSで、「使うドメイン -> http://コンテナ名:80」でリンクを作ります。ここの記述方法がわかりづらいんですが、ドメインのはhttpなし、向き先はhttpでコンテナ名の80番ポートに宛てる形になります。

あとは、「STAGE: ‘production’」の部分ですが、ここをproductionにしないと内部的にオレオレ証明をする仕組みになっているので、正しい証明書を取得してくれません。productionにセットしておくと「ISRG Root X1(要はLet’s Encrypt)」の証明書を取得してくれます。

初回起動時はかなりサーバーリソースを食うのでフリーズしたように感じますが、dockerのログで

[services.d] starting services
[services.d] done.

となっていれば、問題なく起動しているはずです。

完成したdocker-compose.yml

以上をまとめると下記の感じになります。

version: '3'

services:
  https-portal:
    image: steveltn/https-portal:1
    ports:
      - '80:80'
      - '443:443'
    environment:
      DOMAINS: 'hogehoge.com -> http://cockpit-cms:80'
      STAGE: 'production'
    volumes:
      - https-portal-data:/var/lib/https-portal
  cockpit-cms:
    image: agentejo/cockpit
    environment:
      COCKPIT_SESSION_NAME: cockpit
      COCKPIT_SALT: __salt__ // type uuidgen
    ports:
      - "80"      
volumes:
  https-portal-data:

このdocker-compose.ymlがあるところでup -dをすればコンテナが立ち上がります。

cockpit-cmsコンテナを複数用意したい場合は、コンテナ名を変更して複数書けば良いだけなので、複数CMSの運用でも非常に楽です。

複数の場合は、https-portalnのenvironment.DOMAINSを、

environment:
  DOMAINS: 'hogehoge.com -> http://cockpit-cms-a:80, fugafuga.com -> http://cockpit-cms-b:80'

という感じで、カンマ区切りでチェーンしていけば、それぞれ適切にSSLを取得してくれます。

初回アクセス時の注意ポイント

ドメインルートはエラーになる

初回アクセス時、永続化しないデフォルトのDockerコンテナのままだと、いきなりドメインルートにアクセスしても問題ないのですが、今回はstorage配下を永続化するために一旦真っ新にしているので、最初は「ドメイン/install」にアクセスする必要があります。

アクセスすると、storage配下に適切なディレクトリを作成して、インストール完了的な画面が出るので、そこでアカウント・パスワードを確認します(admin/adminですが・・・)。

初期ユーザーは削除しよう

初期インストールをすると、admin/adminなユーザーが作成されますが、これはCockpit CMSの全てで使われているので必ず削除しましょう。忘れるとセキュリティホール化します。

https-portalのRENEW_FORCEはなるべく使わない

https-portalにはenvironment.RENEW_FORCEという、証明書を強制的に更新するオプションが設定されていますが、これはなるべく使わない方が良いです。

というのも、Let’s Encryptでは同じドメインに対して証明書を発行するのは1週間に5回までという制限があるので、テストで起動・削除を繰り返すと、リミットに引っかかって証明書が取得できなくなります(https-portalのドキュメントにも書いてあります)。

[Let’s Encrypt 発行制限] Too many certificates already issued

コンテナを削除するときはバックアップをとっておこう

Cockpit CMSは、永続化していたとしてもコンテナを削除したタイミングでエントリーが消えることが何回かありました。

コンテナを削除するときは、念の為バックアップをとっておいた方が良いでしょう。

Author

Koji Kadoma
Member of codit.work

新着ノート

新着コード