All-in-One Deployment
A single Docker container bundling all M3 Forge components: nginx (reverse proxy), Node.js API (tRPC), React frontend, and Python m3-plugin-runner, managed by supervisord.
The all-in-one image requires external PostgreSQL and S3-compatible storage services. See Deployment Overview for setup instructions.
Suitable For
- Demos and evaluation
- Small teams (single-server deployment)
- Development previews
- Quick testing of Marie-AI + Studio integration
Quick Start
Start the container
docker run -d --name m3-forge \
-p 3000:3000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DATABASE_URL=postgresql://postgres:123456@host.docker.internal:5432/studio \
-e S3_ENDPOINT_URL=http://host.docker.internal:8000 \
-e S3_ACCESS_KEY_ID=MARIEACCESSKEY \
-e S3_SECRET_ACCESS_KEY=MARIESECRETACCESSKEY \
-e JWT_ACCESS_SECRET=$(openssl rand -hex 32) \
-e JWT_REFRESH_SECRET=$(openssl rand -hex 32) \
marieai/m3-forge-all-in-one:latestOr use an .env file:
# Required
DATABASE_URL=postgresql://postgres:123456@host.docker.internal:5432/studio
S3_ENDPOINT_URL=http://host.docker.internal:8000
S3_ACCESS_KEY_ID=MARIEACCESSKEY
S3_SECRET_ACCESS_KEY=MARIESECRETACCESSKEY
# Generate with: openssl rand -hex 32
JWT_ACCESS_SECRET=replace-with-generated-secret
JWT_REFRESH_SECRET=replace-with-generated-secret
# Optional
# S3_BUCKET_NAME=marie
# S3_REGION=us-east-1
# WEBAPP_DOMAIN=apps.localhost
# RUNNER_API_KEY=docker run -d --name m3-forge \
-p 3000:3000 \
-v /var/run/docker.sock:/var/run/docker.sock \
--env-file .env \
marieai/m3-forge-all-in-one:latestAccess the UI
Open http://localhost:3000 in your browser.
- Frontend:
/(React SPA) - API health:
/health - tRPC endpoint:
/trpc
Images
Pre-built images are published to Docker Hub and GitHub Container Registry:
| Image | Description |
|---|---|
marieai/m3-forge-all-in-one:latest | API + Frontend + Plugin Runner + supervisord |
marieai/m3-forge:latest | API + Frontend only (lighter, no m3-plugin-runner) |
GHCR mirrors are available at ghcr.io/marieai/m3-forge-all-in-one and ghcr.io/marieai/m3-forge.
Building from Source
If you need to build the image locally:
git clone https://github.com/marieai/marie-studio.git
cd marie-studio
# Full all-in-one (recommended)
docker build --target allinone \
-f docker/Dockerfile.allinone \
-t m3-forge:allinone .
# Or lighter prod target (no m3-plugin-runner)
docker build --target prod \
-f docker/Dockerfile.allinone \
-t m3-forge:prod .What’s Inside
Startup Sequence
On container start, the entrypoint script:
- Runs Prisma migrations against the configured
DATABASE_URL - Starts supervisord which launches nginx, API, and m3-plugin-runner in priority order
Persisting Data
Mount a volume for webapp storage:
docker run -d --name m3-forge \
-p 3000:3000 \
-v m3-forge-apps:/data/apps \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DATABASE_URL=... \
marieai/m3-forge-all-in-one:latest| Mount Point | Purpose |
|---|---|
/data/apps | Webapp container data and user-deployed applications |
/var/run/docker.sock | Required for m3-plugin-runner to manage containers |
Docker Socket Access
The m3-plugin-runner service requires access to the Docker socket to spawn and manage user-deployed webapp containers (Gradio, Streamlit, FastAPI, etc.).
-v /var/run/docker.sock:/var/run/docker.sockMounting the Docker socket gives the container the ability to manage Docker on the host. In production, consider using Docker socket proxies like Tecnativa/docker-socket-proxy to restrict available API calls.
If you don’t need webapp deployment, use the prod build target which excludes the m3-plugin-runner entirely.
Customizing Ports
Override the exposed port via Docker:
# Expose on port 8080 instead of 3000
docker run -d -p 8080:3000 ... m3-forge:allinoneInternal service ports are configured via environment variables:
| Variable | Default | Service |
|---|---|---|
PORT | 3500 | API server |
The nginx reverse proxy always listens on port 3000 internally.
Database Migrations
Migrations run automatically on every container start via the entrypoint script. This uses:
npx prisma migrate deploy --schema packages/@marie/db/prisma/schema.prismaTo run migrations manually:
docker exec m3-forge npx prisma migrate deploy \
--schema packages/@marie/db/prisma/schema.prismaTo open Prisma Studio for database inspection:
docker exec -it m3-forge npx prisma studio \
--schema packages/@marie/db/prisma/schema.prismaHealth Checks
The all-in-one container checks both the API and m3-plugin-runner:
# Combined health check (used by Docker HEALTHCHECK)
curl -sf http://localhost:3500/health && curl -sf http://localhost:8080/healthCheck container health status:
docker inspect --format='{{.State.Health.Status}}' m3-forgeEnvironment Variable Reference
| Variable | Default | Description |
|---|---|---|
DATABASE_URL | (required) | PostgreSQL connection string |
S3_ENDPOINT_URL | (required) | S3-compatible endpoint URL |
S3_ACCESS_KEY_ID | (required) | S3 access key |
S3_SECRET_ACCESS_KEY | (required) | S3 secret key |
JWT_ACCESS_SECRET | (required) | JWT access token signing secret |
JWT_REFRESH_SECRET | (required) | JWT refresh token signing secret |
S3_BUCKET_NAME | marie | S3 bucket name |
S3_REGION | us-east-1 | S3 region |
PORT | 3500 | API server port |
NODE_ENV | production | Node.js environment |
APPS_DIR | /data/apps | Webapp storage directory |
DOCKER_NETWORK | marie-network | Docker network for spawned webapps |
WEBAPP_DOMAIN | apps.localhost | Domain for webapp subdomains |
RUNNER_API_KEY | (none) | API key for m3-plugin-runner authentication |
Production Considerations
The all-in-one container is not recommended for production at scale. All processes share a single container — a crash in one service affects all others, and individual services cannot be scaled independently.
For production deployments, use the Docker Compose setup which provides:
- Independent service scaling
- Traefik reverse proxy with HTTPS
- Separate log streams per service
- Health checks per service
- Development and production profiles
Troubleshooting
Container exits immediately
Check the logs for migration or startup errors:
docker logs m3-forgeCommon causes:
DATABASE_URLis incorrect or PostgreSQL is not reachable- Database does not exist (create it first:
CREATE DATABASE studio) - Missing required environment variables
API returns 502 Bad Gateway
The API server hasn’t started yet. Check supervisor status:
docker exec m3-forge supervisorctl statusView individual service logs:
docker exec m3-forge cat /var/log/supervisor/api.log
docker exec m3-forge cat /var/log/supervisor/nginx.log
docker exec m3-forge cat /var/log/supervisor/m3-plugin-runner.logDocker socket permission denied
# Check socket permissions
ls -la /var/run/docker.sock
# If needed, add the container user to the docker group
docker run -d --group-add $(getent group docker | cut -d: -f3) \
-v /var/run/docker.sock:/var/run/docker.sock \
... m3-forge:allinoneMigration failures
# Check migration status
docker exec m3-forge npx prisma migrate status \
--schema packages/@marie/db/prisma/schema.prisma
# Reset and re-run (destructive - development only)
docker exec m3-forge npx prisma migrate reset \
--schema packages/@marie/db/prisma/schema.prisma --forceWebapp not accessible via subdomain
- Add
*.apps.localhostto your hosts file or use a DNS service - Ensure the Docker socket is mounted
- Check m3-plugin-runner logs:
docker exec m3-forge cat /var/log/supervisor/m3-plugin-runner.log