asdf と docker-compose を使って macOS 開発環境に Discourse をインストールする

注意:これはサポートされていない開発環境のインストールガイドです。 macOS 用の公式サポートガイドは こちら(ネイティブ)こちら(Docker) にあります。自己責任で進めてください。

このガイドの目的は、Postgres と Redis をコンテナ化しつつ、Ruby はコンテナ外に保つことです。

私は以前、Docker を使用した Discourse 開発ガイド のアプローチを試しましたが、私のマシンではあまりに遅すぎました。

次に、macOS での Discourse 開発ガイド を検討しました。しかし、そのスクリプトが最初に行ったのは brew のインストールでした。brew は非常に優れているかもしれませんが、私は長年 MacPorts を使用しており、brew のインストールを成功裏に拒み続けたいと考えています。さらに、そのスクリプトは PostgreSQL や Redis のようなものをグローバルにインストールしていましたが、私はプロジェクトごとに管理したいと考えていました。

そこで、asdfdocker-compose を組み合わせた私が成功させた方法をご紹介します。その結果、上記の 2 つのアプローチの中間的なものができました。Postgres と Redis は docker-compose を使用してコンテナ内で実行され、Discourse が本番環境で使用している公式バージョンとインストールに固定できます。Rails はネイティブ(メタル)上で動作します。この組み合わせは私にとってかなり高速に動作します。YMMV(あなたの環境によっては異なる場合があります)。

これに従って進めたい場合は、マシンに asdf と Docker がインストールされている必要があります。(OMG、asdf は本当に素晴らしいです…もし複数の開発環境を簡単に管理することに興味があるなら、ぜひ入手すべきです。renvnvm… ほぼすべてを置き換えますが、jenv 以外は。)

macOS インストールスクリプトが行っていたこと を見ると、インストールされるものを 3 つのカテゴリに分類できます。

  • rubyyarn などのコマンドライン環境とツールです。これらをインストールし、asdf を使用してプロジェクトディレクトリにバージョンを固定します。
  • サービス、具体的には Postgres と Redis です。これらも Docker Compose を使用してインストールします。これもプロジェクトに必要なバージョンに固定し、簡単に起動・停止できる開発環境を持つためです。
  • その他、主に ImageMagick や最適化などの画像操作ライブラリです。これらは brewport、またはソースから直接インストールできます。

また、docker-compose によって実行される Postgres サーバーに接続するために、開発環境を少し再設定する必要があります。

Discourse ソース

以下の手順はすべて、Discourse ソースディレクトリ内で行ってください。

git clone https://github.com/discourse/discourse.git && cd discourse

これは重要です。なぜなら、asdf.tool-versions 設定ファイルを保存し、Docker の docker-compose.yml ファイルを作成するのはこの場所だからです。

asdf

asdf を使用してインストールする必要があるものは 3 つあります。rubyyarnpostgres です。幸いなことに、asdf はこれらを一度にインストールし、プロジェクトディレクトリにバージョンを固定することを容易にします。まず、以下の内容で .tool-versions を作成してください。

yarn 1.22.2
ruby 2.6.5
postgres 10.12

次に、asdf install を実行するだけです。

これで、スクリプトおよび後続の指示に含まれている Ruby ライブラリのインストール手順を実行できるようになるはずです。

gem update --system
gem install bundler
gem install rails
gem install mailcatcher
gem install pg -- --with-pg-config=$HOME/.asdf/installs/postgres/10.12/bin/pg_config
bundle install

asdf をインストールした場所に応じて、pg_config のパスを調整する必要があるかもしれません。

docker-compose.yml

次に、Redis と Postgres を起動するように設定された docker-compose.yml ファイルを作成する必要があります。私の設定は以下の通りです。

version: "3"
networks:
  discourse:
    driver: bridge
services:
  data:
    image: "geoffreychallen/discourse_data:latest"
    command: /sbin/boot
    ports:
      - "5432:5432"
      - "6379:6379"
    volumes:
      - "data_shared:/shared/"
      - "data_logs:/var/log/"
    networks:
      - discourse
volumes:
  data_shared:
    driver: local
  data_logs:
    driver: local

標準的な Discourse データコンテナを使用するという @pfaffman の提案に感謝します。geoffreychallen/discourse_data:latestDiscourse Docker からビルドされています。私はサンプルの data.yml ファイルを使用しましたが、2 つの変更を行いました。まず、discourse ユーザーのパスワードを discourse に設定しました。次に、そのユーザーをスーパーユーザーにしてテストデータベースを作成できるようにしました。これが私の data.yml ファイルの hooks 部分です。

