Development Environment
This guide covers setting up a local development environment for working on Otto.
This guide covers setting up a local development environment for working on Otto.
Prerequisites
Before you start, make sure you have the following installed:
- Docker and Docker Compose (v2+) -- required for the backend, worker, and Redis
- Node.js 18+ and npm -- required for the frontend dev server
- An LLM API key from one of the supported providers:
- Google Gemini (recommended)
- OpenAI
- Ollama (free, runs locally)
Starting Development Mode
Run the following from the project root:
Or equivalently:
If this is your first time running Otto, the CLI will launch an interactive configuration wizard to set up your .env file. You can re-run it at any time with ./otto configure.
What Happens on Startup
The ./otto dev command orchestrates three things:
-
Backend services start in Docker. The backend API, ARQ worker, and Redis are launched via
docker-compose.dev.yml. The backend container is built from your local./backendsource code, with the source directory mounted into the container for live editing. -
The CLI waits for the backend to become healthy. It polls
http://localhost:8000/api/healthfor up to 60 seconds before proceeding. -
The frontend starts natively on your host. The Next.js dev server runs outside Docker (via
npm run devinfrontend/), giving you the fastest possible hot reload for frontend changes.
Once everything is running, Otto is available at:
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- Redis: localhost:6379 (exposed in dev mode for debugging)
Hot Reload
Both the backend and frontend support automatic reloading when you edit code.
Backend API (FastAPI)
The backend runs with uvicorn --reload, which watches for Python file changes and restarts the server automatically. Because ./backend is bind-mounted into the container at /app, any file you edit on your host is immediately visible inside the container.
ARQ Worker
The async task worker runs under watchmedo auto-restart, which monitors all .py files in the /app/app directory. When you change any Python file, the worker process restarts automatically. The full command is:
Frontend (Next.js)
The Next.js dev server runs natively on your host machine (not in Docker), so React fast refresh works as expected. Editing any component, page, or stylesheet triggers an instant browser update.
Viewing Logs
When you run ./otto dev, backend and worker logs are streamed to your terminal with color-coded prefixes:
[backend]-- cyan -- FastAPI server logs[worker]-- yellow -- ARQ worker logs
Frontend logs appear inline from the Next.js dev server running in the foreground.
To view logs from a separate terminal, or to filter by service:
Stopping Development Mode
Press Ctrl+C in the terminal where ./otto dev is running. The CLI will:
- Stop the background log streaming
- Run
docker compose downto stop all backend containers - Print "Stopped."
You can also stop services from another terminal:
Running Tests
If you do not have a local virtualenv set up, you can run tests inside the backend container:
Common Development Tasks
Rebuilding After Dependency Changes
If you add or change Python dependencies in requirements.txt, rebuild the backend container:
This runs docker compose -f docker-compose.dev.yml build --no-cache to rebuild from scratch, then you can start dev mode again with ./otto dev.
For frontend dependency changes, stop the dev server and run:
Then restart with ./otto dev.
Resetting Data
To wipe all local data (databases, Redis state, uploads) and start fresh:
This removes files from data/sqlite, data/redis, and data/team_memory while preserving the directory structure. Restart Otto afterward to reinitialize.
Reconfiguring
To change your LLM provider, add integrations, or update API keys:
The wizard shows your current values and lets you update individual sections. Press Enter to keep any existing value.
Checking Service Health
This shows running containers and checks whether the backend and frontend are responding.
For a detailed health check with JSON output:
Project Structure
Key Differences Between Dev and Production
| Aspect | Development | Production |
|---|---|---|
| Backend image | Built from local source | Pre-built from GHCR |
| Backend reload | uvicorn --reload | Standard uvicorn |
| Worker reload | watchmedo auto-restart | Standard arq |
| Frontend | Next.js dev server on host | Static export served by nginx |
| Redis port | Exposed on host (6379) | Internal only |
| Source mounting | ./backend mounted into container | No source mounting |
| Env hint | FASTAPI_ENV=development | Not set |