Transactional email server with a lovely web interface
Ruby HTML CSS Shell CoffeeScript JavaScript
Clone or download
Permalink
Failed to load latest commit information.
app Fix pages that show emails to and from particular addresses Jul 19, 2018
bin Run rake rails:update and add files/changes that look OK Nov 7, 2016
config Remove deprecated form of open and click tracking Jun 26, 2018
db Remove foreigner and use built-in foreign key support Nov 7, 2016
lib Remove deprecated form of open and click tracking Jun 26, 2018
log rails new . --skip-test-unit Mar 30, 2013
provisioning Upgrade rvm_io.ruby to same version used by infrastructure repo Jun 26, 2018
public rails new . --skip-test-unit Mar 30, 2013
spec Remove deprecated form of open and click tracking Jun 26, 2018
vendor/assets Add bootstrap extension for making row on table clickable Apr 1, 2013
.env Allow setting of the aws region for the bucket Mar 15, 2017
.gitignore Install ansible galaxy role with standard name to avoid installation … Jun 26, 2018
.rspec Add rspec Mar 30, 2013
.ruby-version Switch to ruby 2.1.5 for development Dec 16, 2014
.travis.yml Try running on container-based Travis to fix failed build Apr 18, 2016
Capfile Move requires to be in the same file Feb 20, 2017
Gemfile Merge remote-tracking branch 'upstream/master' Mar 17, 2017
Gemfile.lock Partial revert. Go back to initial version of eventmachine so we don'… Jun 18, 2018
Guardfile Remove ruby_gntp and don't explicitly specify guard notification Nov 7, 2016
LICENSE.txt Change license to AGPL Jun 6, 2013
Procfile Remove delayed_job gem Jan 12, 2015
Procfile.production Remove delayed_job gem Jan 12, 2015
README.md Revert "Update introduction of readme to be about OAF's Cuttlefish de… May 26, 2018
Rakefile rails new . --skip-test-unit Mar 30, 2013
Vagrantfile vm needs more memory Dec 16, 2014
ansible.cfg Set standard ansible config in ansible.cfg Jun 26, 2018
config.ru rails new . --skip-test-unit Mar 30, 2013
cuttlefish.sublime-project change signature method Apr 10, 2013
provision_production.sh Set standard ansible config in ansible.cfg Jun 26, 2018

README.md

Stories in Ready

Cuttlefish Cuttlefish

Build Status Coverage Status Code Climate

Cuttlefish is a lovely, easy to set up transactional email server

Sending a few emails from your app is easy. Sending lots becomes painful. There are so many hidden gotchas. Do your emails get delivered? Are you being considered a spammer? What about all those bounced emails?

Let's make sending lots of emails fun again!

And without the hidden dangers of vendor lock in of commercial transactional email services.

  • Send email from your application using smtp in the usual way and get all sorts of added benefits for no effort
  • A lovely web UI to browse what's happening
  • Monitor in real time which emails arrive at their destination and which bounce
  • Works with any web framework and language
  • Automatically not send emails to destinations that have hard bounced in the past
  • Track which emails are opened and which links are clicked
  • Statistics on emails sent, soft/hard bounced and held back
  • View the full email content for recently sent emails
  • Multiple applications can each have their own SMTP authentication
  • Check your IP reputation with one click
  • Easy to install and get going quickly
  • Built in, super easy to set up, automatic DKIM signing
  • Postfix, which you know and trust, handles email delivery
  • Open source, so no vendor lock in.

Cuttlefish is in beta. It's been used in production on three of OpenAustralia Foundation's project for over a year and has sent well over 2 million emails.

##Screenshots

Sign up Dashboard Email

##Things on the cards

  • REST API for deep integration with your application
  • Web callbacks on succesful delivery, hard bounces, open and click events
  • "out of office" and bounce reply filtering
  • Incoming email

Dependencies

