Thursday, December 31, 2015

Using a portable SMTP relay server with docker

I have had a very busy year and had the chance to work on a lot of new and useful docker containers. Taking advantage of these holidays, I finally started to catch up here with my latest work on them :D

There's one thing that it's a pretty common requirement of a website: a SMTP email server or relay.
Every web app needs one for different tasks, like sending out notifications, registration emails, password resets, etc. I made a Postfix SMTP relay container that is easy to use with other containers.

Before running the container, first you need to set the following environment variables to configure the SMTP relay host:
  • SMTP_SERVER: Server address of the SMTP server that will send email from our postfix container.
  • SMTP_USERNAME: Username to authenticate with.
  • SMTP_PASSWORD: Password of the SMTP user.
  • SERVER_HOSTNAME: Server hostname for the Postfix container. Emails will appear to come from this hostname domain.
To use it you need to first pull the image:
docker pull juanluisbaptiste/postfix
and then fire it up with the previous variables defined:
docker run -d --name postfix -P \
       -e SMTP_SERVER=smtp.bar.com \
       -e SMTP_USERNAME=foo@bar.com \
       -e SMTP_PASSWORD=XXXXXXXX \
        -e SERVER_HOSTNAME=helpdesk.mycompany.com \        
        juanluisbaptiste/postfix
Lastly, link your container against it:
docker run --name mycontainer --link "postfix:postfix" myimage

Using docker-compose

Or, you could use docker-compose to start your application containers linked against the postfix container with one command. Suppose you have a web application that links against a database and this postfix container. Download and install docker-compose for your platform, and then on your website's docker project, create a new file called docker-compose.yml, and put the following contents there:
myapp:
  build: myapp
  ports:
  - "80:80"
# If running behind a proxy container, expose the ports instead
# and link the proxy container to this one.
#  expose:
#  - "80"
  links:
  - mariadb:mariadb
  - postfix:postfix
  volumes_from:
  - data
mariadb:
  image: centos/mariadb:latest
  expose:
  - "3306"
  volumes_from:
  - data
  environment:
      MYSQL_ROOT_PASSWORD: changeme
postfix:
   image: juanluisbaptiste/postfix:latest
   expose:
   - "25"
  environment:
      SMTP_SERVER: smtp.mycompany.com
      SMTP_USERNAME: user@mycompany.com
      SMTP_PASSWORD: changeme
      SERVER_HOSTNAME: helpdesk.mycompany.com
data:
  image: centos:latest
  volumes:
  - /var/lib/mysql
  - /var/www/webapp

  command: /bin/true
Then, you can launch your webapp, the database and the postfix container with this command:
docker-compose up
All containers will be started in the right order and the webapp will be linked against the mariadb and postfix containers. Also, the webapp and the mariadb database container will share the same data volume container (unrelated to the postfix container but a good practice).

On thing to note, this container doesn't enable client SMTP authentication, the idea is to expose the port 25 to containers, and then link the containers that need a SMTP service against it so the relay isn't publicly exposed.

A note about using gmail as a relay

Since last year, Gmail by default does not allow email clients that don't use OAUTH 2
for authentication (like Thunderbird or Outlook). First you need to enable access to "Less secure apps" on your google settings.

Also take into account that email From: header will contain the email address of the account being used to authenticate against the Gmail SMTP server (SMTP_USERNAME), the one on the email will be ignored by Gmail.

Friday, February 13, 2015

Setting up a BigBlueButton 0.81 docker container: Part 2

I have made some improvements on my BigBlueButton docker images since I last posted about that. Now, the container can be accessed externally and not only through the private IP address docker assigns to it (by default in 172.17.0.x range) as before. For this to work, the SERVER_NAME env variable must be set pointing to the hostname that is going to be used to access your BigBlueButton container. Now, the container can be started like this:

sudo docker run -d --name bbb -p 80:80 -p 9123:9123 -p 1935:1935 -e SERVER_NAME=meeting.somedomain.com bbb_0.81

Then you can access the container externally (provided SERVER_NAME resolves to a public IP address) using $SERVER_NAME. The hostname set in SERVER_NAME must point to the docker host machine. If the container can't use the same host ports (ie: there's already a web server running on port 80) you can start the container using other ports:

sudo docker run -d --name bbb -p 80:8080 -p 9123:91230 -p 1935:19350 -e SERVER_NAME=meeting.somedomain.com bbb_0.81
And configure a reverse proxy server (like nginx) to go to the BigBlueButton's container private IP address and the new http port in the docker run command when accessing SERVER_NAME, and port forward ports 1935 and 9123 on the docker host machine to the container. Or even easier, use a nginx container and link it to the BigBlueButton container but this deserves another post.

More detailed instructions in the github project page.