Keila - Open Source Mailchimp Alternative Built in Elixir!

Hey folks,

I wanted to share with you a project I’ve been working on for a while: It’s an Open Source (AGPLv3) newsletter tool. Think Mailchimp, but written in Elixir and you can run it on your own server.

Check out the website with a little demo video here:

Recently, people have been talking about the PETAL stack - and it fits Keila quite well: It’s built with Phoenix/Elixir, uses Tailwind for styling, and bit of AlpineJS sprinkled on top of LiveViews.

Developing Keila has been a breeze with the amazing tools from our community.

Here are some of the tools I’m using (on top of the usual suspects like Ecto):

Right now, I’m getting everything ready for the 0.1 release. If you’re curious about the code, check it out on GitHub:

If you have any questions or suggestions, let me know :slight_smile:


I have not tried it yet but it looks like a very good work you have done here.

I would suggest you to set-up Github sponsors for your project.


Thanks for sharing, I will look at this during the weekend as I would be very keen to collaborate on something like this.


Looks really good. I am reading at your git log --reverse


Excellent idea, I will be looking into this! Do you have any experience with GitHub Sponsors so far?

Very cool, please feel free to reach out to me personally :grinning:

1 Like

No, but see how a developer got to make 100k with Github Sponsors, and one if his projects is a port of LiveView to PHP named LiveWire:

1 Like

IIRC he began the project with a closed source and then opened it after hitting his target through GH sponsors. It seems that now he offers training material and support for the sponsors (after opening the source code).

It is a nice story to get inspiration from.

1 Like

Keila v0.1.0 is now out!

The new Markdown editor is powered by LiveView and allows sending of hybrid HTML + Plain Text messages.

From now on, all releases will be available as Docker images on Docker Hub.
There’s now also a Documentation page, so if you want to give Keila a try, here are the installation instructions:

I hope I’ll find some time to blog about some of the challenges and learnings while building Keila so far. The next blog post will probably be on dynamic Ecto queries, but if you have questions about any particular technical aspect, let me know :slight_smile:


Keila 0.5: WYSIWYG, Tracking + Hosted Edition!

Keila 0.5 is now out and there have been a bunch of new features since the last update I posted here!

  • WYSIWYG editor for campaigns
  • Send later feature for campaigns
  • Template editor for creating your own email designs
  • Campaign open/click tracking
  • Easier initial setup + improved dark theme

There’s now also a hosted version of Keila available on
You can try it for free!

If you’re interested in getting a subscription, feel free to PM me first :slight_smile:

Let me know if you have any questions or suggestions! Bug reports and code contributions on GitHub are also always welcome :slight_smile:


Keila 0.8: Revamped UI, Segmentation, Custom Contact Data, API

It’s been a while since I posted an update about Keila here, but that’s only because I forgot to update this post :sweat_smile:

Since 0.5, there have been tons of improvements to Keila, some of the most notable changes are:

There are also some neat improvements for people running their own Keila instance

  • Login-as feature for admins
  • Automated bounce handling with SES
  • Improved official Docker image
  • Running Keila in a subdirectory

And of course Keila has also been upgraded to Phoenix 1.6 and is now using heex templates exclusively :partying_face:

The Shiny New UI

The Segment Editor

Where’s the code? Can I contribute?

You can check out the complete code of Keila on GitHub. Bug reports, feature suggestions, and code contributions are very welcome :slight_smile:

Is there a demo?

If you want to try Keila in action without installing it, you can check out the managed version for free on If you’re interested in getting a subscription, please feel free to PM me.

If you want to install Keila on your own server, check out the installation docs.

GitHub Sponsors

Last but not least, as @Exadra37 suggested in this thread way back in February, you can now also support my work on Keila on GitHub Sponsors :heart:


This looks really slick.

1 Like

Hi, getting this set up and generally got it working. I’m having an issue with keila embedding the port into the Unsubscribe link i.e.:

so when the user clicks on it they see:

An error occurred during a connection to SSL received a record that exceeded the maximum permissible length.


I understand that this is an phoenix config setting but I set up using the docker image so I don’t think I can tweak that, or am I wrong? regards,

Try removing the url: [port: 4040] setting from the Endpoint configuration, if you have it there.

Thanks for the tip. Yeah I guess I will just have to build my own docker image with that tweak to the endpoint.

The official Keila docker image isn’t set up to handle HTTPS termination - so my recommendation would be to use it behind a reverse proxy like Nginx or Traefik.

Ah, I think I misread your question. You can configure the ports for URL generation via environment variables: Configuration - Keila

PORT determines which port Keila listens to and URL_PORT which port is used for URLs. And in case of ports 80 and 443, this is not included in the generated URLs.

Thanks! Thanks for Keila too.



were the changes to the config and the url in the unsubscribe link now looks like:

I am using Traefik as a proxy. To help out anyone else who’d like to have keila behind Traefik, here is my docker-compose.yml:

version: "3"

    image: pentacent/keila:latest
      - "4040:4040"
      - postgres_keila
    build: .
      - .env
      - db-network
      - proxy-network
      - "traefik.enable=true"
      - "traefik.port=4040"
      - "traefik.http.routers.keila_example-com.entrypoints=http"
      - "traefik.http.routers.keila_example-com.rule=Host(``)"
      - "traefik.http.middlewares.keila_example-com-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.keila_example-com.middlewares=keila_example-com-https-redirect"
      - "traefik.http.routers.keila_example-com-secure.entrypoints=https"
      - "traefik.http.routers.keila_example-com-secure.rule=Host(``)"
      - "traefik.http.routers.keila_example-com-secure.tls=true"
      - "traefik.http.routers.keila_example-com-secure.tls.certresolver=http"
      - "traefik.http.routers.keila_example-com-secure.service=keila_example-com"
      - ""
      - ""
    image: postgres:alpine
      - "5432:5432"
      POSTGRES_PASSWORD: postgres
      - db-network

    external: true

This also exposes the Keila to the world without the need to go through Traefik, because its equivalent to "". To be only localhost you need to use instead "", but if the goal is to only have Traefik talking with Keila then you can just simply remove `“4040:4040”.

Regarding Postgres Database you are also exposing it to the world. To communicate with the database from Keila just use the service name postgres_keila has the host on your code, and remove the ports from your docker compose file.


Thanks for the improvements!

1 Like