Maintain A Self-Hosted Markdawn
Use this guide after the first deployment to check services, update the application, and recover from common failures.
Keep a recent database backup and an accessible copy of your environment file before updates. Do not put the environment file or API tokens in a repository.
Check Service Status
Section titled “Check Service Status”systemctl --user status markdawn-postgres.service markdawn-api.service markdawn-collab.serviceRead Logs
Section titled “Read Logs”journalctl --user -u markdawn-api.service -fjournalctl --user -u markdawn-collab.service -fjournalctl --user -u markdawn-postgres.service -fUpdate The Application
Section titled “Update The Application”After the first deployment, fetch and run the deployment script from the target revision:
cd /var/www/markdawngit fetch origin mastergit show origin/master:deploy/deploy.sh > /tmp/markdawn-deploy.shbash /tmp/markdawn-deploy.shrm /tmp/markdawn-deploy.shThe update script pulls code, installs dependencies, builds packages, updates Podman units, applies pending migrations, restarts services, and checks API health.
The current Drizzle v1 baseline is not compatible with databases created from the removed legacy migration history. deploy.sh checks this before pulling code or replacing deployment artifacts and exits without resetting an incompatible database.
Reset An Incompatible Database
Section titled “Reset An Incompatible Database”This permanently deletes the existing PostgreSQL data. Run it only when a clean reset is intended:
cd /var/www/markdawnsystemctl --user stop markdawn-api.service markdawn-collab.service markdawn-postgres.service markdawn-pod.servicepodman volume rm postgres-data./deploy/setup.shsetup.sh creates a fresh postgres-data volume and applies the current migrations. Running setup.sh without removing the incompatible volume does not reset the database.
Check The Public API
Section titled “Check The Public API”curl https://your-domain.example/api/healthCommon Problems
Section titled “Common Problems”Caddy Cannot Get A Certificate
Section titled “Caddy Cannot Get A Certificate”Confirm that the domain resolves to the VPS and ports 80 and 443 are open.
Containers Do Not Start
Section titled “Containers Do Not Start”Check service logs and confirm that /var/www/markdawn/.env exists.
Database Connection Errors
Section titled “Database Connection Errors”Confirm that DATABASE_URL points to localhost:5432 and does not include sslmode=require.
systemctl --user status markdawn-postgres.servicepodman exec markdawn-postgres pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"OAuth Login Fails
Section titled “OAuth Login Fails”Compare the callback URL in the provider dashboard with the URL configured in Markdawn. The protocol, domain, path, and trailing slash must match.
The Browser Shows A Blank Page
Section titled “The Browser Shows A Blank Page”Confirm that VITE_API_URL was set before building the web package. Caddy must proxy the same-origin /collab WebSocket route to the collaboration service.
Migration Safety
Section titled “Migration Safety”Do not use db:push on a migrated database. Use the checked-in schema migrations and run db:migrate through the deployment workflow.
For a server move, follow Move a Markdawn Deployment. For a first installation, return to Deploy Markdawn on a Fedora VPS.