Skip to Content
DeploymentAll-in-One

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:latest

Or use an .env file:

.env
# 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:latest

Access 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:

ImageDescription
marieai/m3-forge-all-in-one:latestAPI + Frontend + Plugin Runner + supervisord
marieai/m3-forge:latestAPI + 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:

  1. Runs Prisma migrations against the configured DATABASE_URL
  2. 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 PointPurpose
/data/appsWebapp container data and user-deployed applications
/var/run/docker.sockRequired 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.sock

Mounting 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:allinone

Internal service ports are configured via environment variables:

VariableDefaultService
PORT3500API 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.prisma

To run migrations manually:

docker exec m3-forge npx prisma migrate deploy \ --schema packages/@marie/db/prisma/schema.prisma

To open Prisma Studio for database inspection:

docker exec -it m3-forge npx prisma studio \ --schema packages/@marie/db/prisma/schema.prisma

Health 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/health

Check container health status:

docker inspect --format='{{.State.Health.Status}}' m3-forge

Environment Variable Reference

VariableDefaultDescription
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_NAMEmarieS3 bucket name
S3_REGIONus-east-1S3 region
PORT3500API server port
NODE_ENVproductionNode.js environment
APPS_DIR/data/appsWebapp storage directory
DOCKER_NETWORKmarie-networkDocker network for spawned webapps
WEBAPP_DOMAINapps.localhostDomain 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-forge

Common causes:

  • DATABASE_URL is 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 status

View 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.log

Docker 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:allinone

Migration 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 --force

Webapp not accessible via subdomain

  1. Add *.apps.localhost to your hosts file or use a DNS service
  2. Ensure the Docker socket is mounted
  3. Check m3-plugin-runner logs:
docker exec m3-forge cat /var/log/supervisor/m3-plugin-runner.log
Last updated on