hooks:
  after_postgres:
    - exec:
        stdin: |
          alter user discourse with password 'discourse';
        cmd: sudo -u postgres psql discourse
        raise_on_fail: false
    - exec:
        stdin: |
          alter user "discourse" with superuser;
        cmd: sudo -u postgres psql discourse
        raise_on_fail: false

繰り返しになりますが、これは独自の Discourse データコンテナを構築して私のものを使わない場合のためのものです。このコンテナを生産環境で使用しないでください。完全に安全ではありません!

この設定では、標準的な Postgres と Redis のポートを両方公開し、コンテナを起動するために必要なブートコマンドを実行します。

docker-compose.yml が準備できたら、試してみましょう。

docker-compose up

すべてが正しく設定されていれば、Redis と Postgres が起動するはずです。キャンセルするには Control-C を押すか、何らかの理由で正常にシャットダウンしない場合は docker-compose down を実行してください。

miscellaneous ライブラリ

画像最適化ライブラリのほとんどは、port または brew を使用してインストールできます。port を使用する方法は以下の通りです。

sudo port install imagemagick pngquant optipng jhead jpegoptim gifsicle

svgonpm をインストールした後であればインストールできます。これは非常に straightforward なので、ここでは扱いません。

参考までに、AFAICT(私の知る限り)、これらのツールのいずれも必須ではありません。後続のさまざまな手順でそれらが不足しているという警告が表示されますが、何も爆発することはありません。

config/database.ymlspec/fixtures/multisite/two_dbs.yml

最後に、Postgres に正しく接続するために、開発環境を少し再設定する必要があります。デフォルトでは Unix ソケットを使用しようとしますが、これはコンテナからエクスポートされていません。

これを修正するには、config/database.yml を変更する必要があります。基本的に、以下のように表示される場所すべてで。

adapter: postgresql

これを以下に置き換えます。

adapter: postgresql
host: localhost
username: discourse
password: discourse

host の追加により、Discourse がソケットを使用しなくなります。また、usernamepassword により、Discourse はデフォルトの Discourse データベースユーザーと上記で設定したパスワードを使用して接続します。

私は config/database.yml でこの変更を 3 回行う必要がありました。1 回は development 下、次に test 下、最後に profile 下です。テストスイートが動作するようにするため、spec/fixtures/multisite/two_dbs.yml でも同様の変更を行う必要がありました。

それでは始めましょう…

さあ、始めましょう!1 つ目のウィンドウで docker-compose を使用して開発環境を起動します。

docker-compose up

2 つ目のウィンドウでデータベースセットアップ手順を実行します。

bundle exec rake db:create

これで正常に動作すれば、brew ベースの macOS ガイド の適切な箇所から再開できます。

作業が終わったら docker-compose を停止し、次回まで開発環境を片付けておきましょう。

データベースと Redis の内容を恒久的に削除したい場合は、docker-compose down -v を実行して、永続ボリュームとコンテナ自体を消去してください。ただし、-v フラグなしで docker-compose down を実行すると、データベースは開発セッション間で維持されます。

テストはパスしますか?

私の設定では、2 つのテストケースが失敗しました。

Failures:

  1) UploadCreator#create_for pngquant should apply pngquant to optimized images
     Failure/Error: expect(upload.filesize).to eq(9558)

       expected: 9558
            got: 9550

       (compared using ==)
     # ./spec/lib/upload_creator_spec.rb:115:in `block (4 levels) in <main>'

  2) tasks/uploads uploads:secure_upload_analyse_and_update when store is external when secure media is enabled rebakes the posts attached
     Failure/Error: expect(post1.reload.baked_at).not_to eq(post1_baked)

       expected: value != 2020-03-08 03:20:01.777117000 +0000
            got: 2020-03-08 03:20:01.777117000 +0000

       (compared using ==)

       Diff:
         <The diff is empty, are your objects producing identical `#inspect` output?>
     # ./spec/tasks/uploads_spec.rb:90:in `block (5 levels) in <main>'

Finished in 19 minutes 21 seconds (files took 13.67 seconds to load)
4297 examples, 2 failures, 11 pending

私には、最初のものは pngquant が予想以上にうまく機能しているように見えます。なぜそれが失敗を表すのかはわかりません。2 つ目も理解できません。しかし、これは私には妥当に思えます。

ハッキングを楽しんでください!

「いいね!」 5