How to Update Open-SEO: Complete Self-Hosted Upgrade Guide

Updating Open-SEO requires pulling the latest code from the main branch, refreshing Node.js dependencies with pnpm, applying database migrations via Drizzle-ORM, and rebuilding the Docker image using Dockerfile.selfhost.

Open-SEO is an open-source SEO platform maintained by every-app. Keeping your instance current ensures you receive the latest features, security patches, and database schema updates. This guide walks through the exact commands and configuration files—located in the every-app/open-seo repository—required to update open-seo safely.

Step 1: Pull the Latest Source Code

Start by fetching the newest commit from the repository. This brings in updated source files, migration scripts, and dependency manifests.

git checkout main
git pull origin main

This updates your local working directory to match the current state of the main branch on GitHub.

Step 2: Refresh Node.js Dependencies

Open-SEO uses pnpm for reproducible installs locked by pnpm-lock.yaml. After pulling new code, reinstall dependencies to align with the versions specified in package.json.

pnpm install

This command reads the lock file and installs the exact dependency tree required by the new release, including updates to TanStack Server Functions and Drizzle-ORM.

Step 3: Rebuild the Frontend Bundle

If you serve the web UI, compile the optimized static assets using the Vite configuration defined in web/vite.config.ts.


# Production build

pnpm run build

# Or for local development

pnpm run dev

The build process generates optimized assets based on the current TypeScript types in src/types/schemas/*.ts, which are updated automatically when backend query shapes change.

Step 4: Apply Database Migrations

Schema changes ship with migration metadata in drizzle-pg/meta/*.json. Apply these using the built-in migration script or the D1-to-Postgres helper.

Standard migration:

pnpm run migrate

Migrating from legacy D1 to Postgres:

node scripts/migrate-d1-to-postgres.ts

These commands reference drizzle.config.ts (for SQLite/D1) and drizzle-pg.config.ts (for Postgres) to execute schema changes safely.

Step 5: Rebuild and Redeploy the Docker Image

For self-hosted deployments, recreate the container image using the definitions in Dockerfile.selfhost and the orchestration in compose.yaml.

docker compose build
docker compose up -d

This rebuilds the application with the latest code, dependencies, and compiled assets, then restarts the service without destroying persistent volumes.

Step 6: Verify the Update

Confirm the deployment health by running the Playwright end-to-end test suite and checking the application URL.

pnpm run test:e2e

The test files in e2e/keyword-research-navigation.spec.ts validate critical user flows. Additionally, open http://localhost:3000 (or your configured host) to verify the UI loads without runtime errors.

Summary

  • Source control: Always pull the latest main branch before updating.
  • Dependencies: Run pnpm install to sync with pnpm-lock.yaml.
  • Database: Execute pnpm run migrate or node scripts/migrate-d1-to-postgres.ts to apply schema changes tracked in drizzle.config.ts.
  • Deployment: Rebuild the Docker image using docker compose build and restart with docker compose up -d.
  • Validation: Use pnpm run test:e2e to confirm the upgrade succeeded.

Frequently Asked Questions

What should I do if database migrations fail?

Check that your drizzle.config.ts points to the correct database URL and that you have Postgres running. If migrating from Cloudflare D1, use the scripts/migrate-d1-to-postgres.ts helper script specifically designed to port legacy data to the new schema.

Do I need to rebuild the frontend every time I update?

Yes, if you are serving the web UI in production. Run pnpm run build to regenerate static assets via web/vite.config.ts. The build process bundles the latest TypeScript types from src/types/schemas/ and optimizes the output for deployment.

Can I update Open-SEO without using Docker?

While the repository provides Dockerfile.selfhost and compose.yaml for containerized deployments, you can run the update manually by executing pnpm install, pnpm run build, pnpm run migrate, and starting the Node.js process directly. However, you must ensure your environment matches the Node version specified in package.json.

How do I verify that the update was successful?

Run the end-to-end test suite with pnpm run test:e2e, which executes Playwright tests including e2e/keyword-research-navigation.spec.ts. Additionally, manually verify that http://localhost:3000 loads without errors and that core features like keyword research function correctly.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →