Installation de Discourse pour le développement sur macOS avec asdf et docker-compose

Notez que ce guide d’installation est pour un environnement de développement non pris en charge. Les guides officiellement pris en charge pour macOS se trouvent ici (natif) et ici (Docker). Procédez à vos propres risques.

L’objectif de ce guide est de conteneuriser postgres et redis tout en gardant ruby en dehors des conteneurs.

J’ai essayé l’approche Discourse pour le développement avec Docker, mais elle était tout simplement trop lente sur ma machine.

Ensuite, j’ai examiné le guide Discourse pour le développement sur macOS. Mais la première chose que le script fait est d’installer brew. brew est peut-être excellent, mais j’utilise MacPorts depuis longtemps et je souhaite continuer à résister avec succès à l’installation de brew. De plus, ce script effectuait également des installations globales d’outils comme postgresql et redis, que je préférerais pouvoir gérer au niveau de chaque projet.

Voici donc ce qui a fonctionné pour moi en combinant asdf et docker-compose. Le résultat est un compromis entre les deux approches décrites ci-dessus. postgres et redis sont exécutés dans un conteneur via docker-compose afin qu’ils puissent être figés sur les versions officielles utilisées par Discourse en production. Rails s’exécute directement sur le matériel. Cette combinaison est considérablement plus réactive pour moi. YMMV.

Si vous souhaitez suivre les étapes, vous devrez avoir asdf et Docker installés sur votre machine. (OMG asdf est vraiment fantastique… vous devriez absolument l’obtenir si vous avez le moindre intérêt à gérer facilement de nombreux environnements de développement différents. Il remplace renv, nvm… apparemment presque tout sauf jenv.)

Si vous examinez ce que faisait le script d’installation macOS, vous pouvez séparer les éléments installés en trois catégories :

  • les environnements et outils en ligne de commande comme ruby et yarn. Nous les installerons et figerons leurs versions dans notre répertoire de projet en utilisant asdf.
  • les services — spécifiquement postgres et redis. Nous les installerons via Docker Compose, encore une fois afin de pouvoir figer leurs versions sur celles nécessaires à ce projet et également disposer d’un environnement de développement que nous pouvons facilement démarrer et arrêter.
  • autres — principalement des bibliothèques pour la manipulation d’images comme ImageMagick et l’optimisation. Ceux-ci peuvent être installés soit avec brew, port, soit directement depuis les sources.

Nous devrons également reconfigurer légèrement notre environnement de développement pour nous connecter au serveur postgres exécuté par docker-compose.

Source de Discourse

Toutes les étapes ci-dessous doivent être effectuées dans votre répertoire source de Discourse :

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

C’est important car c’est là que asdf enregistrera son fichier de configuration .tool-versions et où nous créerons notre fichier docker-compose.yml pour Docker.

asdf

Il y a trois choses que nous devons installer avec asdf : ruby, yarn et postgres. Heureusement, asdf facilite à la fois l’installation de tous ces éléments d’un coup et le figement des versions dans notre répertoire de projet. Tout d’abord, créez .tool-versions avec le contenu suivant :

yarn 1.22.2
ruby 2.6.5
postgres 10.12

Ensuite, exécutez simplement asdf install.

Vous devriez maintenant pouvoir effectuer les étapes d’installation des bibliothèques Ruby incluses dans le script et plus loin dans les instructions :

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

Vous devrez peut-être ajuster le chemin vers pg_config en fonction de l’endroit où vous avez installé asdf.

docker-compose.yml

Ensuite, nous devons créer notre fichier docker-compose.yml configuré pour démarrer redis et postgres. Le mien ressemble à ceci :

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

Merci à @pfaffman pour la suggestion d’utiliser un conteneur de données Discourse standard. geoffreychallen/discourse_data:latest est construit à partir de Discourse Docker. J’ai utilisé le fichier data.yml d’exemple avec deux modifications. Premièrement, j’ai défini le mot de passe de l’utilisateur discourse sur « discourse ». Deuxièmement, j’ai fait de cet utilisateur un superutilisateur afin qu’il puisse créer des bases de données de test. Voici la partie hooks de mon fichier data.yml :

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

Encore une fois, ceci est uniquement si vous souhaitez construire votre propre conteneur de données Discourse et ne pas utiliser le mien. Veuillez ne pas utiliser ce conteneur en production — il est complètement non sécurisé !

Dans cette configuration, nous exposons à la fois les ports standard de postgres et de redis et exécutons la commande boot dont le conteneur a besoin pour démarrer.

Une fois votre docker-compose.yml en place, essayez-le :

docker-compose up

Si tout est correctement configuré, vous devriez voir redis et postgres démarrer. Appuyez sur Control-C pour annuler ou exécutez docker-compose down si, pour une raison quelconque, quelque chose ne s’arrête pas proprement.

Bibliothèques diverses

La plupart des bibliothèques d’optimisation d’images peuvent être installées soit avec port soit avec brew. Voici comment faire avec port :

sudo port install imagemagick pngquant optipng jhead jpegoptim gifsicle

svgo peut être installé une fois que vous avez npm. Je ne vais pas couvrir cela, car c’est assez simple.

Pour information, à ma connaissance, aucun de ces outils n’est requis. Je vois des avertissements lors de diverses étapes ultérieures indiquant leur absence, mais rien ne semble exploser.

config/database.yml et spec/fixtures/multisite/two_dbs.yml

Enfin, nous devons reconfigurer légèrement notre environnement de développement pour se connecter correctement à postgres. Par défaut, il essaie d’utiliser un socket Unix, qui n’est pas exporté par notre conteneur.

Pour corriger cela, vous devez modifier config/database.yml. Essentiellement, partout où vous voyez :

adapter: postgresql

Remplacez-le par :

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

L’ajout de host empêche Discourse d’utiliser un socket, et les paramètres username et password obligent Discourse à se connecter en utilisant l’utilisateur de base de données Discourse par défaut et le mot de passe que nous avons défini ci-dessus.

J’ai dû apporter cette modification trois fois dans config/database.yml : une fois sous development, ensuite sous test, et enfin sous profile. Pour que la suite de tests fonctionne, j’ai également dû apporter une modification similaire dans spec/fixtures/multisite/two_dbs.yml.

C’est parti…

Allez, c’est parti ! Dans une fenêtre, lancez votre environnement de développement avec docker-compose :

docker-compose up

Dans une deuxième fenêtre, exécutons les étapes de configuration de la base de données :

bundle exec rake db:create

Si cela a fonctionné, vous pouvez reprendre à l’étape appropriée du guide macOS basé sur brew.

Lorsque vous avez terminé de travailler, arrêtez docker-compose et vous pourrez ranger votre environnement de développement jusqu’à la prochaine fois.

Si vous souhaitez supprimer définitivement la base de données et le contenu de redis, exécutez simplement docker-compose down -v pour effacer les volumes persistants ainsi que les conteneurs eux-mêmes. Mais sans le drapeau -v, docker-compose down conservera votre base de données entre les sessions de développement.

Les tests passent-ils ?

Mon installation a échoué sur deux cas de test :

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

Pour moi, le premier semble indiquer que pngquant fonctionne un peu mieux que prévu. Je ne sais pas pourquoi cela représente un échec. Le second, je ne le comprends pas non plus. Mais cela me semble raisonnable.

Bon bricolage !

5 « J'aime »