Contember
GraphQL-first headless CMS with TypeScript schema definition.
Overview
Contember is a modern GraphQL-first headless CMS that takes a unique schema-first approach, allowing developers to define their content models using TypeScript decorators and classes. Unlike traditional CMSs that require manual database schema management, Contember automatically generates GraphQL APIs, database migrations, and admin interfaces from your TypeScript schema definitions. This approach eliminates the typical disconnect between backend models and frontend requirements while maintaining type safety throughout the entire stack.
This stack combines Contember Engine with PostgreSQL to create a powerful content management foundation where schema changes propagate automatically through the entire system. When you modify your TypeScript schema definitions, Contember generates the necessary database migrations, updates the GraphQL API endpoints, and refreshes the admin interface without manual intervention. PostgreSQL provides the robust relational foundation needed for Contember's advanced features like content versioning, complex relationships, and built-in access control lists.
This combination is ideal for development teams who want the flexibility of headless CMS architecture without sacrificing developer experience or type safety. Frontend developers benefit from strongly-typed GraphQL queries that match their TypeScript models, while backend developers can focus on business logic rather than boilerplate API code. The automatic migration system makes this stack particularly valuable for teams practicing continuous deployment, as schema changes can be version-controlled and deployed with confidence.
Key Features
- TypeScript-first schema definition with automatic GraphQL API generation from decorated classes
- Built-in Access Control Lists (ACL) system with role-based permissions defined in schema
- Automatic database migration generation when TypeScript schema models change
- Content versioning and audit trail tracking all changes with PostgreSQL JSONB storage
- Multi-tenant architecture support with isolated data and configurable permissions
- Real-time GraphQL subscriptions for live content updates using PostgreSQL LISTEN/NOTIFY
- Integrated admin panel SDK that auto-generates forms based on schema definitions
- Advanced PostgreSQL features like full-text search and JSON querying for content fields
Common Use Cases
- 1E-commerce platforms requiring complex product catalogs with custom fields and relationships
- 2Multi-brand corporate websites needing shared content management with tenant isolation
- 3SaaS applications requiring user-generated content with granular permission controls
- 4News and publishing platforms with editorial workflows and content scheduling
- 5API-first development where mobile apps and web frontends share content sources
- 6Rapid prototyping of content-heavy applications with evolving data requirements
- 7Enterprise applications needing audit trails and version control for compliance
Prerequisites
- Minimum 1GB RAM for PostgreSQL operations and Contember Engine compilation
- Docker and Docker Compose with support for depends_on service ordering
- Basic TypeScript knowledge for schema definition and model relationships
- Understanding of GraphQL queries and mutations for API integration
- Port 4000 available for Contember Engine GraphQL endpoint access
- Environment variables configured for database credentials and admin access
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 contember-engine: 3 image: contember/engine:latest4 container_name: contember5 restart: unless-stopped6 environment: 7 DEFAULT_DB_HOST: postgres8 DEFAULT_DB_NAME: contember9 DEFAULT_DB_USER: contember10 DEFAULT_DB_PASSWORD: ${DB_PASSWORD}11 TENANT_DB_NAME: contember12 CONTEMBER_ROOT_EMAIL: ${ADMIN_EMAIL}13 CONTEMBER_ROOT_PASSWORD: ${ADMIN_PASSWORD}14 ports: 15 - "4000:4000"16 depends_on: 17 - postgres18 networks: 19 - contember-network2021 postgres: 22 image: postgres:16-alpine23 container_name: contember-postgres24 environment: 25 POSTGRES_USER: contember26 POSTGRES_PASSWORD: ${DB_PASSWORD}27 POSTGRES_DB: contember28 volumes: 29 - postgres_data:/var/lib/postgresql/data30 networks: 31 - contember-network3233volumes: 34 postgres_data: 3536networks: 37 contember-network: 38 driver: bridge.env Template
.env
1DB_PASSWORD=changeme2ADMIN_EMAIL=admin@example.com3ADMIN_PASSWORD=changemeUsage Notes
- 1Docs: https://docs.contember.com/
- 2GraphQL API at http://localhost:4000/content
- 3Define schema in TypeScript: @contember/schema
- 4Automatic database migrations from schema changes
- 5Built-in ACL (Access Control Lists) for permissions
- 6Admin panel with @contember/admin SDK
Individual Services(2 services)
Copy individual services to mix and match with your existing compose files.
contember-engine
contember-engine:
image: contember/engine:latest
container_name: contember
restart: unless-stopped
environment:
DEFAULT_DB_HOST: postgres
DEFAULT_DB_NAME: contember
DEFAULT_DB_USER: contember
DEFAULT_DB_PASSWORD: ${DB_PASSWORD}
TENANT_DB_NAME: contember
CONTEMBER_ROOT_EMAIL: ${ADMIN_EMAIL}
CONTEMBER_ROOT_PASSWORD: ${ADMIN_PASSWORD}
ports:
- "4000:4000"
depends_on:
- postgres
networks:
- contember-network
postgres
postgres:
image: postgres:16-alpine
container_name: contember-postgres
environment:
POSTGRES_USER: contember
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: contember
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- contember-network
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 contember-engine:5 image: contember/engine:latest6 container_name: contember7 restart: unless-stopped8 environment:9 DEFAULT_DB_HOST: postgres10 DEFAULT_DB_NAME: contember11 DEFAULT_DB_USER: contember12 DEFAULT_DB_PASSWORD: ${DB_PASSWORD}13 TENANT_DB_NAME: contember14 CONTEMBER_ROOT_EMAIL: ${ADMIN_EMAIL}15 CONTEMBER_ROOT_PASSWORD: ${ADMIN_PASSWORD}16 ports:17 - "4000:4000"18 depends_on:19 - postgres20 networks:21 - contember-network2223 postgres:24 image: postgres:16-alpine25 container_name: contember-postgres26 environment:27 POSTGRES_USER: contember28 POSTGRES_PASSWORD: ${DB_PASSWORD}29 POSTGRES_DB: contember30 volumes:31 - postgres_data:/var/lib/postgresql/data32 networks:33 - contember-network3435volumes:36 postgres_data:3738networks:39 contember-network:40 driver: bridge41EOF4243# 2. Create the .env file44cat > .env << 'EOF'45DB_PASSWORD=changeme46ADMIN_EMAIL=admin@example.com47ADMIN_PASSWORD=changeme48EOF4950# 3. Start the services51docker compose up -d5253# 4. View logs54docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/contember/run | bashTroubleshooting
- Schema validation failed during migration: Check TypeScript decorators syntax and ensure all relationships reference existing entities
- GraphQL endpoint returns 500 errors: Verify PostgreSQL connection and ensure database user has CREATE and ALTER privileges
- Admin interface shows empty forms: Confirm schema models include proper field decorators and admin panel configuration
- Migration files not generating: Restart Contember Engine after schema changes and check TypeScript compilation errors
- Access denied errors in GraphQL queries: Review ACL definitions in schema and verify user permissions match query requirements
- PostgreSQL connection refused: Ensure postgres service starts before contember-engine using depends_on configuration
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Ad Space
Shortcuts: C CopyF FavoriteD Download