> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plugged.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Ubuntu Deployment Guide

> Complete guide for deploying Plugged.in on Ubuntu servers

# Ubuntu Deployment

This guide covers deploying Plugged.in on Ubuntu servers (20.04 LTS or later) for production or staging environments.

## System Requirements

<CardGroup cols={2}>
  <Card title="Minimum Requirements" icon="server">
    * Ubuntu 20.04 LTS or later
    * 2 CPU cores
    * 4GB RAM
    * 20GB storage
    * Node.js v20+
    * PostgreSQL 15+
  </Card>

  <Card title="Recommended Setup" icon="rocket">
    * Ubuntu 22.04 LTS
    * 4+ CPU cores
    * 8GB+ RAM
    * 50GB+ SSD storage
    * Dedicated database server
    * Redis for caching
  </Card>
</CardGroup>

## Prerequisites Installation

### 1. System Updates

```bash theme={null}
# Update package list and upgrade system
sudo apt-get update
sudo apt-get upgrade -y

# Install essential packages
sudo apt-get install -y \
  curl \
  wget \
  git \
  build-essential \
  nginx \
  certbot \
  python3-certbot-nginx
```

### 2. Node.js Installation

<Tabs>
  <Tab title="Using NodeSource">
    ```bash theme={null}
    # Install Node.js v20
    curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
    sudo apt-get install -y nodejs

    # Verify installation
    node --version  # Should be v20+
    npm --version   # Should be available
    npx --version   # Should be available
    ```
  </Tab>

  <Tab title="Using NVM">
    ```bash theme={null}
    # Install NVM
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
    source ~/.bashrc

    # Install Node.js
    nvm install 20
    nvm use 20
    nvm alias default 20
    ```
  </Tab>
</Tabs>

### 3. PostgreSQL Setup

```bash theme={null}
# Install PostgreSQL 15
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get install -y postgresql-15 postgresql-client-15

# Create database and user
sudo -u postgres psql <<EOF
CREATE USER pluggedin WITH PASSWORD 'your_secure_password';
CREATE DATABASE pluggedin_prod OWNER pluggedin;
GRANT ALL PRIVILEGES ON DATABASE pluggedin_prod TO pluggedin;
EOF
```

### 4. pnpm Installation

```bash theme={null}
# Install pnpm globally
npm install -g pnpm

# Verify installation
pnpm --version
```

### 5. Python and uv (for Python MCP Servers)

```bash theme={null}
# Install Python 3
sudo apt-get install -y python3 python3-pip python3-venv

# Install uv for Python package management
curl -LsSf https://astral.sh/uv/install.sh | sh

# Add to PATH (add to ~/.bashrc)
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```

### 6. Sandboxing Tools (Required for Security)

<Warning>
  Sandboxing is critical for secure execution of MCP servers. Install at least one sandboxing tool.
</Warning>

```bash theme={null}
# Install Bubblewrap (preferred sandboxing tool)
sudo apt-get install -y bubblewrap

# Install Firejail (fallback sandboxing tool)
sudo apt-get install -y firejail

# Install FUSE (required for some sandboxed applications)
sudo apt-get install -y fuse3 libfuse3-3

# Verify installations
bwrap --version
firejail --version
fusermount3 --version
```

**Why Sandboxing is Required:**

* **Security Isolation**: Prevents MCP servers from accessing sensitive system files
* **Resource Limits**: Controls CPU, memory, and I/O usage
* **Network Isolation**: Optional network restrictions for untrusted servers
* **Process Containment**: Prevents escape from sandbox environment

## Application Deployment

### 1. Clone Repository

```bash theme={null}
# Create application directory
sudo mkdir -p /var/www/pluggedin
sudo chown $USER:$USER /var/www/pluggedin

# Clone repository
cd /var/www/pluggedin
git clone https://github.com/VeriTeknik/pluggedin-app.git .
```

### 2. Environment Configuration

Create `.env` file:

```bash theme={null}
cp .env.example .env
nano .env
```

Configure essential variables:

