Add documentation on how to send emails in dev mode

While developing https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/30644 I took some notes internally on how to be able to actually send emails with my gdk installation.

I have included below what we did, if there's any interest I could add an MR to the docs with this info and your suggestions on how to improve it.

How to send emails from gitlab in development mode

gdk is by default not prepared to actually send emails via smtp, that only applies to production mode. In dev mode, gdk uses letter_opener_web to show sent messages in a web interface under http://localhost:3000/rails/letter_opener

In order to enable smtp delivery we have to:

  1. Copy gitlab/config/initializers/smtp_settings.rb.sample to smtp_settings.rb and configure the smtp connection (it is important to comment out the Rails.env.production? conditional):

    # if Rails.env.production?
      Rails.application.config.action_mailer.delivery_method = :smtp
    
      ActionMailer::Base.delivery_method = :smtp
      ActionMailer::Base.smtp_settings = {
        enable: true,
        address: 'smtp.gmail.com',
        port: 587,
        user_name: 'foobar@gmail.com',
        password: 'my-password',
        domain: 'smtp.gmail.com',
        authentication: :login,
        enable_starttls_auto: true,
        tls: false,
        openssl_verify_mode: 'peer', # See ActionMailer documentation for other possible options,
        ca_path: '/usr/local/etc/openssl',
        ca_file: '/usr/local/etc/openssl/cert.pem',
      }
    # end

    In the above snippet:

    • we use gmail as smtp provider (enable 2FA, then create an application password)
    • comment out the Rails.env.production? conditional to enable it in dev too
  2. In gitlab/config/environments/development.rb make sure that ActionMailer logs delivery errors:

    config.action_mailer.raise_delivery_errors = true
  3. Then test the configuration is correctly loaded and try to deliver a message:

    $ bin/rails console
    
    [7] pry(main)> ActionMailer::Base.smtp_settings
    => {:enable=>true,
     :address=>"smtp.gmail.com",
     :port=>587,
     :user_name=>"foobar@gmail.com",
     :password=>"my-password",
     :domain=>"smtp.gmail.com",
     :authentication=>:login,
     :enable_starttls_auto=>true,
     :tls=>false,
     :openssl_verify_mode=>"peer",
     :ca_path=>"/usr/local/etc/openssl",
     :ca_file=>"/usr/local/etc/openssl/cert.pem"}
    
    [8] pry(main)> ActionMailer::Base.delivery_method
    => :smtp
    
    
    [9] pry(main)> Notify.test_email('foobar@gmail.com', 'Hello World', 'This is a test message').deliver_now
    ...
    => #<Mail::Message:70169718084300, Multipart: false, Headers: <Date: Thu, 11 Jul 2019 16:59:49 +0200>, <From: GitLab <example@example.com>>, <Reply-To: GitLab <noreply@example.com>>, <To: foobar@gmail.com>, <Message-ID: <5d274ee5122c6_57a3fd1a782dfd03593e@Ravel.local.mail>>, <Subject: Hello World>, <Mime-Version: 1.0>, <Content-Type: text/html; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>, <Auto-Submitted: auto-generated>, <X-Auto-Response-Suppress: All>>

There's also issues with the OpenSSL certificates in Ruby macOS, so if running in macOS we need to:

  1. Install openssl with brew

    $ brew install openssl
  2. Make sure to include the actual ca_path and ca_file confs in the smtp_settings.rb file as the samples above, or when actually sending the emails we will be getting SSL verification error issues in the gitlab logs