Motia Icon
Deployment Guide

Self-Hosted Deployment

Learn how to deploy your Motia project to production using motia-docker

Run your Motia app in Docker containers. Same environment everywhere - dev, staging, production.

You need motia package 0.5.2-beta.101 or higher

Quick Start

Important: Run these commands from your project root (where your package.json is).

cd /path/to/your/motia-project

Make sure you see package.json when you run ls.

Setup Docker files

npx motia@latest docker setup

This creates Dockerfile and .dockerignore in your project.

Build and run

npx motia@latest docker run --project-name my-app

Replace my-app with your project name.

Check it works

Open http://localhost:3000 in your browser.

For more options:

npx motia@latest docker run --help

Getting ENOENT: no such file or directory, open package.json?

You're not in your project directory. Run cd /path/to/your/project first.


Manual Docker Setup

Want more control? Build it yourself.

The docker setup command creates a Dockerfile for you, but here's what's in it:

Dockerfile
# Use Motia's base image (has Node + Python ready)
FROM motiadev/motia:latest
 
# For AWS Lightsail or other ARM platforms, use:
# FROM --platform=linux/arm64 motiadev/motia:latest
 
# Copy package files
COPY package*.json ./
 
# Install dependencies
RUN npm ci --only=production
 
# Copy your app
COPY . .
 
# If you have Python steps, uncomment this line:
# RUN npx motia@latest install
 
# Expose the port
EXPOSE 3000
 
# Start your app
CMD ["npm", "run", "start"]

Python Steps?

If you have Python steps, uncomment this line in the Dockerfile:

RUN npx motia@latest install

And make sure you have a requirements.txt file in your project.

.dockerignore

Create a .dockerignore file to keep your image small:

# Git
.git
.gitignore
 
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
ENV/
 
# Node
node_modules/
npm-debug.log
yarn-debug.log
yarn-error.log
 
# IDE
.vscode/
.idea/
*.swp
*.swo
 
# Local development
.env
 
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

Build and Run Manually

Build your image

docker build -t my-motia-app .

Run it

docker run -it --rm -p 3000:3000 my-motia-app

Open http://localhost:3000 - your app should be running!


Deploy to Cloud

AWS Lightsail

Lightsail needs ARM. Update your Dockerfile:

FROM --platform=linux/arm64 motiadev/motia:latest

Then build and deploy.

Railway

Connect your GitHub repo. Railway detects the Dockerfile automatically.

Fly.io

Create fly.toml:

app = "my-motia-app"
 
[build]
  dockerfile = "Dockerfile"
 
[[services]]
  internal_port = 3000
  protocol = "tcp"

Deploy: fly deploy

Render

Create a Web Service, point to your repo. Render builds automatically.


Configuring Adapters for Production

When deploying multiple Motia instances, you need distributed adapters to share state, events, and streams across instances. Without them, each instance operates in isolation.

When to Use Distributed Adapters

Use default adapters when:

  • Running a single Motia instance
  • Development and testing
  • Simple deployments

Use distributed adapters when:

  • Running multiple Motia instances (horizontal scaling)
  • Production deployments requiring high availability
  • Need shared state/events/streams across instances

Docker Compose with Redis

For production deployments, use Docker Compose to run Motia with Redis:

docker-compose.yml
version: '3.8'
 
services:
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
 
  motia:
    build: .
    ports:
      - "3000:3000"
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - RABBITMQ_URL=amqp://rabbitmq:5672
    depends_on:
      - redis
      - rabbitmq
 
  rabbitmq:
    image: rabbitmq:3-management-alpine
    ports:
      - "5672:5672"
      - "15672:15672"
    volumes:
      - rabbitmq-data:/var/lib/rabbitmq
 
volumes:
  redis-data:
  rabbitmq-data:

Configure Adapters in motia.config.ts

Update your configuration to use distributed adapters:

motia.config.ts
import { config } from '@motiadev/core'
import { RedisStateAdapter } from '@motiadev/adapter-redis-state'
import { RedisStreamAdapterManager } from '@motiadev/adapter-redis-streams'
import { RabbitMQEventAdapter } from '@motiadev/adapter-rabbitmq-events'
import { RedisCronAdapter } from '@motiadev/adapter-redis-cron'
 
export default config({
  adapters: {
    state: new RedisStateAdapter({
      host: process.env.REDIS_HOST || 'localhost',
      port: parseInt(process.env.REDIS_PORT || '6379'),
    }),
    streams: new RedisStreamAdapterManager({
      host: process.env.REDIS_HOST || 'localhost',
      port: parseInt(process.env.REDIS_PORT || '6379'),
    }),
    events: new RabbitMQEventAdapter({
      url: process.env.RABBITMQ_URL || 'amqp://localhost:5672',
      exchangeName: process.env.RABBITMQ_EXCHANGE || 'motia.events',
      exchangeType: 'topic',
    }),
    cron: new RedisCronAdapter({
      host: process.env.REDIS_HOST || 'localhost',
      port: parseInt(process.env.REDIS_PORT || '6379'),
    }),
  },
})

Install Adapter Packages

Add the adapter packages to your package.json:

npm install @motiadev/adapter-redis-state \
            @motiadev/adapter-redis-streams \
            @motiadev/adapter-rabbitmq-events \
            @motiadev/adapter-redis-cron

Scaling Multiple Instances

With distributed adapters configured, you can scale to multiple instances:

docker-compose.yml
services:
  motia-1:
    build: .
    ports:
      - "3000:3000"
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    depends_on:
      - redis
 
  motia-2:
    build: .
    ports:
      - "3001:3000"
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    depends_on:
      - redis
 
  motia-3:
    build: .
    ports:
      - "3002:3000"
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    depends_on:
      - redis

All instances share the same state, events, and streams through Redis and RabbitMQ.

Without distributed adapters, each Motia instance has isolated state and events. Use Redis/RabbitMQ adapters for multi-instance deployments.

Learn more about adapters →


Resources

Need help? See our Community Resources for questions, examples, and discussions.