```env theme={null}
# Database
DATABASE_URL="postgresql://pluggedin:your_secure_password@localhost:5432/pluggedin_prod"

# Authentication
NEXTAUTH_URL="https://your-domain.com"
NEXTAUTH_SECRET="generate-with-openssl-rand-base64-32"

# Application
NODE_ENV="production"
PORT="3000"

# MCP Configuration
MCP_PACKAGE_STORE_DIR="/var/www/pluggedin/.cache/mcp-packages"
MCP_PNPM_STORE_DIR="/var/www/pluggedin/.cache/mcp-packages/pnpm-store"
MCP_UV_CACHE_DIR="/var/www/pluggedin/.cache/mcp-packages/uv-cache"

# Sandboxing Configuration (IMPORTANT for security)
MCP_ISOLATION_TYPE="bubblewrap"  # Primary: bubblewrap | firejail | none
MCP_ISOLATION_FALLBACK="firejail"  # Fallback if primary not available
MCP_ENABLE_NETWORK_ISOLATION="false"  # Set to true for stricter isolation

# API Keys (optional)
PLUGGEDIN_API_KEY="your-api-key"
```

### 3. Install Dependencies

```bash theme={null}
# Install Node dependencies
pnpm install

# Build application
pnpm build

# Run database migrations
pnpm db:migrate
```

### 4. Create Cache Directories

```bash theme={null}
# Create MCP package cache directories
mkdir -p ~/.cache/mcp-packages/pnpm-store
mkdir -p ~/.cache/mcp-packages/uv-cache

# Set permissions
chmod 755 ~/.cache/mcp-packages
```

## Systemd Service Setup

### 1. Create Service File

```bash theme={null}
sudo nano /etc/systemd/system/pluggedin.service
```

```ini theme={null}
[Unit]
Description=Plugged.in Application
After=network.target postgresql.service

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/pluggedin
Environment="NODE_ENV=production"
Environment="PATH=/usr/local/bin:/usr/bin:/bin:/home/www-data/.local/bin"
ExecStart=/usr/bin/node .next/standalone/server.js
Restart=always
RestartSec=10

# Security
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/www/pluggedin

# Resource limits
LimitNOFILE=65536
LimitNPROC=512

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

### 2. Enable and Start Service

```bash theme={null}
# Set ownership
sudo chown -R www-data:www-data /var/www/pluggedin

# Reload systemd
sudo systemctl daemon-reload

# Enable service
sudo systemctl enable pluggedin

# Start service
sudo systemctl start pluggedin

