Changes

m
Line 1: Line 1:  +
{{DISPLAYTITLE:Discourse Migration}}
 +
 
This page gathers info about Discourse migration.
 
This page gathers info about Discourse migration.
    +
For the implementation, see [[User:Jtraulle/DiscourseMigration/Implementation]]
 +
 +
 +
==Context (forum migration project genesis)==
 +
 +
 +
Topic has been first discussed on the french speaking Dolibarr forum here : https://www.dolibarr.fr/forum/11-suggestionsnouvelles-fonctionnalites/64778-forum-quelle-solution-choisir
 +
 +
Topic has also been discussed on [[Report board meeting 20190730 teleconf]]
 +
 +
 +
==Proposed skeleton==
 +
 +
 +
Each newly created thread '''<u>MUST</u>''' be placed into a category.
 +
 +
Categories in '''bold''' are main categories.
 +
 +
Categories preceded of a bullet point are sub categories belonging to a main category.
 +
<br />
 +
{| class="wikitable mw-collapsible"
 +
!Categories proposal
 +
|-
 +
|'''Annonces & actualités (verrouillé)'''
 +
 +
''Vous trouverez dans cette catégorie des annonces et actualités en lien avec le projet Dolibarr : nouvelles versions, évènements, mise à jour des outils communautaire du projet, etc.''
 +
|-
 +
|'''Installer mon Dolibarr'''
 +
''Obtenir de l’aide sur l’installation de Dolibarr quelque soit votre système (GNU/Linux, macOS, Windows, système NAS), votre méthode d’installation (depuis les sources, DoliWamp, DoliDeb, DoliRpm) et votre environnement (serveur local, mutualisé, dédié, cloud).''
 +
|-
 +
|'''Utiliser mon Dolibarr'''
 +
''Obtenir de l’aide sur l’utilisation des modules fournis avec Dolibarr, suggérer des nouvelles fonctionnalités ou signaler des anomalies.''<br />
 +
 +
*Modules GRC/GRF (Tiers, Contrats/Abonnements, Interventions, Commandes, Expéditions, Tickets)
 +
*Modules GRH (Utilisateurs, Adhérents, Congés, Notes de frais)
 +
*Modules PM (Produits, Services)
 +
*Modules financiers (Facturation, Banque/Caisse, Dons, Comptabilité, Comptabilité avancée)
 +
*Autres modules natifs (Projets/Travail collaboratif, GED, Outils multi-modules, etc.)
 +
*Modules externes du DoliStore
 +
*Retours d'expérience
 +
|-
 +
|'''Maintenir mon Dolibarr'''
 +
''Obtenir de l’aide sur la mise à jour de Dolibarr vers une version plus récente, la migration d’une instance Dolibarr vers un nouveau serveur, les opérations de sauvegarde et de restauration (fichiers et base de données) et plus généralement, tout ce qui touche à la configuration et à la maintenance système de la machine hébergeant votre instance Dolibarr (cron, permissions, etc.).''
 +
|-
 +
|'''Développer pour Dolibarr'''
 +
''Obtenir de l’aide concernant le développement de modules spécifiques ou thèmes pour Dolibarr mais également sur la façon d’utiliser les modules API REST et SOAP pour interconnecter Dolibarr avec une application externe.''
 +
|-
 +
|'''Discuter entre Dolibarriens'''
 +
''Cet espace de discussion vous permet d’échanger avec les autres utilisateurs de Dolibarr sur des sujets sans lien avec Dolibarr.''
 +
|}
 +
 +
 +
Each newly created thread can also have '''''tags''''' regardless of its category.
 +
{| class="wikitable"
 +
|+Transversal tags proposal
 +
!Tags type
 +
!Tags proposal
 +
|-
 +
| rowspan="3" |Type of
 +
thread
 +
|Question
 +
|-
 +
|Suggestion
 +
|-
 +
|Anomalie
 +
|-
 +
| rowspan="8" |Code branch
 +
or Version
 +
|v10.x
 +
|-
 +
|v9.x
 +
|-
 +
|v8.x
 +
|-
 +
|v7.x
 +
|-
 +
|v6.x
 +
|-
 +
|v5.x
 +
|-
 +
|v4.x
 +
|-
 +
|v3.x
 +
|}
 +
 +
 +
An user will also have the ability to mark an answer of the thread as the '''solution'''.
 +
 +
