DocsRun it yourself
Self-host OpenSEO with Docker
How to self-host OpenSEO with Docker: run the open-source SEO suite on your own computer or a cloud server, with HTTPS for your own domain.
- Docker
- PostgreSQL
- GitHub
OpenSEO is open source under the MIT licence, and everything this site runs is in the repository: the dashboard, the API with its MCP server and background worker, the public site and the database schema. With Docker, one command starts all of it.
| Where | Good for | You need |
|---|---|---|
| Your own computer | Trying it out, or using it just for yourself | Docker Desktop (Windows, macOS) or Docker (Linux) |
| A cloud server | Using it from anywhere, with a team, on your own domain | A server with 2 CPUs and 4 GB of memory, and a domain |
| From source | Changing the code | Node.js 22, pnpm 10 and Postgres |
On your own computer
Install Docker
Install Docker Desktop on Windows or macOS, or Docker Engine on Linux, and start it. Give it at least 4 GB of memory: the first build compiles the dashboard and the site.
Get the code
Terminal git clone https://github.com/duckduckdeploy/openseo.git openseo cd openseoSet two secrets
Terminal cp .env.example .env # Then open .env and set these two: AUTH_SECRET= # any 32+ random characters ENCRYPTION_KEY= # the output of: openssl rand -base64 32AUTH_SECRETsigns sign-in sessions.ENCRYPTION_KEYencrypts the API keys and Google tokens you store; keep a copy somewhere safe, because they cannot be read without it.Terminal # Generate both with Docker if you have no openssl: docker run --rm alpine sh -c "apk add -q openssl && echo AUTH_SECRET=\$(openssl rand -hex 32) && echo ENCRYPTION_KEY=\$(openssl rand -base64 32)"Start it
Terminal docker compose up -d --buildThe first build takes a few minutes. Postgres starts, the database is set up, and then the API, dashboard and site come up. Open
http://localhost:3200, create your account and follow the setup.
| Address | What it is |
|---|---|
| http://localhost:3200 | The dashboard: where you work |
| http://localhost:3101 | This site and the docs, served locally |
| http://localhost:4100 | The API, and the MCP server at /mcp for your AI agent |
These addresses are only reachable from your computer. To stop OpenSEO, run docker compose down; your data stays in a Docker volume until you remove it with docker compose down -v.
On a cloud server, with your own domain
Any provider that gives you a Linux server works: a virtual server with 2 CPUs, 4 GB of memory and 40 GB of disk is enough for one person or a small team, and costs around $10 to $25 a month. Use Ubuntu 24.04 or Debian 12.
Point your domain at the server
Create DNS records for your domain,
app.andapi.on it (for exampleexample.com,app.example.comandapi.example.com), all pointing at the server's IP address. Open ports 22, 80 and 443 in the provider's firewall, and nothing else.Install Docker and get the code
On the server # Ubuntu or Debian: install Docker curl -fsSL https://get.docker.com | sh # Get OpenSEO git clone https://github.com/duckduckdeploy/openseo.git openseo cd openseo cp .env.example .envSet the secrets and your domain
.env # .env on a server with the domain example.com AUTH_SECRET=... ENCRYPTION_KEY=... POSTGRES_PASSWORD=... # a long random password OPENSEO_DOMAIN=example.com APP_URL=https://app.example.com WEB_URL=https://example.com PUBLIC_API_URL=https://api.example.comThe public addresses are built into the dashboard and the site, so set them before you start, and rebuild if you change them.
Start it with HTTPS
On the server docker compose --profile https up -d --buildThe
httpsprofile adds Caddy in front, which gets certificates from Let's Encrypt and renews them on its own. The app, site and API listen only on the server itself; Caddy is the only thing facing the internet.
Updating
cd openseo
git pull
docker compose up -d --build # add --profile https on a serverDatabase changes are applied automatically when the API starts. Back up first if your data matters to you.
OpenSEO keeps two Postgres databases: openseo for accounts, keys, usage and billing, and openseo_data for everything projects track and research. The second is created on first start, on the same server. To keep it elsewhere, set DATA_DATABASE_URL.
Backups
# Back up both databases to files: accounts and keys, then project data
docker compose exec -T postgres pg_dump -U openseo openseo | gzip > openseo-$(date +%F).sql.gz
docker compose exec -T postgres pg_dump -U openseo openseo_data | gzip > openseo_data-$(date +%F).sql.gz
# Restore them into an empty install
gunzip -c openseo-2026-10-15.sql.gz | docker compose exec -T postgres psql -U openseo openseo
gunzip -c openseo_data-2026-10-15.sql.gz | docker compose exec -T postgres psql -U openseo openseo_dataKeep .env with your backups: the database is useless without the same ENCRYPTION_KEY. On a server, run the backup command nightly with cron and copy the files off the machine.
Settings
| Setting | What it does |
|---|---|
| GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET | Lets users connect Search Console and Analytics. See Set up Google sign-in. |
| API_BIND, APP_BIND, WEB_BIND | Which address each service listens on. 127.0.0.1 by default, so only this machine can reach them. |
| POSTGRES_PASSWORD | The database password. Set a long random one on a server. |
After changing .env, run docker compose up -d again. See Set up Google sign-in.
From source, for development
pnpm install
docker compose up -d postgres # or point DATABASE_URL at your own Postgres
pnpm db:migrate
pnpm devpnpm dev runs the API on :4100, the dashboard on :3200 and the site on :3101 with live reload. pnpm typecheck and pnpm test run the checks; the tests need no database or network, because they use an in-memory Postgres and stand-ins for the data provider and Google.
Next
Connect your AI agent to your own install: your MCP endpoint is {API_URL}/mcp. See Connect an agent over MCP.