# Check status
sudo systemctl status pluggedin
```

## Nginx Configuration

### 1. Create Nginx Config

```bash theme={null}
sudo nano /etc/nginx/sites-available/pluggedin
```

```nginx theme={null}
server {
    listen 80;
    server_name your-domain.com;

    # Redirect to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name your-domain.com;

    # SSL configuration (will be managed by Certbot)

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Proxy settings
    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;
        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;

        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # WebSocket support for real-time features
    location /api/websocket {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # Static file caching
    location /_next/static {
        proxy_pass http://localhost:3000;
        add_header Cache-Control "public, max-age=31536000, immutable";
    }
}
```

### 2. Enable Site

```bash theme={null}
# Enable site
sudo ln -s /etc/nginx/sites-available/pluggedin /etc/nginx/sites-enabled/

# Test configuration
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx
```

### 3. SSL Certificate

```bash theme={null}
# Obtain Let's Encrypt certificate
sudo certbot --nginx -d your-domain.com

# Auto-renewal
sudo systemctl enable certbot.timer
```

## Security Hardening

### 1. Firewall Configuration

```bash theme={null}
# Install UFW
sudo apt-get install -y ufw

# Configure firewall
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Enable firewall
sudo ufw --force enable
```

### 2. Configure Sandboxing

<Note>
  Sandboxing is enabled by default for all STDIO MCP servers. Ensure tools are properly installed.
</Note>

```bash theme={null}
# Verify sandboxing tools are installed
which bwrap || sudo apt-get install -y bubblewrap
which firejail || sudo apt-get install -y firejail

# Test sandboxing functionality
bwrap --version
firejail --version

# Configure sandboxing in .env
cat >> .env << EOF
MCP_ISOLATION_TYPE="bubblewrap"
MCP_ISOLATION_FALLBACK="firejail"
MCP_ENABLE_NETWORK_ISOLATION="false"
EOF

# Set appropriate permissions for sandbox directories
sudo chown -R www-data:www-data /var/www/pluggedin/.cache
sudo chmod -R 755 /var/www/pluggedin/.cache
```

**Sandboxing Modes:**

* **bubblewrap**: Lightweight, user-namespace based isolation (recommended)
* **firejail**: SUID-based sandboxing with extensive security profiles
* **none**: Disable sandboxing (NOT recommended for production)

### 3. Database Security

```bash theme={null}
# Secure PostgreSQL
sudo nano /etc/postgresql/15/main/postgresql.conf

# Add/modify:
# listen_addresses = 'localhost'
# ssl = on

# Restart PostgreSQL
sudo systemctl restart postgresql
```

## Monitoring & Maintenance

### 1. Log Management

```bash theme={null}
# View application logs
sudo journalctl -u pluggedin -f

# View Nginx logs
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
```

### 2. Health Checks

Create health check script:

```bash theme={null}
#!/bin/bash
# /usr/local/bin/pluggedin-health

curl -f http://localhost:3000/api/health || exit 1
```

```bash theme={null}
chmod +x /usr/local/bin/pluggedin-health

# Add to crontab
*/5 * * * * /usr/local/bin/pluggedin-health || systemctl restart pluggedin
```

### 3. Backup Strategy

```bash theme={null}
# Database backup script
#!/bin/bash
# /usr/local/bin/backup-pluggedin

BACKUP_DIR="/var/backups/pluggedin"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR
pg_dump pluggedin_prod | gzip > "$BACKUP_DIR/db_$DATE.sql.gz"

# Keep only last 30 days
find $BACKUP_DIR -name "db_*.sql.gz" -mtime +30 -delete
```

Add to crontab:

```bash theme={null}
0 2 * * * /usr/local/bin/backup-pluggedin
```

## Troubleshooting

### Common Issues

<AccordionGroup>
  <Accordion title="Command 'npx' not found">
    **Solution**: Install npm globally or ensure Node.js installation includes npm

    ```bash theme={null}
    npm install -g npx
    ```
  </Accordion>

  <Accordion title="Command 'uvx' not found">
    **Solution**: Install uv and add to PATH

    ```bash theme={null}
    curl -LsSf https://astral.sh/uv/install.sh | sh
    export PATH="$HOME/.local/bin:$PATH"
    ```
  </Accordion>

  <Accordion title="EACCES: permission denied">
    **Solution**: Check file ownership and permissions

    ```bash theme={null}
    sudo chown -R www-data:www-data /var/www/pluggedin
    sudo chmod -R 755 /var/www/pluggedin
    ```
  </Accordion>

  <Accordion title="Database connection failed">
    **Solution**: Verify PostgreSQL is running and credentials are correct

    ```bash theme={null}
    sudo systemctl status postgresql
    sudo -u postgres psql -c "\l"
    ```
  </Accordion>
</AccordionGroup>

### Debug Mode

Enable debug logging:

```bash theme={null}
# Add to .env
DEBUG=mcp:*

# Restart service
sudo systemctl restart pluggedin
```

Check logs for:

* `[MCP Wrapper] Environment info`
* `[MCP Wrapper] Command not found`
* `[MCP Wrapper] Current PATH`

## Performance Optimization

### 1. Node.js Tuning

```bash theme={null}
# Add to service file
Environment="NODE_OPTIONS=--max-old-space-size=4096"
```

### 2. PostgreSQL Tuning

```bash theme={null}
# Edit postgresql.conf
sudo nano /etc/postgresql/15/main/postgresql.conf

# Adjust based on available RAM:
shared_buffers = 1GB
effective_cache_size = 3GB
maintenance_work_mem = 256MB
```

### 3. Redis Cache (Optional)

```bash theme={null}
# Install Redis
sudo apt-get install -y redis-server

# Enable and start
sudo systemctl enable redis-server
sudo systemctl start redis-server

# Add to .env
REDIS_URL="redis://localhost:6379"
```

## Support

For deployment issues:

* **Documentation**: [docs.plugged.in](https://docs.plugged.in)
* **GitHub Issues**: [Report issues](https://github.com/VeriTeknik/pluggedin-app/issues)
* **Community**: [GitHub Discussions](https://github.com/orgs/VeriTeknik/discussions)
* **Email Support**: [api-support@plugged.in](mailto:api-support@plugged.in)