This explains why there is no '''Résolu''' tag in the proposal.
 +
<br />
 
<br />
 
<br />
 +
 +
===Proposed mapping between current and new skeleton===
 +
 +
 +
Categories are in bold and sub-categories in italic.
 +
{| class="wikitable mw-collapsible"
 +
|+
 +
!Current categories or sub-categories
 +
!New proposed categories and sub-categories
 +
|-
 +
|'''Annonces et fonctionnement du forum'''
 +
|'''Annonces & actualités (verrouillé)'''
 +
|-
 +
|'''Installation'''
 +
| rowspan="6" |'''Installer mon Dolibarr'''
 +
|-
 +
|''Installation sous Mac''
 +
|-
 +
|''Installation sous Gnu/Linux''
 +
|-
 +
|''Installation sous Windows''
 +
|-
 +
|''Installation Qnap Synology Divers''
 +
|-
 +
|''Installation Hebergeurs''
 +
|-
 +
|'''Mise à Jour'''
 +
|'''Maintenir mon Dolibarr'''
 +
|-
 +
|'''Howto / Aide'''
 +
| rowspan="10" |'''Utiliser mon Dolibarr'''
 +
|-
 +
|'''Bugs sur la version CVS ou demo'''
 +
|-
 +
|'''Bugs sur la version stable courante'''
 +
|-
 +
|'''Bugs avec PostgreSQL'''
 +
|-
 +
|'''Bugs sur la version ARCHIVE'''
 +
|-
 +
|''Bugs Dolibarr V6''
 +
|-
 +
|''Bugs Dolibarr V7''
 +
|-
 +
|''Bugs Dolibarr V3''
 +
|-
 +
|''Bugs Dolibarr V4''
 +
|-
 +
|''Bugs Dolibarr V5''
 +
|-
 +
|'''Retours d'expériences utilisateurs/intégrateurs'''
 +
|''Retours d'expérience''
 +
|-
 +
|'''Suggestions/Nouvelles fonctionnalités'''
 +
| rowspan="7" |'''Utiliser mon Dolibarr'''
 +
|-
 +
|'''Spécifiques à un Pays'''
 +
|-
 +
|''France''
 +
|-
 +
|''Belgique''
 +
|-
 +
|''Canada''
 +
|-
 +
|''Suisse''
 +
|-
 +
|''Autre''
 +
|-
 +
|'''Le module que j'ai téléchargé et deployé n'apparait pas'''
 +
|''Modules externes du DoliStore''
 +
|-
 +
|'''Création d'un nouveau module'''
 +
| rowspan="4" |'''Développer pour Dolibarr'''
 +
|-
 +
|''Hooks/Triggers/Classes Objets''
 +
|-
 +
|''API''
 +
|-
 +
|''Git & Github''
 +
|-
 +
|'''Adhérents/Association'''
 +
|''Modules GRC/GRF''
 +
|-
 +
|'''E-Commerce'''
 +
|''Modules externes du DoliStore''
 +
|-
 +
|'''Agenda'''
 +
|''Autres modules natifs''
 +
|-
 +
|'''WebMails'''
 +
| rowspan="4" |''Modules externes du DoliStore''
 +
|-
 +
|'''Autres modules'''
 +
|-
 +
|''Modules InfraS''
 +
|-
 +
|''Modules ATM''
 +
|-
 +
|''Module gestion de projets''
 +
| rowspan="3" |''Autres modules natifs''
 +
|-
 +
|''Extrafields''
 +
|-
 +
|''Modeles ODT''
 +
|-
 +
|''Modules Patas Monkeys''
 +
|''Modules externes du DoliStore''
 +
|-
 +
|'''Gestion des Ressources Humaines (GRH)'''
 +
| rowspan="6" |''Modules GRH''
 +
|-
 +
|''Module utilisateurs''
 +
|-
 +
|''Demandes de congés''
 +
|-
 +
|''Notes de frais''
 +
|-
 +
|''GRH''
 +
|-
 +
|''Protection des Données''
 +
|-
 +
|'''Gestion de la relation client (GRC)'''
 +
| rowspan="13" |''Modules GRC/GRF''
 +
|-
 +
|''Module Tiers''
 +
|-
 +
|''Modules Contrats/Abonnements''
 +
|-
 +
|''Module Interventions''
 +
|-
 +
|''Propositions commerciales''
 +
|-
 +
|''Expéditions''
 +
|-
 +
|''Contrats/Abonnements''
 +
|-
 +
|''Gestionnaire de tickets(Expérimental)''
 +
|-
 +
|''Commandes clients''
 +
|-
 +
|'''Gestion de la relation fournisseur (GRF)'''
 +
|-
 +
|''Fournisseurs''
 +
|-
 +
|''Propositions commerciales fournisseurs''
 +
|-
 +
|''Incoterm''
 +
|-
 +
|'''Modules financiers (Compta/trésorerie)'''
 +
| rowspan="9" |''Modules financiers''
 +
|-
 +
|''Comptabilité /Comptabilité (avancée)''
 +
|-
 +
|''Prélèvements''
 +
|-
 +
|''Banques et caisses''
 +
|-
 +
|''Dons''
 +
|-
 +
|''Règlement salaires''
 +
|-
 +
|''Module Marges''
 +
|-
 +
|''Factures et avoirs clients/ factures fournisseurs''
 +
|-
 +
|''Gestion des emprunts''
 +
|-
 +
|'''Gestion des Produits/Services (PM)'''
 +
| rowspan="6" |''Modules PM''
 +
|-
 +
|''Variantes de produits''
 +
|-
 +
|''Numéros de Lot/Série''
 +
|-
 +
|''Stock''
 +
|-
 +
|''Gestion des services''
 +
|-
 +
|''Gestion des produits''
 +
|-
 +
|'''Gestion électronique de documents (GED)'''
 +
|''Autres modules natifs''
 +
|-
 +
|'''Modules Themes'''
 +
| rowspan="3" |'''Utiliser mon Dolibarr'''
 +
|-
 +
|''Theme amarok''
 +
|-
 +
|''Theme Eldy''
 +
|-
 +
|'''Outils multi-modules'''
 +
| rowspan="5" |''Autres modules natifs''
 +
|-
 +
|''Libellés/Catégories''
 +
|-
 +
|''Éditeur WYSIWYG''
 +
|-
 +
|''Mass Emailing''
 +
|-
 +
|''Flux RSS''
 +
|-
 +
|''Exports / Imports de données''
 +
|'''Utiliser mon Dolibarr'''
 +
|-
 +
|''Module Multidevise''
 +
| rowspan="2" |''Autres modules natifs''
 +
|-
 +
|''Codes-barres''
 +
|-
 +
|'''Sites web et autres applications frontales'''
 +
|'''Utiliser mon Dolibarr'''
 +
|-
 +
|''Touch Screen POS''
 +
|''Modules financiers''
 +
|-
 +
|''Module Sondage ou Vote''
 +
|''Autres modules natifs''
 +
|-
 +
|''Module Caisse''
 +
|''Modules financiers''
 +
|-
 +
|'''Système'''
 +
| rowspan="2" |'''Maintenir mon Dolibarr'''
 +
|-
 +
|''Travaux planifiés''
 +
|-
 +
|'''Interfaces avec des systèmes externes'''
 +
|'''Développer pour Dolibarr'''
 +
|-
 +
|''Paypal''
 +
|''Modules financiers''
 +
|-
 +
|''Impressions Directe''
 +
| rowspan="4" |''Autres modules natifs''
 +
|-
 +
|'''Projets/Travail collaboratif'''
 +
|-
 +
|''Module Ressources''
 +
|-
 +
|''Projets/Opportunités/Affaires''
 +
|}
 +
 +
 +
