> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Nectr-AI/nectr-ai-pr-review-agent/llms.txt
> Use this file to discover all available pages before exploring further.

# Self-Hosting Guide

> Deploy Nectr on your own infrastructure with Docker

## Overview

Nectr is designed to be self-hosted. You own your data, your API keys, and your infrastructure. This guide covers deploying Nectr using Docker on any server, cloud provider, or Kubernetes cluster.

<Note>
  Self-hosting gives you complete control but requires managing your own database, Neo4j instance, and SSL certificates.
</Note>

## Why Self-Host?

* **Data Ownership:** All code, PRs, and reviews stay on your infrastructure
* **Custom Integrations:** Modify the codebase to fit your workflow
* **Security:** Meet compliance requirements for sensitive codebases
* **Cost Control:** No usage-based pricing for high-volume teams

## Prerequisites

* **Linux server** (Ubuntu 22.04+ recommended) or any Docker-compatible host
* **Docker** and **Docker Compose** installed
* **Domain name** with DNS access (for SSL certificates)
* **PostgreSQL database** (self-hosted or managed)
* **Neo4j database** (self-hosted or AuraDB)

## Architecture

A self-hosted Nectr deployment consists of:

```
┌─────────────────────────────────────────────────────────────┐
│                      Your Infrastructure                     │
│                                                              │
│  ┌──────────────┐   ┌──────────────┐   ┌──────────────┐   │
│  │   Frontend   │   │   Backend    │   │  PostgreSQL  │   │
│  │   Next.js    │──▶│   FastAPI    │──▶│   Database   │   │
│  │  (port 3000) │   │  (port 8000) │   │  (port 5432) │   │
│  └──────────────┘   └──────────────┘   └──────────────┘   │
│         │                   │                               │
│         │                   └──────────────┐                │
│         │                                  │                │
│  ┌──────▼──────┐                    ┌──────▼──────┐        │
│  │   Nginx     │                    │    Neo4j    │        │
│  │   Reverse   │                    │    Graph    │        │
│  │   Proxy     │                    │  (port 7687)│        │
│  └─────────────┘                    └─────────────┘        │
│         │                                                   │
└─────────┼───────────────────────────────────────────────────┘
          │
          ▼
    Internet (HTTPS)
```

## Docker Deployment

### Using Docker Compose

The easiest way to self-host Nectr is with Docker Compose.

<Steps>
  <Step title="Clone Repository">
    ```bash theme={null}
    git clone https://github.com/yourusername/nectr.git
    cd nectr
    ```
  </Step>

  <Step title="Create docker-compose.yml">
    Create a `docker-compose.yml` file in the project root:

    ```yaml docker-compose.yml theme={null}
    version: '3.8'

    services:
      backend:
        build:
          context: .
          dockerfile: Dockerfile
        ports:
          - "8000:8000"
        environment:
          - DATABASE_URL=postgresql+asyncpg://postgres:password@postgres:5432/nectr
          - NEO4J_URI=bolt://neo4j:7687
          - NEO4J_USERNAME=neo4j
          - NEO4J_PASSWORD=neo4jpassword
          - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
          - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}
          - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}
          - GITHUB_PAT=${GITHUB_PAT}
          - SECRET_KEY=${SECRET_KEY}
          - MEM0_API_KEY=${MEM0_API_KEY}
          - BACKEND_URL=https://api.yourdomain.com
          - FRONTEND_URL=https://yourdomain.com
          - APP_ENV=production
          - LOG_LEVEL=INFO
        depends_on:
          - postgres
          - neo4j
        restart: unless-stopped

      frontend:
        build:
          context: ./nectr-web
          dockerfile: Dockerfile
        ports:
          - "3000:3000"
        environment:
          - NEXT_PUBLIC_API_URL=https://api.yourdomain.com
        restart: unless-stopped

      postgres:
        image: postgres:16-alpine
        environment:
          - POSTGRES_USER=postgres
          - POSTGRES_PASSWORD=password
          - POSTGRES_DB=nectr
        volumes:
          - postgres_data:/var/lib/postgresql/data
        restart: unless-stopped

      neo4j:
        image: neo4j:5.15
        environment:
          - NEO4J_AUTH=neo4j/neo4jpassword
          - NEO4J_PLUGINS=["apoc"]
        volumes:
          - neo4j_data:/data
        ports:
          - "7474:7474"  # Browser UI
          - "7687:7687"  # Bolt protocol
        restart: unless-stopped

    volumes:
      postgres_data:
      neo4j_data:
    ```
  </Step>

  <Step title="Create Frontend Dockerfile">
    Create `nectr-web/Dockerfile`:

    ```dockerfile nectr-web/Dockerfile theme={null}
    FROM node:20-alpine AS builder

    WORKDIR /app

    COPY package*.json ./
    RUN npm ci

    COPY . .
    RUN npm run build

    FROM node:20-alpine AS runner

    WORKDIR /app

    ENV NODE_ENV production

    COPY --from=builder /app/public ./public
    COPY --from=builder /app/.next/standalone ./
    COPY --from=builder /app/.next/static ./.next/static

    EXPOSE 3000

    CMD ["node", "server.js"]
    ```
  </Step>

  <Step title="Configure Environment Variables">
    Create a `.env` file in the project root:

    ```bash .env theme={null}
    # AI
    ANTHROPIC_API_KEY=sk-ant-...

    # GitHub
    GITHUB_CLIENT_ID=...
    GITHUB_CLIENT_SECRET=...
    GITHUB_PAT=ghp_...

    # Auth
    SECRET_KEY=your-generated-secret

    # Mem0
    MEM0_API_KEY=m0-...
    ```

    <Warning>
      Never commit `.env` to version control. Add it to `.gitignore`.
    </Warning>
  </Step>

  <Step title="Start Services">
    ```bash theme={null}
    docker-compose up -d
    ```

    This starts:

    * Backend (FastAPI) on port 8000
    * Frontend (Next.js) on port 3000
    * PostgreSQL on port 5432
    * Neo4j on ports 7474 (browser) and 7687 (bolt)
  </Step>

  <Step title="Run Migrations">
    Apply database migrations:

    ```bash theme={null}
    docker-compose exec backend alembic upgrade head
    ```
  </Step>

  <Step title="Verify Deployment">
    ```bash theme={null}
    curl http://localhost:8000/health
    ```

    Expected response:

    ```json theme={null}
    {
      "status": "healthy",
      "database": "connected",
      "neo4j": "connected"
    }
    ```
  </Step>