Ruby 2.1.5, MySQL, Redis (2.4 or greater), Postfix (Postfix is optional for local development or just trying it out. Some things like the email deliverability just won't show anything)

Also you need the following libraries: imagemagick, libmagickwand-dev, libmysqld-dev

To install:

We use Vagrant and Ansible to automatically set up a fresh server with everything you need to run Cuttlefish. It's a fairly complicated affair as Cuttlefish does have quite a few moving parts but all of this is with the purpose of making it easier for the developer sending mail.

These instructions are specifically for installing the server at https://cuttlefish.oaf.org.au.

To install to a local test virtual machine

  1. Create a file ~/.cuttlefish_ansible_vault_pass.txt which contains the password for encrypting the secret values used in the deploy. The encrypted variables are at provisioning/roles/cuttlefish-app/vars/main.yml.

  2. Download base box and build virtual machine with everything needed for Cuttlefish. This will take a while (at least 30 mins or so)

vagrant up
  1. Deploy the application. As this is the first deploy it will take quite a while (5 mins or so). Further deploys will be much quicker. We're using the --set-before local_deploy=true flag to deploy to your local test virtual machine instead of production.
bundle exec cap --set-before local_deploy=true deploy:setup deploy:cold foreman:export foreman:start
  1. Add to your local /etc/hosts file
127.0.0.1       cuttlefish.oaf.org.au
  1. Point your web browser at https://cuttlefish.oaf.org.au:8443/

To install on Linode

  1. Login at the Linode Manager

  2. Add a new Linode

  3. Select "Linode 2048" at location "Fremont, CA"

  4. Select your new Linode in the dashboard

  5. Click "Deploy a Linux Distribution". Choose "Ubuntu 14.04 LTS" and choose a root password. Leave everything as default.

  6. Click "Boot" and wait for it to start up

  7. Update provisioning/hosts with the name of your server (e.g. li123-45.members.linode.com)

  8. Create a file ~/.cuttlefish_ansible_vault_pass.txt which contains the password for encrypting the secret values used in the deploy. The encrypted variables are at provisioning/roles/cuttlefish-app/vars/main.yml.

  9. To provision the server for the first time you will need to supply the root password you chose in step 5. On subsequent deploys you won't need this. To supply this password edit the ./provision_production.sh script and temporily add the --ask-pass argument to the last command, then run the script:

./provision_production.sh
  1. Update the server name in config/deploy.rb

  2. Deploy the application. As this is the first deploy it will take quite a while (5 mins or so). Further deploys will be much quicker

cap deploy:setup
cap deploy:cold
cap foreman:export
cap foreman:restart
  1. At this stage you might want to snapshot the disk

  2. Make sure that DNS for cuttlefish.oaf.org.au points to the server ip address

  3. Point your browser at https://cuttlefish.org.au

At this point you should have a basic working setup. You should be able to send test mail and see it getting delivered.

Some further things to ensure things work smoothly

  1. Add DNS TXT record for cuttlefish.oaf.org.au with "v=spf1 ip4:your.server.ip4.address ip6:your.server.ip6.address -all"

  2. Set up incoming email for cuttlefish.oaf.org.au (In OpenAustralia Foundation's case using Google Apps for domain). Add addresses contact@cuttlefish.oaf.org.au, bounces@cuttlefish.oaf.org.au and sender@cuttlefish.oaf.org.au

  3. Ensure that the devise email address is set to contact@cuttlefish.oaf.org.au

  4. Set up reverse DNS. In the Linode Manager under "Remote Access" click "Reverse DNS" then for the hostname put in "cuttlefish.oaf.org.au" and follow the instructions. This step is necessary in order to be able to sign up to receive Feedback loop emails.

Screenshots

Done some development work which updates the look of the main pages? To update the screenshots

bundle exec rspec spec/features/screenshot_feature.rb

Then commit the results

How to contribute

If you find what looks like a bug:

  • Check the GitHub issue tracker to see if anyone else has reported issue.
  • If you don't see anything, create an issue with information on how to reproduce it.

If you want to contribute an enhancement or a fix:

  • Fork the project on GitHub.
  • Make your changes with tests.
  • Commit the changes without making changes to any files that aren't related to your enhancement or fix.
  • Send a pull request.