{"id":24883072,"url":"https://github.com/jonnitto/mjml-server","last_synced_at":"2026-05-10T09:37:39.517Z","repository":{"id":274660408,"uuid":"923554474","full_name":"jonnitto/mjml-server","owner":"jonnitto","description":"Standalone mjml server, listening on port 8080/tcp.","archived":false,"fork":false,"pushed_at":"2025-03-03T16:41:23.000Z","size":142,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-19T04:13:32.837Z","etag":null,"topics":["docker","docker-image","email","mjml"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonnitto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2025-01-28T13:10:05.000Z","updated_at":"2025-02-28T13:14:35.000Z","dependencies_parsed_at":"2025-01-28T17:23:50.861Z","dependency_job_id":"446f75f0-3ff8-4673-8f9d-1e6107e5c88d","html_url":"https://github.com/jonnitto/mjml-server","commit_stats":null,"previous_names":["jonnitto/mjml-server","carbonpackages/mjml-server"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonnitto%2Fmjml-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonnitto%2Fmjml-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonnitto%2Fmjml-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonnitto%2Fmjml-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonnitto","download_url":"https://codeload.github.com/jonnitto/mjml-server/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245806459,"owners_count":20675300,"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":["docker","docker-image","email","mjml"],"created_at":"2025-02-01T13:18:05.105Z","updated_at":"2026-05-10T09:37:34.472Z","avatar_url":"https://github.com/jonnitto.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MJML docker microservice / server\n\nStandalone [mjml](http://mjml.io) server, listening on port 8080/tcp.\n\nDue to various challenges this image supports the following features:\n\n- Clean and fast shutdowns on docker.\n- Simple CORS capabilities.\n- Small footprint (at least in a npm way).\n- Supports healthchecks.\n- Supports change of mjml config in the request\n\n## Overview\n\nThis image spools up a simple mjml server instance, listening to port 8080/tcp per default.\n\nDue 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.\n\nStarting the image is as easy as running a test instance through docker\n\n```sh\ndocker run -it --rm jonnitto/mjml-server\n```\n\nor `docker-compose` with the following example:\n\n```yml\nservices:\n  mjml:\n    image: jonnitto/mjml-server\n    # environment:\n    # to change the port:\n    #   - PORT=8081\n    # for development, uncomment the following lines:\n    #   - CORS=*\n    #   - MJML_KEEP_COMMENTS=true\n    #   - MJML_VALIDATION_LEVEL=strict\n    #   - MJML_MINIFY=false\n    #   - MJML_BEAUTIFY=true\n```\n\n## Defaults\n\nThe production defaults, without any override, default to:\n\n```sh\nCORS \"\"\nMJML_CONFIG_CONIG \"false\"\nMJML_KEEP_COMMENTS \"false\"\nMJML_VALIDATION_LEVEL \"soft\"\nMJML_MINIFY \"true\"\nMJML_BEAUTIFY \"false\"\nHEALTHCHECK \"true\"\nCHARSET \"utf8\"\nDEFAULT_RESPONSE_CONTENT_TYPE \"text/html; charset=utf-8\"\n```\n\n## Development\n\nFor development environments I would suggest to switch it to\n\n```sh\nCORS \"*\"\nMJML_KEEP_COMMENTS \"true\"\nMJML_VALIDATION_LEVEL \"strict\"\nMJML_MINIFY \"false\"\nMJML_BEAUTIFY \"true\"\nHEALTHCHECK \"false\"\n```\n\nThis will escalate any issues you have with invalid mjml code to the docker log (`stdout` or `docker-compose logs`).\n\n## Install community components\n\nIf you want to add [community components](https://documentation.mjml.io/#community-components) you can define `MJML_CONFIG_CONIG` as `JSON`. If you want, for example add the\n`mj-chartjs` component, you can define the variable like this:\n\n```sh\nMJML_CONFIG_CONIG \"{\\\"packages\\\":[\\\"mjml-chartjs/lib/MjChartjs.js\\\"]}\"\n```\n\n## API\n\nAn api call should look like this:\n\n```js\n  const mjml = '\u003cmjml\u003e\u003cmj-body\u003e\u003cmj-section\u003e\u003cmj-column\u003e\u003cmj-text\u003eHello World\u003c/mj-text\u003e\u003c/mj-column\u003e\u003c/mj-section\u003e\u003c/mj-body\u003e\u003c/mjml\u003e';\n  const endpoint = 'http://YOUR_ENDPOINT';\n  const port = '8080'\n  // Override configuration from enviroment or https://github.com/mjmlio/mjml/blob/master/packages/mjml-core/src/index.js#L101-L124\n  const config = {\n    beautify: false,\n    minify: true,\n    validationLevel: 'strict',\n    fonts: {},\n  }\n\n  fetch(`${endpoint}:${host}`, {\n      method: 'POST',\n      headers: {\n            'Content-Type': 'application/json; charset=utf-8'\n      },\n      body: JSON.stringify({ mjml, config })\n})\n```\n\nor with PHP and Guzzle\n\n```php\nuse GuzzleHttp\\Pool;\nuse GuzzleHttp\\Client;\nuse GuzzleHttp\\Psr7\\Request;\n\n$client = new Client();\n\n$request = new Request(\n  \"POST\",\n  \"http://YOUR_ENDPOINT:8080/\",\n  [\n      \"Content-Type\" =\u003e \"application/json; charset=utf-8\"\n  ],\n  \"{\\\"mjml\\\":\\\"\u003cmjml\u003e\u003cmj-body\u003e\u003cmj-section\u003e\u003cmj-column\u003e\u003cmj-text\u003eHello World\u003c/mj-text\u003e\u003c/mj-column\u003e\u003c/mj-section\u003e\u003c/mj-body\u003e\u003c/mjml\u003e\\\",\\\"config\\\":{\\\"fonts\\\":{},\\\"validationLevel\\\":\\\"strict\\\",\\\"keepComments\\\":false,\\\"beautify\\\":false,\\\"minify\\\":false}}\");\n\n$response = $client-\u003esend($request);\n```\n\nBut you can use any language you want to create the request\n\n## Useage togehter with ddev\n\nI you use [ddev](https://ddev.com) for development like me, you can add this service like that:\n\nCreate a file called `docker-compose.mjml.yaml` in you `.ddev` folder:\n\n```yaml\nservices:\n  mjml:\n    container_name: ddev-${DDEV_SITENAME}-mjml\n    hostname: ${DDEV_SITENAME}-mjml\n    image: jonnitto/mjml-server\n    labels:\n      com.ddev.site-name: ${DDEV_SITENAME}\n      com.ddev.approot: $DDEV_APPROOT\n    environment:\n      - CORS=*\n      - HEALTHCHECK=false\n```\n\nAdd a enviroment variable in you `config.yaml`:\n\n```yaml\nweb_environment:\n  - MJML_API_ENDPOINT=ddev-${DDEV_SITENAME}-mjml:8080\n```\n\nNow you can use the enviroment variable `MJML_API_ENDPOINT` as your endpoint.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonnitto%2Fmjml-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonnitto%2Fmjml-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonnitto%2Fmjml-server/lists"}