Nginx-based Docker image that serves Decap CMS with a custom S3/MinIO media library plugin.
Decap CMS is a pure frontend SPA — there is no server. It runs entirely in the browser and talks directly to the GitLab API to read/write Markdown files. Authentication uses GitLab PKCE OAuth (no client secret required).
This image packages:
@m11s-io/decap-cms-media-library-s3 plugin (loaded via unpkg)config.yml files from a tenants.json or environment variablesDecap CMS has no built-in S3/MinIO support. The @m11s-io/decap-cms-media-library-s3 plugin fills that gap.
When an editor clicks the media button, the plugin opens a file picker, POSTs the selected file to an upload_url endpoint, and inserts the returned public URL into the content. The upload endpoint is a separate service you run alongside the CMS (e.g. a small Express proxy that signs and forwards to MinIO).
The plugin is loaded as an IIFE before Decap initialises (window.CMS_MANUAL_INIT = true), registered with CMS.registerMediaLibrary, then CMS.init() is called manually. This ordering is required because Decap auto-initialises synchronously on script load and would fail to find the plugin otherwise.
Mount a tenants.json at /etc/decap/tenants.json. The entrypoint generates a separate config.yml and nginx root per hostname.
[
{
"hostname": "cms.example.com",
"gitlabRepo": "myorg/myrepo",
"gitlabBranch": "main",
"gitlabAppId": "abc123",
"uploadUrl": "https://upload.example.com/upload",
"postsFolder": "website/src/content/posts"
},
{
"hostname": "cms.other.com",
"gitlabRepo": "myorg/other",
"gitlabBranch": "main",
"gitlabAppId": "def456",
"uploadUrl": "https://upload.other.com/upload"
}
]
nginx uses a map $host $tenant_root directive to route each hostname to its generated static directory. One container, many tenants.
If no tenants.json is present, configure via environment variables:
docker run -p 80:80 \
-e GITLAB_REPO=myorg/myrepo \
-e GITLAB_BRANCH=main \
-e GITLAB_APP_ID=abc123 \
-e UPLOAD_URL=https://upload.example.com/upload \
-e POSTS_FOLDER=website/src/content/posts \
m11s/decap-cms:latest-s3
The CMS is then available at http://localhost/admin/.
Create a GitLab OAuth application (User Settings → Applications):
http(s)://<your-cms-host>/admin/apiUse the Application ID as GITLAB_APP_ID / gitlabAppId.
The default config.yml.template defines a single posts collection. Set postsFolder per tenant (or POSTS_FOLDER in single-tenant mode) when posts do not live in the repository-root posts directory. For custom collections, mount your own config.yml.template at /etc/decap/config.yml.template using the same ${VAR} placeholders, or provide complete per-tenant configs via a mounted directory.
Content type
Image
Digest
sha256:2a1bd0ca7…
Size
26.5 MB
Last updated
4 months ago
docker pull m11s/decap-cms