Skip to content

Standalone mjml server, listening on port 8080/tcp.

License

Notifications You must be signed in to change notification settings

jonnitto/mjml-server

Repository files navigation

MJML docker microservice / server

Standalone mjml server, listening on port 8080/tcp.

Due to various challenges this image supports the following features:

  • Clean and fast shutdowns on docker.
  • Simple CORS capabilities.
  • Small footprint (at least in a npm way).
  • Supports healthchecks.
  • Supports change of mjml config in the request

Overview

This image spools up a simple mjml server instance, listening to port 8080/tcp per default.

Due to GDPR / DSGVO reasons I required the mjml instance to be under my own control, as the processing personal information is processed in mail content generation.

Starting the image is as easy as running a test instance through docker

docker run -it --rm jonnitto/mjml-server

or docker-compose with the following example:

services:
  mjml:
    image: jonnitto/mjml-server
    # environment:
    # to change the port:
    #   - PORT=8081
    # for development, uncomment the following lines:
    #   - CORS=*
    #   - MJML_KEEP_COMMENTS=true
    #   - MJML_VALIDATION_LEVEL=strict
    #   - MJML_MINIFY=false
    #   - MJML_BEAUTIFY=true

Defaults

The production defaults, without any override, default to:

CORS ""
MJML_CONFIG_CONIG "false"
MJML_KEEP_COMMENTS "false"
MJML_VALIDATION_LEVEL "soft"
MJML_MINIFY "true"
MJML_BEAUTIFY "false"
HEALTHCHECK "true"
CHARSET "utf8"
DEFAULT_RESPONSE_CONTENT_TYPE "text/html; charset=utf-8"

Development

For development environments I would suggest to switch it to

CORS "*"
MJML_KEEP_COMMENTS "true"
MJML_VALIDATION_LEVEL "strict"
MJML_MINIFY "false"
MJML_BEAUTIFY "true"
HEALTHCHECK "false"

This will escalate any issues you have with invalid mjml code to the docker log (stdout or docker-compose logs).

Install community components

If you want to add community components you can define MJML_CONFIG_CONIG as JSON. If you want, for example add the mj-chartjs component, you can define the variable like this:

MJML_CONFIG_CONIG "{\"packages\":[\"mjml-chartjs/lib/MjChartjs.js\"]}"

API

An api call should look like this:

  const mjml = '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>';
  const endpoint = 'http://YOUR_ENDPOINT';
  const port = '8080'
  // Override configuration from enviroment or https://github.com/mjmlio/mjml/blob/master/packages/mjml-core/src/index.js#L101-L124
  const config = {
    beautify: false,
    minify: true,
    validationLevel: 'strict',
    fonts: {},
  }

  fetch(`${endpoint}:${host}`, {
      method: 'POST',
      headers: {
            'Content-Type': 'application/json; charset=utf-8'
      },
      body: JSON.stringify({ mjml, config })
})

or with PHP and Guzzle

use GuzzleHttp\Pool;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;

$client = new Client();

$request = new Request(
  "POST",
  "http://YOUR_ENDPOINT:8080/",
  [
      "Content-Type" => "application/json; charset=utf-8"
  ],
  "{\"mjml\":\"<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>\",\"config\":{\"fonts\":{},\"validationLevel\":\"strict\",\"keepComments\":false,\"beautify\":false,\"minify\":false}}");

$response = $client->send($request);

But you can use any language you want to create the request

Useage togehter with ddev

I you use ddev for development like me, you can add this service like that:

Create a file called docker-compose.mjml.yaml in you .ddev folder:

services:
  mjml:
    container_name: ddev-${DDEV_SITENAME}-mjml
    hostname: ${DDEV_SITENAME}-mjml
    image: jonnitto/mjml-server
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: $DDEV_APPROOT
    environment:
      - CORS=*
      - HEALTHCHECK=false

Add a enviroment variable in you config.yaml:

web_environment:
  - MJML_API_ENDPOINT=ddev-${DDEV_SITENAME}-mjml:8080

Now you can use the enviroment variable MJML_API_ENDPOINT as your endpoint.