We removed our free Sandbox April 25th.
You can read more on our blog.

SMTP

Introduction

Our SMTP service is based on Postfix. It can receive e-mails from your instances, and forward them:

  • either to their final destination (e.g., if you send an e-mail to someone@gmail.com, send it to GMail servers);
  • or to a relay or smarthost like SendGrid, CritSend, or others. DotCloud uses (and recommends!) MailGun for that purpose.

If the destination server is down, instead of bouncing an error message to the sender immediately, the MTA will keep it into a queue, and retry to deliver it at regular intervals. If the delivery still fails after a while (it can be hours or even days, depending of the setup), it will give up and send you back an error message. This mechanism allows for mail servers to be down for short period of time, or to do throttling (stop accepting new messages) when they are overloaded, for instance.

Note

Why should I use a SMTP service?

If SMTP services were bundled with web application servers, you could experience the following issue:

  1. At normal time, you have 4 web frontends.
  2. Due to a peak of activity, you scale to 10 frontends.
  3. Instance #7 sends a notification e-mail to some user.
  4. The e-mail server of this user is temporarily down, causing instance #7 to spool the message.
  5. The activity goes back to normal, and you want to scale down.
  6. Ah, wait, you can’t scale down as long as you have pending messages in instances: they would be lost!

That’s why scalable web applications need to decouple things as much as possible – and SMTP servers are just one of the many places where it is required.

Note

Why should I use a service like MailGun instead of, e.g., SES?

SES is a basic outgoing email service. Mailgun is a complete email platform which one can easily build Gmail-like service on top of.

Even when looking only from outgoing email perspective, Mailgun gives developers full reputation isolation and control over their mailing queue.

Deploying

To include a SMTP service in your stack, just add a section like the following one in your Build File:

mailer:
  type: smtp

Warning

The default configuration will try to send e-mails directly to their destination. A lot of e-mail providers will systematically flag messages coming from the cloud as “spam”. You can still use this default configuration for testing purposes, but when going into production, you should rely on a third-party mail routing service.

You can use a third-party relay (also called a “smarthost”) if it supports standard SMTP routing (most services do). The parameters must be specified in the Build File.

Here is an example with MailGun:

mailer:
  type: smtp
  config:
    smtp_relay_server: smtp.mailgun.org
    smtp_relay_port: 587
    smtp_relay_username: postmaster@yourmailgundomain.com
    smtp_relay_password: YourMailgunPassword

Note

The smtp_relay_port, smtp_relay_username and smtp_relay_password are optional arguments here.

Warning

The config dictionnary of a stateful service is applied when your Service is launched for the first time. If you change it, you will need to destroy the concerned service and push your application again to apply the changes.

Using Your New SMTP Service

There are two ways to use your new SMTP service:

  • by entering its address, port, etc. in the local SMTP configuration for each other service (PHP, Ruby, Python, Java, and so on); to relay them to the SMTP service.
  • by sending your messages directly to it, from your code.

Note

Why can’t I send my messages directly to, e.g., SendGrid?

Well, you can. As explained above, the whole point of using your own dotCloud SMTP relay is to prevent messages from lingering in the local SMTP queue, where they could be lost if the service scales down. If you are 100% sure that SendGrid will accept your messages 100% of the time, you can configure the local SMTP relays to use SendGrid servers (or send to SendGrid directly from your code).

Get Your SMTP Service Parameters

You can retrieve all the parameters with “dotcloud info”, like this:

$ dotcloud info ramen.mailer
cluster: wolverine
config:
    smtp_password: _|KZ&CKWa[
name: ramen.mailer
namespace: ramen
ports:
-   name: smtp
    url: smtp://dotcloud:_|KZ&CKWa[@mailer.ramen.dotcloud.com:1587
-   name: ssh
    url: ssh://dotcloud@mailer.ramen.dotcloud.com:1586
type: smtp

In that case, the parameters are:

  • login: dotcloud
  • password: _|KZ&CKWa[
  • host: mailer.ramen.dotcloud.com
  • port: 1587

Configure the Local MTA to Use Your SMTP Service

All our services come with a built-in MTA listening on localhost. You can specify a smarthost (SMTP relay) for this MTA when you deploy the service.

Note

You cannot yet reconfigure a running service. You have to destroy it and re-deploy a new one for now. Sorry about that.

The configuration format is the same for all images. A short example is worth one thousand words:

www:
  type: php
  config:
    smtp_server: mailer.ramen.dotcloud.com
    smtp_port: 1587
    smtp_username: dotcloud
    smtp_password: _|KZ&CKWa[

Note

If you want to use your SendGrid/CritSend/MailGun/etc. account, you can do it there. Just put the right parameters at the right place.

Warning

The config dictionnary of a stateful service is applied when your Service is launched for the first time. If you change it, you will need to destroy the concerned service and push your application again to apply the changes.

You can then use default mail functions in your code. If a programming language or framework asks you a specific SMTP server address, use “localhost”.

Send Your Messages Directly Through Your SMTP Service

If you don’t want to go through the local MTA, you can use the parameters retrieved with “dotcloud info”. You will need to pass them to the mail() function (or its equivalent) directly in your code.

It is probably easier to configure the local MTA to relay to your SMTP service, since it means that you won’t have to change your code between different environments.

Note

For your reference, the SMTP service only supports the CRAM-MD5 authentication method. Any decent SMTP library will automatically detect and use this authentication method.

Troubleshooting

You can check if Postfix is running and display the status of its different queues with:

$ dotcloud status ramen.mailer

You can read Postfix’s e-mails logs with:

$ dotcloud logs ramen.mailer

Press Ctrl+C to stop watching the logs.

You can always restart Postfix with:

$ dotcloud restart ramen.mailer

Receiving Mails

The SMTP service cannot receive messages coming from the outside. However, if you need to handle those, we suggest you have a look at excellent third party services like MailGun. Incoming mails can be:

  • routed to a URL in your app;
  • stored in a mailbox, which can be accessed using an API.

Don’t hesitate to have a look at MailGun documentation for receiving and parsing mail to see how easy it is to handle incoming mails!