===Preview of new mapping after migration===
 +
<br /><gallery widths="400" heights="800">
 +
File:Categories-discourse.png|Preview of new mapping after migration
 +
</gallery><gallery widths="500" heights="300">
 +
File:Liste-cat.png|Posts distribution across main categories
 +
File:Liste-sub-cat.png|Posts distribution across sub-category "Utiliser mon Dolibarr"
 +
</gallery>
 +
 +
 +
==Demo instance==
 +
 +
Demo instance with migrated data is available here : https://test-dolibarr-discourse.traulle.net/ (private ; see https://www.dolibarr.fr/forum/administration-forum/64852-instance-de-test-discourse#113680 for access - restricted to forum moderators and admins)
 +
 +
 +
==Migration path==
 +
 +
 +
Migrating from Kunena to Discourse can be handled using [https://github.com/discourse/discourse/blob/master/script/import_scripts/kunena3.rb the Discourse official import script].
 +
 +
A step by step guide is also available [https://meta.discourse.org/t/importing-from-kunena-3/43776?u=jtraulle on the Discourse forum].
 +
 +
Old Kunena releases (3.x) can be downloaded from the [https://joomlacode.org/gf/project/kunena/frs/?action=index&br_pkgrlssort_by=package_name&br_pkgrlssort_order=asc JoomlaCode forge].
 +
 +
 +
The original Discourse's Kunena migration script has been customized to be more aligned with the specific migration needs of the french Dolibarr forum.
 +
 +
It can be retrieved here : https://gist.github.com/jtraulle/a8ed0244a2a77498f29ac32fd2bc0f65
 +
 +
Main differences with original script :
 +
 +
===Import Users===
 +
 +
*Retrieve old "anonymous" Kunena users that does not have a Joomla! account
 +
*Retrieve profile info
 +
*Retrieve avatars
 +
 +
===Import Categories===
 +
 +
*Import categories hierarchy ignoring main groups (Discourse only has two levels hierarchy)
 +
*Categories are imported preserving the original order
 +
*Categories with no posts (and no subcategories) are ignored/skipped
 +
 +
------
 +
 +
The latest version of the custom migration script takes care of re-categorizing topics into the [[#Proposed_skeleton]]
 +
 +
===Import Posts===
 +
 +
*Multiple enhancements on posts text content
 +
**Escape some commonly used chars (>, -, +, *) to not be wrongly parsed as Markdown
 +
**Block quote
 +
***add a line break after [quote] BBCode tag if there is none
 +
***Replacing old posts reference in quote blocks by new ones
 +
***Removing remaining posts references in quote blocks for posts that does not exists anymore
 +
**Unordered lists
 +
***Break line after [ul] only for lines that starts by [ul] and followed by [li] tag on the same line
 +
**Strike support
 +
***Replace [strike][/strike] BBCode tag by <s></s> HTML equivalent for markdown parser
 +
**Emojis
 +
***Convert some emojis shortcuts to preserve custom emojis previously used
 +
 +
*Thank you
 +
**Kunena post's "thank you" are imported as Discourse post's likes  (added)
 +
 +
===Import Attachments===
 +
 +
Attachments to import into the new Discourse instance should be present to the local filesystem before running the task (plan about 400M disk space).
 +
 +
 +
To download attachments from previous forum, start by export the URLs from the Kunena database.
 +
 +
<syntaxhighlight lang="SQL">
 +
SELECT CONCAT('https://www.dolibarr.fr/', folder, '/', filename) AS url FROM gvrsi_kunena_attachments ORDER BY id;
 +
</syntaxhighlight>
 +
 +
Put all the URLs into a text file (for example <code>uploads.txt</code>).
 +
 +
Next, use <code>wget</code> to download all attachment preserving the directory structure (yuuup, file names of multiple distinct attachments can be the same ...)
 +
 +
<syntaxhighlight lang="bash">
 +
wget --no-host-directories --force-directories --input-file=uploads.txt
 +
</syntaxhighlight>
 +
 +
===Permalinks===
 +
 +
Permalinks offer the ability to preserve old forum links (from Kunena) and emit a HTTP 301 (Permanent Redirect) when hitting such old links for categories, topics, posts and profile links.
 +
 +
====Categories permalinks====
 +
 +
Kunena stores aliases for categories in the '''kunena_categories''' '''alias''' database field.
 +
 +
====Topics permalinks====
 +
 +
For topics URLs, this a bit more tricky since they are not stored in database (it uses standard Joomla! SEO friendly URLs generated using JRouter) and should therfore be generated on the fly in the import script.
 +
 +
Research showed that a "safe" alias can be generated using following Joomla! function :
 +
* <code>stringUrlSafe()</code> function in <code>libraries/vendor/joomla/filter/src/OutputFilter.php</code>
 +
* using <code>transliterate()</code> function in <code>libraries/src/Language/Language.php</code>
 +
* using <code>utf8_latin_to_ascii()</code> function in <code>libraries/src/Language/Transliterate.php</code>
 +
 +
====Direct messages permalinks====
 +
 +
Permalinks to specific messages like for example https://www.dolibarr.fr/forum/12-howto--aide/62681-wiki-dolibarr-org?start=225#113400 are even more tricky than topics permalinks because everything that is after a # in considered and anchor and, as such could be treated only on the client side (therefore using Javascript).
 +
 +
The permalink treatment logic for direct messages is the following :
 +
 +
# User go to https://test-dolibarr-discourse.traulle.net/forum/12-howto--aide/62681-wiki-dolibarr-org?start=225#113400 (the old permalink)
 +
# Normalization permalink rule <code>/(.*)\?.*/\1</code> is triggered and therefore remove part of the URL starting by ? ; the new URL to be processed become https://test-dolibarr-discourse.traulle.net/forum/12-howto--aide/62681-wiki-dolibarr-org#113400
 +
# Permalink for topic is triggered and redirect the URL to https://test-dolibarr-discourse.traulle.net/forum/t/wiki-dolibarr-org/27878#113400 (keeping the original anchor with the old postid)
 +
# Javascript detect that the current URL have a # part
 +
# Using Javascript, we redirect to the permalink https://test-dolibarr-discourse.traulle.net/forum/old-post/113400 that redirects to https://test-dolibarr-discourse.traulle.net/forum/t/wiki-dolibarr-org/27878/227
 +
 +
 +
=====Javascript part=====
 +
 +
This code is to paste in the <code>Admin → Customize → Themes → Light → Edit CSS/HTML → Common → </head></code> section.
 +
 +
<syntaxhighlight lang="HTML">
 +
<script type="text/javascript">
 +
var urlSplit = document.URL.split("#");
 +
if (urlSplit[1]) {
 +
    location.href = "/forum/old-post/" + urlSplit[1];
 +
}
 +
</script>
 +
</syntaxhighlight>
 +
 +
===Ads===
 +
 +
Current forum display an Ad banner (ads are currently managed in house using Joomla!
 +
 +
Discourse offers an ''' Official Advertising / Ad Plugin''' that can be used as a replacement. See https://meta.discourse.org/t/official-advertising-ad-plugin-for-discourse/33734
 +
 +
 +
 
==Tentative design==
 
==Tentative design==
<br />
+
 
    
===Custom logos===
 
===Custom logos===
Line 9: Line 478:     
Go to <code>Admin → Customize → Settings → Branding</code>
 
Go to <code>Admin → Customize → Settings → Branding</code>
  −
<br />
      
*Based on Dolibarr main color '''#3D5F93'''
 
*Based on Dolibarr main color '''#3D5F93'''
 
*[https://fr.cooltext.com/download-font-blippo Blippo] font<br />
 
*[https://fr.cooltext.com/download-font-blippo Blippo] font<br />
    +
<br />
 
====Main forum logo====
 
====Main forum logo====
 
[[File:Logo forum discourse (proposal).png|none|thumb|300x300px|Logo forum discourse (proposal)]]
 
[[File:Logo forum discourse (proposal).png|none|thumb|300x300px|Logo forum discourse (proposal)]]
Line 44: Line 512:  
This is a tentative custom Layout
 
This is a tentative custom Layout
   −
 
+
<gallery widths="800" perrow="2" heights="500">
<gallery mode="slideshow" style="max-width: 800px; max-height: 500px;">
   
File:Discourse-tentative-design-blue.png|Tentative design desktop (proposal)
 
File:Discourse-tentative-design-blue.png|Tentative design desktop (proposal)
 
File:Discourse-tentative-design-mobile-view.png|Tentative design mobile view (proposal)
 
File:Discourse-tentative-design-mobile-view.png|Tentative design mobile view (proposal)
 
</gallery>
 
</gallery>
   −
[[|none|thumb|800x800px|Tentative design (proposal)|alt=]]
+
<br />
    +
====Custom Header to add====
 +
Go to <code>Admin → Customize → Themes → Light → Edit CSS/HTML → Desktop → Header</code> and paste :
 
<br />
 
<br />
====Custom Header to add====
+
{| class="mw-collapsible mw-collapsed"
Go to <code>Admin → Customize → Themes → Light → Edit CSS/HTML → Common → Header</code> and paste :
+
!
 
+
|-
<syntaxhighlight lang="HTML">
+
|<syntaxhighlight lang="HTML">
 
<div id="header" class="clearfix">
 
<div id="header" class="clearfix">
 
     <div id="inner-header">
 
     <div id="inner-header">
Line 98: Line 567:  
     </div>
 
     </div>
 
</div>
 
</div>
</syntaxhighlight><br />
+
</syntaxhighlight>
 +
|}
 +
<br />
 
====Custom Footer to add====
 
====Custom Footer to add====
Go to <code>Admin → Customize → Themes → Light → Edit CSS/HTML → Common → Footer</code> and paste :
+
Go to <code>Admin → Customize → Themes → Light → Edit CSS/HTML → Desktop → Footer</code> and paste :
    
<syntaxhighlight lang="HTML">
 
<syntaxhighlight lang="HTML">
Line 109: Line 580:  
====Custom CSS to add====
 
====Custom CSS to add====
   −
Go to <code>Admin → Customize → Themes → Light → Edit CSS/HTML → Common → CSS</code> and paste :
+
Go to <code>Admin → Customize → Themes → Light → Edit CSS/HTML → Desktop → CSS</code> and paste :<br />
 
+
{| class="mw-collapsible mw-collapsed"
<syntaxhighlight lang="CSS">
+
!
 +
|-
 +
|<syntaxhighlight lang="CSS">
 
#header {
 
#header {
 
background-color: rgb(61,95,147);
 
background-color: rgb(61,95,147);
Line 330: Line 803:  
     text-align: center;
 
     text-align: center;
 
}
 
}
</syntaxhighlight><br />
+
</syntaxhighlight>
 +
|}
 +
<br />
 +
 
 +
==Requirements==
 +
 
 +
 
 +
===Hardware requirements===
 +
''To the extent possible, a VPS machine ''that will be dedicated to running the Discourse forum software '''only''''' is the way to go.''
 +
 
 +
*modern single core CPU, dual core recommended
 +
*1 GB RAM minimum (with swap)
 +
*64 bit Linux compatible with Docker (I recommand 18.04 LTS Ubuntu Server to be aligned with the wiki.dolibarr.org OS).
 +
*10 GB disk space minimum (SSD is a plus for the speed but not a requirement)
 +
 
 +
Refer to [https://github.com/discourse/discourse/blob/master/docs/INSTALL.md#hardware-requirements Hardware requirement (github.com)]
 +
 
 +
 
 +
===Domain requirements===
 +
Discourse '''<u>requires</u>''' a FQDN (Fully Qualified Domain Name) : for example <code>forum.dolibarr.fr</code> and cannot be installed in a subdirectory.
 +
 
 +
=> We must found a solution and valid it works.
 +
Future is to have doc/wiki on https://www.dolibarr.org/wiki, an forum of https://www.dolibarr.org/forum. Forum is 2/3 of traffic received on dolibarr.org and it is important to have a lot of content trusted by Google to have dolibarr.org valorized highly on Google search engine answers.
 +
 
 +
There is a solution here using a CDN frontend like Fastly: https://meta.discourse.org/t/discourse-in-a-subfolder-multiple-servers-sharing-a-domain/30514
 +
It is based on Fastly, be Dolibarr is using Cloudflare as CDN that may offers same features.
 +
 
 +
Another solution without CDN, using your own proxy, is suggested here https://meta.discourse.org/t/subfolder-support-with-docker/30507 but previous one seems easier.
 +
 
 +
 
 +
=> '''Yes, it is doable using nginx or Apache2 as a reverse proxy.''' In fact, I am using nginx as a reverse proxy on the demo instance.
 +
 
 +
=> With Cloudflare I found this : https://blog.cloudflare.com/subdomains-vs-subdirectories-improved-seo-part-2/
   −
==Email requirements==
+
===Email requirements===
Discourse '''<u>requires</u>''' connection to a valid mail server  
+
Discourse '''<u>requires</u>''' connection to a valid mail server :
    
*using SMTP protocol
 
*using SMTP protocol
*accessible on a FQDN (Fully Qualified Domain Name) : for example <code>@forum.dolibarr.fr</code>
+
*accessible on a FQDN (Fully Qualified Domain Name) : for example <code>forum.dolibarr.fr</code>
 
*with authentication (username and password)
 
*with authentication (username and password)
   −
===First choice : in house mail server like Postfix===
+
<br />
'''''Cheap but tricky to set/configure'''''
+
{| class="wikitable"
 +
|+Comparison of two possible configurations
 +
!In house mail server like [http://www.postfix.org/ Postfix]
 +
!External email service like [https://www.mailgun.com/ Mailgun]
 +
|-
 +
|
 +
*'''''Cheapest'''''
 +
*'''''Tricky to set/configure'''''
 +
*'''''Monitoring email reputation is required'''''
 +
|
 +
*'''''Affordable'''''
 +
*'''''Simple and easy (no configuration)'''''
 +
*'''''Email reputation is managed by the provider'''''
 +
|-
 +
|
 +
*Install [http://www.postfix.org/ Postfix] mailserver
   −
*Install Postfix mailserver
   
*Configure / allow / unblock port 587 for outgoing email sending by postfix in the firewall (IP table, etc.)
 
*Configure / allow / unblock port 587 for outgoing email sending by postfix in the firewall (IP table, etc.)
 
*Configure Postfix to require authentication : see https://blog.rom1v.com/2010/01/ajouter-lauthentification-smtp-sur-un-serveur-mail/
 
*Configure Postfix to require authentication : see https://blog.rom1v.com/2010/01/ajouter-lauthentification-smtp-sur-un-serveur-mail/
   −
===Second choice : external email service like [https://www.mailgun.com/ Mailgun]===
+
------
'''''Affordable, simple and easy (no configuration)'''''
+
Alternative : https://forum.normandie-libre.fr/t/installation-dun-forum-discourse-avec-apache-docker-et-mailboy/25
 +
|
 +
*[https://www.mailgun.com/ Mailgun] pricing, [https://www.mailgun.com/pricing first 10 000 emails every month free (+5$ by 10 000 email)]
 +
*[https://fr.mailjet.com/ Mailjet] pricing, [https://fr.mailjet.com/pricing/ first 6 000 monthly emails free (no more than 200 email per day ; 30 000 per month for 7,16€])
 +
*[https://aws.amazon.com/fr/ses/ AWS SES (Amazon Web Services Simple Email Service)] pricing, [https://aws.amazon.com/fr/ses/pricing/ 0.10$ per 1 000 emails].
 +
*[https://sendgrid.net/ SendGrid] pricing, Free for 100 emails per day or 14$ per month for 40 0000 emails.
 +
 
 +
|}
 +
 
 +
==Tips and tricks==
 +
 
 +
===Discourse tips and tricks===
 +
Add an Unreplied tab to the navbar : [https://meta.discourse.org/t/reply-reminder-remind-users-to-reply-to-new-users-topics-with-zero-replies/42644/2]
 +
 
 +
 
 +
====Execute migration script====
 +
 
 +
<syntaxhighlight lang="bash">
 +
/var/discourse/launcher enter web_only
 +
# Install required dependencies to import data (gems)
 +
su discourse -c "export IMPORT=1; bundle config unset deployment; bundle config set path 'vendor/bundle'; bundle config set without 'test development'; bundle install --jobs 4"
 +
# Run import script
 +
su discourse -c 'export IMPORT=1; cp /scripts/kunena3_dolibarr_de.rb /var/www/discourse/script/import_scripts/kunena3_dolibarr_de.rb; bundle exec ruby /var/www/discourse/script/import_scripts/kunena3_dolibarr_de.rb'
 +
</syntaxhighlight>
 +
 
 +
Note :
 +
 
 +
====Restaure Discourse backup from command line====
 +
 
 +
<syntaxhighlight lang="bash">
 +
/var/discourse/launcher enter web_only
 +
su discourse -c 'bundle exec ruby script/discourse restore forum-dolibarr-france-2019-08-07-080937-v20190731090219.tar'
 +
</syntaxhighlight>
 +
 
 +
You must of course replace <code>forum-dolibarr-france-2019-08-07-080937-v20190731090219.tar</code> by the backup filename to restore.
 +
 
 +
Note : to restore a save from a multisite install that is not the main (first) database, prepend the command by <code>RAILS_DB=dolibarrde</code> where <code>dolibarrde</code> is the name of the database :
 +
 
 +
<syntaxhighlight lang="bash">
 +
/var/discourse/launcher enter web_only
 +
su discourse -c 'RAILS_DB=dolibarrde bundle exec ruby script/discourse restore dolibarr-germany-forum-2020-08-16-163120-v20200814081437.sql.gz'
 +
</syntaxhighlight>
 +
 
 +
===Docker tips and tricks===
 +
The main and recommended way to Install Discourse is using Docker containers system (it contains everything required to run Discourse : Ruby, Sidekiq, Redis, PostgreSQL with the appropriate version and does not mess with the host data).
 +
 
 +
The [https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md#install-docker--git quick start guide] is great for installation.
 +
 
 +
 
 +
Data that should be preserved when the containers die (PostgreSQL database data files, users uploads, etc.), are persisted on the host.
   −
*For [https://www.mailgun.com/ Mailgun], [https://www.mailgun.com/pricing first 10 000 emails every month free (+5$ by 10 000 email)]
+
The default mount point for all persisted data related to Discourse is through
    +
<code>/var/discourse/shared/data</code> and <code>/var/discourse/shared/web-only</code>
   −
==PostgreSQL tips and trick==
+
===PostgreSQL tips and tricks===
   −
===Allow PostgreSQL to be accessed from an external application===
+
====Allow PostgreSQL to be accessed from an external application====
    
''Useful to be able to access the database from a graphical client (like pgAdmin 4, TablePlus or Postico for example).''
 
''Useful to be able to access the database from a graphical client (like pgAdmin 4, TablePlus or Postico for example).''
   −
1. Expose the 5432 TCP port from the container to the host by adding this line to the '''<code>expose:</code>''' section of <code>containers/app.yml</code> :
+
1. Expose the 5432 TCP port from the container to the host by adding this line to the '''<code>expose:</code>''' section of <code>/var/discourse/containers/app.yml</code> :
 +
<syntaxhighlight lang="yaml">
 
  - "5432:5432"
 
  - "5432:5432"
 +
</syntaxhighlight>
 
2. Rebuild the container to take into account modifications to '''<code>app.yml</code>''' :
 
2. Rebuild the container to take into account modifications to '''<code>app.yml</code>''' :
  ./launcher rebuild app
+
<syntaxhighlight lang="bash">
 +
cd /var/discourse
 +
  ./launcher rebuild data
 +
</syntaxhighlight>
 
3. Enter into the container, login as the default postgresql user, add a new user and grant it all perms to the database
 
3. Enter into the container, login as the default postgresql user, add a new user and grant it all perms to the database
  ./launcher enter app
+
<syntaxhighlight lang="bash">
 +
cd /var/discourse
 +
  ./launcher enter data
 
  sudo -u postgres psql discourse
 
  sudo -u postgres psql discourse
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="sql">
 
  CREATE USER my_username WITH PASSWORD 'my_password';
 
  CREATE USER my_username WITH PASSWORD 'my_password';
 
  GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO my_username;
 
  GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO my_username;
Line 370: Line 948:  
  GRANT ALL PRIVILEGES ON DATABASE discourse to my_username;
 
  GRANT ALL PRIVILEGES ON DATABASE discourse to my_username;
 
  \q
 
  \q
 +
</syntaxhighlight>
    
Refer to [https://tableplus.io/blog/2018/04/postgresql-how-to-grant-access-to-users.html PostgreSQL - How to grant access to users?] for more info.
 
Refer to [https://tableplus.io/blog/2018/04/postgresql-how-to-grant-access-to-users.html PostgreSQL - How to grant access to users?] for more info.
   −
===Dumping database===
+
====Dumping database====
 +
 
 +
=====Using <code>pg_dump</code> to dump the database=====
 +
 
 +
Below syntax assume that a custom pgsql account has been created prior to running the command and that port 5432 of PostgreSQL is correctly forwarded from the container to the host (following [[#Allow PostgreSQL to be accessed from an external application]] section instructions).
   −
====Use <code>pg_dump</code> to dump the database====
+
The below command is executed from the host.
    +
<syntaxhighlight lang="bash">
 
  pg_dump -h 127.0.0.1 -d discourse -U my_username -W > discourse-backup-20190801.sql
 
  pg_dump -h 127.0.0.1 -d discourse -U my_username -W > discourse-backup-20190801.sql
 +
</syntaxhighlight>
   −
====Use discourse internal backup tool====
+
=====Using discourse internal backup tool=====
   −
It is also possible to use Discourse internal backup tool to grab a backup of the Discourse instance.
+
It is also possible to use Discourse internal backup tool to grab a backup (database + users uploads) of the Discourse instance.
    
Just go to <code>Admin → Backup</code>
 
Just go to <code>Admin → Backup</code>