</Steps>

## SSL & Reverse Proxy

Use Nginx as a reverse proxy with Let's Encrypt for SSL certificates.

<Steps>
  <Step title="Install Nginx">
    ```bash theme={null}
    sudo apt update
    sudo apt install nginx certbot python3-certbot-nginx
    ```
  </Step>

  <Step title="Configure Nginx">
    Create `/etc/nginx/sites-available/nectr`:

    ```nginx /etc/nginx/sites-available/nectr theme={null}
    # Frontend
    server {
        listen 80;
        server_name yourdomain.com;

        location / {
            proxy_pass http://localhost:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }

    # Backend API
    server {
        listen 80;
        server_name api.yourdomain.com;

        location / {
            proxy_pass http://localhost:8000;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            
            # WebSocket support (for MCP SSE)
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 86400;
        }
    }
    ```
  </Step>

  <Step title="Enable Site">
    ```bash theme={null}
    sudo ln -s /etc/nginx/sites-available/nectr /etc/nginx/sites-enabled/
    sudo nginx -t
    sudo systemctl restart nginx
    ```
  </Step>

  <Step title="Get SSL Certificates">
    ```bash theme={null}
    sudo certbot --nginx -d yourdomain.com -d api.yourdomain.com
    ```

    Follow the prompts. Certbot automatically updates your Nginx config.
  </Step>

  <Step title="Auto-Renewal">
    Test auto-renewal:

    ```bash theme={null}
    sudo certbot renew --dry-run
    ```

    Certbot automatically renews certificates before they expire.
  </Step>
</Steps>

## Alternative: Single Server Without Docker

If you prefer not to use Docker:

<Steps>
  <Step title="Install Dependencies">
    ```bash theme={null}
    # Backend
    sudo apt install python3.14 python3-pip postgresql

    # Frontend
    curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
    sudo apt install nodejs
    ```
  </Step>

  <Step title="Set Up Backend">
    ```bash theme={null}
    python3 -m venv venv
    source venv/bin/activate
    pip install -r requirements.txt
    cp .env.example .env
    # Edit .env with your values
    alembic upgrade head
    ```
  </Step>

  <Step title="Set Up Frontend">
    ```bash theme={null}
    cd nectr-web
    npm install
    cp .env.example .env.local
    # Edit .env.local
    npm run build
    ```
  </Step>

  <Step title="Create Systemd Services">
    Create `/etc/systemd/system/nectr-backend.service`:

    ```ini theme={null}
    [Unit]
    Description=Nectr Backend
    After=network.target

    [Service]
    Type=simple
    User=nectr
    WorkingDirectory=/home/nectr/nectr
    Environment="PATH=/home/nectr/nectr/venv/bin"
    EnvironmentFile=/home/nectr/nectr/.env
    ExecStart=/home/nectr/nectr/venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000
    Restart=always

    [Install]
    WantedBy=multi-user.target
    ```

    Create `/etc/systemd/system/nectr-frontend.service`:

    ```ini theme={null}
    [Unit]
    Description=Nectr Frontend
    After=network.target

    [Service]
    Type=simple
    User=nectr
    WorkingDirectory=/home/nectr/nectr/nectr-web
    Environment="NODE_ENV=production"
    EnvironmentFile=/home/nectr/nectr/nectr-web/.env.local
    ExecStart=/usr/bin/npm start
    Restart=always

    [Install]
    WantedBy=multi-user.target
    ```
  </Step>

  <Step title="Start Services">
    ```bash theme={null}
    sudo systemctl daemon-reload
    sudo systemctl enable nectr-backend nectr-frontend
    sudo systemctl start nectr-backend nectr-frontend
    ```
  </Step>
