Skip to main content
Anchor releases updates regularly with new features, improvements, and security fixes. This guide covers how to safely update your self-hosted instance.

Update Process

The update process varies slightly depending on whether you’re using the pre-built image or building from source.

Pre-built Image

For deployments using ghcr.io/zhfahim/anchor:latest:
1

Backup your data

Always backup before updating:
# Create backup directory
mkdir -p ~/anchor-backups

# Stop Anchor (optional, for consistent backup)
docker compose down

# Backup data volume
docker run --rm \
  -v anchor_data:/data \
  -v ~/anchor-backups:/backup \
  alpine tar czf /backup/anchor-data-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
The /data volume contains your JWT secret. Always include it in backups.
2

Pull the latest image

Download the newest version:
docker compose pull anchor
This pulls the :latest tag or whatever tag you specified in your docker-compose.yml.
3

Stop the current container

docker compose down
Your data persists in the volume and won’t be deleted.
4

Start the updated container

docker compose up -d
The container will:
  1. Start with the new image
  2. Connect to the database (embedded or external)
  3. Automatically run any pending migrations
  4. Start the API and web services
5

Verify the update

Check logs to ensure successful startup:
docker compose logs -f anchor
Look for:
  • [anchor] Postgres ready
  • [anchor] Running migrations...
  • No error messages
  • Health check passing
# Check container health
docker ps
# Should show "healthy" status

Building from Source

For deployments building from the repository:
1

Backup your data

Same as pre-built image (see above).
2

Pull latest source code

cd anchor
git pull origin main
Check for breaking changes:
git log --oneline -10
3

Rebuild and restart

docker compose down
docker compose build --no-cache
docker compose up -d
The --no-cache flag ensures a clean build with all updates.
4

Verify the update

docker compose logs -f anchor

Version Pinning

For production, consider pinning to specific versions instead of using :latest:
docker-compose.yml
services:
  anchor:
    image: ghcr.io/zhfahim/anchor:v1.2.3  # Pin to specific version
    # or
    image: ghcr.io/zhfahim/anchor:1.2     # Pin to minor version

Finding Available Versions

# Visit the releases page
open https://github.com/zhfahim/anchor/releases

Updating from Pinned Version

1

Update version in docker-compose.yml

docker-compose.yml
services:
  anchor:
    image: ghcr.io/zhfahim/anchor:v1.3.0  # Update version
2

Apply update

docker compose pull anchor
docker compose up -d

Database Migrations

Anchor automatically runs database migrations on startup using Prisma Migrate.

How Migrations Work

  1. Container starts
  2. Entrypoint script connects to database
  3. Runs: prisma migrate deploy
  4. Applies any pending migrations
  5. Starts application services
From docker-entrypoint.sh:
echo "[anchor] Running migrations..."
cd /app/server
./node_modules/.bin/prisma migrate deploy

Manual Migration

If you need to run migrations manually:
# Check migration status
docker exec anchor sh -c "cd /app/server && npx prisma migrate status"

# Apply pending migrations
docker exec anchor sh -c "cd /app/server && npx prisma migrate deploy"

# View migration history
docker exec anchor sh -c "cd /app/server && ls prisma/migrations"

Rolling Back Migrations

Prisma Migrate doesn’t support automatic rollbacks. To revert:
1

Stop Anchor

docker compose down
2

Restore database backup

docker compose up -d
docker exec -i anchor pg_restore -U anchor -d anchor -h 127.0.0.1 -c \
  < ~/anchor-backups/anchor-db-20240115.dump
docker compose down
3

Revert to previous image

docker-compose.yml
services:
  anchor:
    image: ghcr.io/zhfahim/anchor:v1.2.0  # Previous version
docker compose pull anchor
docker compose up -d
Always test updates in a staging environment before applying to production.

Update Checklist

Before updating:
  • Backup /data volume
  • Backup database (pg_dump)
  • Review release notes for breaking changes
  • Note current version (check logs or container tag)
  • Test in staging environment (if available)
  • Schedule maintenance window (if needed)
  • Verify sufficient disk space
After updating:
  • Check logs for errors
  • Verify health check passes
  • Test login and core functionality
  • Verify sync works (create/edit note)
  • Check admin panel (if applicable)
  • Monitor for 24-48 hours

Automated Updates

Using Watchtower

Automatically update containers when new images are available:
docker-compose.yml
services:
  anchor:
    image: ghcr.io/zhfahim/anchor:latest
    # ... anchor config ...

  watchtower:
    image: containrrr/watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_POLL_INTERVAL=86400  # Check daily
      - WATCHTOWER_INCLUDE_STOPPED=false
    command: anchor  # Only watch anchor container
Automatic updates can cause unexpected downtime. Only use in non-critical environments or with extensive monitoring.

Using Renovate

Automatically create PRs for version updates in your infrastructure repo:
renovate.json
{
  "extends": ["config:base"],
  "docker": {
    "enabled": true
  },
  "packageRules": [
    {
      "matchPackageNames": ["ghcr.io/zhfahim/anchor"],
      "schedule": ["before 3am on Monday"]
    }
  ]
}

Zero-Downtime Updates

For high-availability deployments:
1

Use external database

Required for multi-instance deployments:
docker-compose.yml
environment:
  - PG_HOST=postgres.example.com
2

Run multiple Anchor instances

Behind a load balancer:
docker-compose.yml
services:
  anchor-1:
    image: ghcr.io/zhfahim/anchor:latest
    environment:
      - PG_HOST=postgres

  anchor-2:
    image: ghcr.io/zhfahim/anchor:latest
    environment:
      - PG_HOST=postgres

  nginx:
    image: nginx:alpine
    # Load balancer config
3

Rolling update

Update instances one at a time:
# Update instance 1
docker compose stop anchor-1
docker compose pull anchor-1
docker compose up -d anchor-1

# Wait for health check
sleep 30

# Update instance 2
docker compose stop anchor-2
docker compose pull anchor-2
docker compose up -d anchor-2

Troubleshooting Updates

Update fails to start

# View detailed logs
docker compose logs anchor

# Check migration errors
docker compose logs anchor | grep -i migration

# Verify database connection
docker exec anchor pg_isready -h 127.0.0.1 -p 5432 -U anchor

Data loss concerns

# Verify volume still exists
docker volume ls | grep anchor

# Inspect volume contents
docker run --rm -v anchor_data:/data alpine ls -la /data

# Check JWT secret persisted
docker run --rm -v anchor_data:/data alpine cat /data/.jwt_secret

Reverting to previous version

# Stop current version
docker compose down

# Edit docker-compose.yml to use old version
# image: ghcr.io/zhfahim/anchor:v1.2.0

# Start old version
docker compose pull anchor
docker compose up -d

# Restore database if needed (see Rolling Back Migrations)

Migration stuck or failing

# Check migration status
docker exec anchor sh -c "cd /app/server && npx prisma migrate status"

# Mark migration as applied (use with caution)
docker exec anchor sh -c "cd /app/server && npx prisma migrate resolve --applied 20240115120000_migration_name"

# Reset and reapply (destructive!)
# Only for development/testing
docker exec anchor sh -c "cd /app/server && npx prisma migrate reset"

Release Notes

Always review release notes before updating:

Next Steps

Configuration

Review configuration options

Database Options

Learn about database management

Build docs developers (and LLMs) love