{"id":13558288,"url":"https://github.com/mlandauer/cuttlefish","last_synced_at":"2025-04-11T20:38:40.444Z","repository":{"id":7754567,"uuid":"9122188","full_name":"mlandauer/cuttlefish","owner":"mlandauer","description":"Transactional email server with a lovely web interface","archived":false,"fork":false,"pushed_at":"2024-06-27T03:33:49.000Z","size":26769,"stargazers_count":1584,"open_issues_count":149,"forks_count":178,"subscribers_count":62,"default_branch":"master","last_synced_at":"2025-04-03T23:08:17.070Z","etag":null,"topics":["cross-platform","email","email-sender","mta","ruby-on-rails","transactional-emails"],"latest_commit_sha":null,"homepage":"http://cuttlefish.io","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mlandauer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-03-30T21:30:54.000Z","updated_at":"2025-03-31T09:24:27.000Z","dependencies_parsed_at":"2024-06-27T05:29:00.176Z","dependency_job_id":"6eba7e07-571d-4534-bc77-d55c57d7cd58","html_url":"https://github.com/mlandauer/cuttlefish","commit_stats":{"total_commits":2689,"total_committers":16,"mean_commits":168.0625,"dds":0.612495351431759,"last_synced_commit":"df337581a158480a4ddddfa8aab341679df005b7"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlandauer%2Fcuttlefish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlandauer%2Fcuttlefish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlandauer%2Fcuttlefish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlandauer%2Fcuttlefish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mlandauer","download_url":"https://codeload.github.com/mlandauer/cuttlefish/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248478130,"owners_count":21110642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cross-platform","email","email-sender","mta","ruby-on-rails","transactional-emails"],"created_at":"2024-08-01T12:04:51.756Z","updated_at":"2025-04-11T20:38:40.422Z","avatar_url":"https://github.com/mlandauer.png","language":"Ruby","funding_links":[],"categories":["Ruby","Sending","others","网络服务","Open-Source Tools"],"sub_categories":["SMTP Server","网络服务_其他"],"readme":"# ![Cuttlefish](https://raw.github.com/mlandauer/cuttlefish/master/app/assets/images/cuttlefish_80x48.png) Cuttlefish\n\n[![Build Status](https://travis-ci.com/mlandauer/cuttlefish.svg?branch=master)](https://travis-ci.com/mlandauer/cuttlefish) [![Coverage Status](https://coveralls.io/repos/github/mlandauer/cuttlefish/badge.svg?branch=master)](https://coveralls.io/github/mlandauer/cuttlefish?branch=master) [![Maintainability](https://api.codeclimate.com/v1/badges/abe94fb0811e8e8c512a/maintainability)](https://codeclimate.com/github/mlandauer/cuttlefish/maintainability)\n\n* Project site: [cuttlefish.io](https://cuttlefish.io)\n* Github repo:  [github.com/mlandauer/cuttlefish](https://github.com/mlandauer/cuttlefish)\n\nCuttlefish is a lovely, easy to set up transactional email server\n\nSending 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?\n\nLet's make sending lots of emails fun again!\n\nAnd without the hidden dangers of vendor lock in of commercial transactional email services.\n\n* Send email from your application using smtp in the usual way and get all sorts of added benefits for no effort\n* A lovely web UI to browse what's happening\n* Monitor in real time which emails arrive at their destination and which bounce\n* Works with any web framework and language\n* Automatically not send emails to destinations that have hard bounced in the past\n* Track which emails are opened and which links are clicked\n* Statistics on emails sent, soft/hard bounced and held back\n* View the full email content for recently sent emails\n* Multiple applications can each have their own SMTP authentication\n* [GraphQL](https://graphql.org/) API where anything you can do in the admin UI can do with the API\n* Web callbacks on successful or failed deliveries of emails\n* Check your IP reputation with one click\n* Easy to install and get going quickly\n* Built in, super easy to set up, automatic DKIM signing\n* Postfix, which you know and trust, handles email delivery\n* Open source, so no vendor lock in.\n\nCuttlefish is in beta. It's been used in production by [OpenAustralia Foundation](http://www.openaustraliafoundation.org.au)'s projects for many years and sends over a million emails per month.\n\n## Screenshots\n\n![Sign up](https://raw.github.com/mlandauer/cuttlefish/master/app/assets/images/screenshots/1.png)\n![Dashboard](https://raw.github.com/mlandauer/cuttlefish/master/app/assets/images/screenshots/2.png)\n![Email](https://raw.github.com/mlandauer/cuttlefish/master/app/assets/images/screenshots/3.png)\n\n## Things on the cards\n\n* \"out of office\" and bounce reply filtering\n* Incoming email\n\n## Dependencies\nRuby, PostgresQL, Redis (2.4 or greater), Postfix\n\nAlso you need the following libraries:\nimagemagick, libmagickwand-dev, libpq-dev\n\nFor development, however, the only dependencies are Docker and Docker compose.\n\n## Development\n\nSetting up a local development environment with all the correct dependencies and\nmoving parts is now very straightforward by using [Docker](https://www.docker.com/).\n\nTo start with:\n```\ndocker compose run web bundle exec rake db:create db:schema:load\n```\n\nNow add some example seed data. This will also create a site admin with email \"joy@smart-unlimited.com\" and password \"password\". You'll need these details later to sign in. Skip this step if you don't want seed data.\n\n```\ndocker compose run web bundle exec rake db:seed\n```\n\nThen\n```\ndocker compose up\n```\n\nThose steps will take a little while as they download images and build\nthe docker containers.\n\nWhen its stops spitting output to the console point your web browser at\n\nhttp://localhost:3000\n\nIf you've used the `db:seed` task to populate the development database you can now log in using the email \"joy@smart-unlimited.com\" with the password \"password\".\n\nFor development all mail sent out by Cuttlefish will actually go to mailcatcher.\nTo see the mailcatcher mail:\n\nhttp://localhost:1080\n\nTo run the tests (do that from another window):\n```\ndocker compose exec web rake\n```\n\n## To install:\n\nWe use [Vagrant](https://www.vagrantup.com/) and [Ansible](http://docs.ansible.com/) 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\nparts but all of this is with the purpose of making it easier for the developer sending mail.\n\nThese instructions are specifically for installing the server at https://cuttlefish.oaf.org.au.\n\nCurrently the setup requires a relatively old version of Ansible (2.5.0) using Python 2.7.\n\n### To install to a local test virtual machine\n\n1. 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`.\n\n2. Download base box and build virtual machine with everything needed for Cuttlefish. This will take a while (at least 30 mins or so)\n```\nvagrant up\n```\n\n3. 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.\n```\nbundle exec cap --set-before local_deploy=true deploy:setup deploy:cold foreman:export foreman:start\n```\n\n4. Add to your local `/etc/hosts` file\n```\n127.0.0.1       cuttlefish.oaf.org.au\n```\n\n5. Point your web browser at https://cuttlefish.oaf.org.au:8443/\n\n### To install on [Linode](https://www.linode.com/)\n\n1. Login at the [Linode Manager](https://manager.linode.com/)\n\n2. [Add a new Linode](https://manager.linode.com/linodes/add)\n\n3. Select \"Linode 8GB\" at location \"Fremont, CA\"\n\n4. Select your new Linode in the dashboard\n\n5. Click \"Deploy a Linux Distribution\". Choose \"Ubuntu 16.04 LTS\" and choose a root password. Leave everything as default.\n\n6. Click \"Boot\" and wait for it to start up\n\n8. Update `provisioning/hosts` with the name of your server (e.g. li123-45.members.linode.com)\n\n9. 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`.\n\n10. 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:\n\n```\n./provision_production.sh\n```\n\n11. Update the server name in `config/deploy.rb`\n\n12. 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\n```\ncap deploy:setup\ncap deploy:cold\ncap foreman:export\ncap foreman:restart\n```\n\n13. At this stage you might want to snapshot the disk\n\n14. Make sure that DNS for cuttlefish.oaf.org.au points to the server ip address\n\n14. Point your browser at https://cuttlefish.org.au\n\nAt this point you should have a basic working setup. You should be able to send test mail and see it getting delivered.\n\nSome further things to ensure things work smoothly\n\n1. Add DNS TXT record for cuttlefish.oaf.org.au with \"v=spf1 ip4:your.server.ip4.address ip6:your.server.ip6.address -all\"\n\n2. 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\n\n2. Ensure that the devise email address is set to contact@cuttlefish.oaf.org.au\n\n3. 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](https://en.wikipedia.org/wiki/Feedback_loop_%28email%29).\n\n## Deploying to production\n\nOne gotcha is that we're still on Capistrano 2 which doesn't apply database migrations\nby default on deploys.\n\nFor normal deploys\n```\ncap deploy\n```\n\nTo rollback a failed deploy\n```\ncap deploy:rollback\n```\n\nTo deploy and run the migrations\n```\ncap deploy:migrations\n```\n\n## Screenshots\nDone some development work which updates the look of the main pages? To update the screenshots\n```\nbundle exec rspec spec/features/screenshot_feature.rb\n```\nThen commit the results\n\n## How to contribute\n\nIf you find what looks like a bug:\n\n* Check the [GitHub issue tracker](http://github.com/mlandauer/cuttlefish/issues/)\n  to see if anyone else has reported issue.\n* If you don't see anything, create an issue with information on how to reproduce it.\n\nIf you want to contribute an enhancement or a fix:\n\n* Fork the project on GitHub.\n* Make your changes with tests.\n* Commit the changes without making changes to any files that aren't related to your enhancement or fix.\n* Send a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlandauer%2Fcuttlefish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmlandauer%2Fcuttlefish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlandauer%2Fcuttlefish/lists"}