</Steps>

## Managed Services

For easier maintenance, use managed services:

| Service        | Provider                        | Cost                 |
| -------------- | ------------------------------- | -------------------- |
| **PostgreSQL** | Supabase, AWS RDS, DigitalOcean | Free tier available  |
| **Neo4j**      | Neo4j AuraDB                    | Free tier: 50k nodes |
| **Mem0**       | Mem0.ai                         | Pay-as-you-go        |
| **Server**     | AWS EC2, DigitalOcean, Hetzner  | \$5-20/month         |

<Note>
  Using managed databases simplifies backups, scaling, and maintenance.
</Note>

## Monitoring & Backups

### Health Monitoring

Set up uptime monitoring:

```bash theme={null}
# Install monitoring agent (example: Uptime Robot)
curl https://yourdomain.com/health
```

### Database Backups

<Tabs>
  <Tab title="PostgreSQL">
    Automated daily backups:

    ```bash theme={null}
    # Create backup script
    cat > /home/nectr/backup.sh << 'EOF'
    #!/bin/bash
    BACKUP_DIR="/home/nectr/backups"
    DATE=$(date +%Y%m%d_%H%M%S)
    docker exec nectr_postgres_1 pg_dump -U postgres nectr > "$BACKUP_DIR/nectr_$DATE.sql"
    find "$BACKUP_DIR" -mtime +7 -delete  # Keep 7 days
    EOF

    chmod +x /home/nectr/backup.sh

    # Add to crontab
    crontab -e
    # Add: 0 2 * * * /home/nectr/backup.sh
    ```
  </Tab>

  <Tab title="Neo4j">
    Neo4j backup:

    ```bash theme={null}
    docker exec nectr_neo4j_1 neo4j-admin dump --to=/data/backup.dump
    docker cp nectr_neo4j_1:/data/backup.dump ./neo4j_backup.dump
    ```
  </Tab>
</Tabs>

### Log Management

Rotate logs to prevent disk space issues:

```bash theme={null}
# Configure logrotate
sudo cat > /etc/logrotate.d/nectr << EOF
/home/nectr/nectr/logs/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
}
EOF
```

## Scaling

### Horizontal Scaling

Run multiple backend instances behind a load balancer:

```yaml docker-compose.yml (excerpt) theme={null}
services:
  backend:
    # ... existing config ...
    deploy:
      replicas: 3
  
  nginx:
    image: nginx:alpine
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "80:80"
    depends_on:
      - backend
```

### Vertical Scaling

Increase server resources:

* **CPU:** 2+ cores for production
* **RAM:** 4GB minimum, 8GB recommended
* **Storage:** 20GB+ (depends on PR volume)

## Security Best Practices

<Steps>
  <Step title="Use Strong Secrets">
    Generate cryptographically secure secrets:

    ```bash theme={null}
    python -c "import secrets; print(secrets.token_hex(32))"
    ```
  </Step>

  <Step title="Restrict Database Access">
    Configure PostgreSQL to only accept connections from localhost:

    ```bash theme={null}
    # postgresql.conf
    listen_addresses = 'localhost'
    ```
  </Step>

  <Step title="Enable Firewall">
    ```bash theme={null}
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw allow 22/tcp  # SSH
    sudo ufw enable
    ```
  </Step>

  <Step title="Regular Updates">
    Keep system packages updated:

    ```bash theme={null}
    sudo apt update && sudo apt upgrade -y
    ```
  </Step>

  <Step title="Secure GitHub PAT">
    Store GitHub PAT in environment variables, never in code. Rotate it every 90 days.
  </Step>
</Steps>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Container fails to start">
    Check logs:

    ```bash theme={null}
    docker-compose logs backend
    docker-compose logs frontend
    ```

    Common issues:

    * Missing environment variables
    * Database connection failures
    * Port conflicts
  </Accordion>

  <Accordion title="Database connection timeout">
    Verify PostgreSQL is accessible:

    ```bash theme={null}
    docker-compose exec backend ping postgres
    ```

    Check `DATABASE_URL` format:

    ```
    postgresql+asyncpg://user:password@host:5432/database
    ```
  </Accordion>

  <Accordion title="Neo4j authentication failed">
    Reset Neo4j password:

    ```bash theme={null}
    docker-compose exec neo4j cypher-shell
    # Change password in shell
    ```
  </Accordion>

  <Accordion title="Out of disk space">
    Check disk usage:

    ```bash theme={null}
    df -h
    docker system df
    ```

    Clean up unused images:

    ```bash theme={null}
    docker system prune -a
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Configure GitHub App" icon="github" href="/configuration/oauth-setup">
    Set up OAuth and webhooks
  </Card>

  <Card title="Connect Repository" icon="link" href="/api/repos/connect">
    Connect your first repo
  </Card>
</CardGroup>
