Self-Hosting Guide - Relaticle Documentation                 [ Skip to main content ](#main-content)= 768) mobileMenu = false"&gt;  [                                                         ](https://relaticle.com)

  [ Features ](https://relaticle.com/#features) [ Pricing ](https://relaticle.com/pricing) [ Documentation ](https://relaticle.com/docs) [  Discord  ](https://relaticle.com/discord)  [ Sign In ](https://relaticle.com/login) [ Start for free ](https://relaticle.com/register)

  [                                                         ](https://relaticle.com)

  [ Features ](https://relaticle.com/#features) [ Pricing ](https://relaticle.com/pricing) [ Contact ](https://relaticle.com/contact) [ Docs ](https://relaticle.com/docs)

  [ Sign In ](https://relaticle.com/login) [ Start for free ](https://relaticle.com/register)

    Documentation
-----------------

 [ Getting Started ](https://relaticle.com/docs/getting-started) [ Import Guide ](https://relaticle.com/docs/import) [ Developer Guide ](https://relaticle.com/docs/developer) [ Self-Hosting Guide ](https://relaticle.com/docs/self-hosting) [ MCP Server ](https://relaticle.com/docs/mcp) [ API Reference ](https://relaticle.com/docs/api)

  [\#](#self-hosting-guide "Permalink")Self-Hosting Guide
=======================================================

Deploy Relaticle on your own infrastructure with Docker or manually.

---

[\#](#quick-start "Permalink")Quick Start
-----------------------------------------

Get Relaticle running in 5 steps:

1. Download the compose file:

```
curl -o compose.yml https://raw.githubusercontent.com/Relaticle/relaticle/main/compose.yml

```

2. Generate an application key:

```
echo "APP_KEY=base64:$(openssl rand -base64 32)"

```

3. Create a `.env` file with your settings:

```
APP_KEY=base64:your-generated-key-here
DB_PASSWORD=your-secure-database-password
APP_URL=https://crm.example.com

```

4. Start the containers:

```
docker compose up -d

```

5. Create your admin account:

```
docker compose exec app php artisan make:filament-user

```

Your CRM is now available at `{APP_URL}/app`.

---

[\#](#requirements "Permalink")Requirements
-------------------------------------------

ResourceMinimumRecommendedRAM2 GB4 GBCPU1 core2 coresDisk10 GB20 GB+Docker20.10+LatestDocker Composev2.0+Latest---

[\#](#environment-variables "Permalink")Environment Variables
-------------------------------------------------------------

### [\#](#required "Permalink")Required

These must be set or the containers will refuse to start.

VariableDescription`APP_KEY`Encryption key. Generate with `openssl rand -base64 32`, then prefix with `base64:`.`DB_PASSWORD`PostgreSQL password. Use a strong random value.### [\#](#application "Permalink")Application

VariableDefaultDescription`APP_NAME``Relaticle`Displayed in the browser tab and emails.`APP_ENV``production`Set to `production` for self-hosting.`APP_DEBUG``false`Set to `true` only for debugging. Never in production.`APP_TIMEZONE``UTC`Application timezone.`APP_URL``http://localhost`Full URL where Relaticle is accessible. Include the scheme.`APP_PORT``80`Host port the app container binds to.`APP_PANEL_DOMAIN`(empty)Set for subdomain routing (e.g., `app.example.com`). Leave empty for path mode (`/app`).`REQUIRE_EMAIL_VERIFICATION``true`When `false`, users sign in without verifying their email — useful for self-hosters who haven't configured SMTP yet. The admin you create via `make:filament-user` is auto-verified regardless, so the default of `true` is safe for fresh Docker installs. Only set to `false` if your panel is on a private network: with verification disabled, anyone who can reach `/app/register` can create a working account.`LOG_CHANNEL``stderr`Where logs go. `stderr` is recommended for Docker.`LOG_LEVEL``warning`Minimum log level. Use `debug` for troubleshooting.### [\#](#mail "Permalink")Mail

VariableDefaultDescription`MAIL_MAILER``log`Mail driver: `smtp`, `ses`, `mailgun`, `postmark`, or `log`.`MAIL_HOST`(empty)SMTP host (e.g., `smtp.mailgun.org`).`MAIL_PORT``587`SMTP port.`MAIL_USERNAME`(empty)SMTP username.`MAIL_PASSWORD`(empty)SMTP password.`MAIL_ENCRYPTION``tls``tls` or `ssl`.`MAIL_FROM_ADDRESS``hello@example.com`Sender email address.`MAIL_FROM_NAME``Relaticle`Sender display name.### [\#](#database-and-redis "Permalink")Database and Redis

These are pre-configured in `compose.yml` and generally don't need changing.

VariableDefaultDescription`DB_DATABASE``relaticle`PostgreSQL database name.`DB_USERNAME``relaticle`PostgreSQL username.`REDIS_PASSWORD``null`Redis password. Leave as `null` for no auth.### [\#](#optional "Permalink")Optional

VariableDescription`GOOGLE_CLIENT_ID`Google OAuth client ID for social login.`GOOGLE_CLIENT_SECRET`Google OAuth client secret.`GITHUB_CLIENT_ID`GitHub OAuth client ID for social login.`GITHUB_CLIENT_SECRET`GitHub OAuth client secret.`SENTRY_LARAVEL_DSN`Sentry DSN for error tracking.`FATHOM_ANALYTICS_SITE_ID`Fathom Analytics site ID.### [\#](#feature-flags "Permalink")Feature Flags

Toggle features on or off. All are enabled by default. Useful for forks and custom deployments that want to disable specific functionality without modifying code.

VariableDefaultDescription`RELATICLE_FEATURE_ONBOARD_SEED``true`Seed demo data (sample companies, contacts, tasks) when a new team is created. Set to `false` to start with an empty workspace.`RELATICLE_FEATURE_SOCIAL_AUTH``true`Enable Google and GitHub social login. Set to `false` to use only email/password authentication.`RELATICLE_FEATURE_DOCUMENTATION``true`Enable the `/docs` documentation module. Set to `false` to remove documentation routes and navigation links.---

[\#](#architecture "Permalink")Architecture
-------------------------------------------

The Docker setup runs 5 containers:

ContainerImagePurpose**app**`ghcr.io/relaticle/relaticle:latest`Web server (nginx + PHP-FPM) on port 8080. Runs migrations automatically on startup.**horizon**`ghcr.io/relaticle/relaticle:latest`Queue worker powered by Laravel Horizon. Processes background jobs.**scheduler**`ghcr.io/relaticle/relaticle:latest`Runs `schedule:work` for recurring tasks (e.g., cleanup, notifications).**postgres**`postgres:17-alpine`PostgreSQL 17 database.**redis**`redis:7-alpine`Cache, sessions, and queue backend. Runs with append-only persistence.### [\#](#volumes "Permalink")Volumes

VolumePurpose`postgres`Database files. Back this up.`redis`Redis persistence data.`storage`Uploaded files and application storage. Back this up.### [\#](#networking "Permalink")Networking

The app container listens on port 8080 internally and maps to `APP_PORT` (default 80) on the host. All containers communicate through Docker's internal network. Only the app container exposes a port to the host.

---

[\#](#creating-your-admin-account "Permalink")Creating Your Admin Account
-------------------------------------------------------------------------

After starting the containers, create your first admin user:

```
docker compose exec app php artisan make:filament-user

```

When prompted to pick a panel, choose `app`, then enter a name, email, and password. Once created, access the CRM panel at `{APP_URL}/app`. (To create the instance-wide system administrator instead, see the next section.)

**Note**: By default the CRM panel is available at the `/app` path. To use subdomain routing instead (e.g., `app.example.com`), set the `APP_PANEL_DOMAIN` environment variable.

### [\#](#system-administrator-account "Permalink")System Administrator Account

The `sysadmin` panel at `{APP_URL}/sysadmin` is a separate, instance-wide admin surface for managing every team and user on your installation. To create a system administrator, you can either pick `sysadmin` from the `make:filament-user` panel prompt, or use the dedicated command:

```
docker compose exec app php artisan sysadmin:create

```

---

[\#](#reverse-proxy-and-ssl "Permalink")Reverse Proxy and SSL
-------------------------------------------------------------

The app container serves HTTP on port 8080 internally. Place a reverse proxy in front to handle SSL termination and route traffic to the container.

### [\#](#nginx "Permalink")Nginx

```
server {
    listen 443 ssl http2;
    server_name crm.example.com;

    ssl_certificate /etc/letsencrypt/live/crm.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/crm.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:80;
        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;
    }
}

server {
    listen 80;
    server_name crm.example.com;
    return 301 https://$server_name$request_uri;
}

```

### [\#](#caddy "Permalink")Caddy

```
crm.example.com {
    reverse_proxy 127.0.0.1:80
}

```

Caddy handles SSL certificates automatically via Let's Encrypt.

### [\#](#traefik "Permalink")Traefik

Add these labels to the `app` service in your `compose.yml`:

```
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.relaticle.rule=Host(`crm.example.com`)"
  - "traefik.http.routers.relaticle.entrypoints=websecure"
  - "traefik.http.routers.relaticle.tls.certresolver=letsencrypt"
  - "traefik.http.services.relaticle.loadbalancer.server.port=8080"

```

**Note**: When using a reverse proxy, set `APP_URL` to your public HTTPS URL (e.g., `https://crm.example.com`). The app trusts `X-Forwarded-*` headers from RFC1918 private networks, loopback, and IPv6 ULA/link-local — covering Coolify/Dokploy/Traefik on a Docker network and reverse proxies on the host. Headers from public IPs are rejected, preventing spoofing.

---

[\#](#deploying-on-dokploy "Permalink")Deploying on Dokploy
-----------------------------------------------------------

[Dokploy](https://dokploy.com/) is an open-source deployment platform. Here's how to deploy Relaticle on it.

### [\#](#1-create-a-project "Permalink")1. Create a Project

In the Dokploy dashboard, click **Create Project** and give it a name (e.g., "Relaticle").

### [\#](#2-add-a-compose-service "Permalink")2. Add a Compose Service

1. Inside your project, click **Create Service** and select **Compose**
2. Set the source to **Raw** and paste the contents of the [compose.yml](https://raw.githubusercontent.com/Relaticle/relaticle/main/compose.yml)
3. Click **Create**

### [\#](#3-set-environment-variables "Permalink")3. Set Environment Variables

In the service's **Environment** tab, add the required variables:

```
APP_KEY=base64:your-generated-key-here
DB_PASSWORD=your-secure-database-password
APP_URL=https://crm.yourdomain.com
APP_PORT=8080

```

Generate your `APP_KEY` with:

```
echo "base64:$(openssl rand -base64 32)"

```

**Note**: Set `APP_PORT=8080` so the container maps port 8080:8080, avoiding conflicts with Dokploy's own port 80.

### [\#](#4-deploy "Permalink")4. Deploy

Click **Deploy**. Dokploy will pull the images and start all 5 containers. Wait for health checks to pass.

### [\#](#5-configure-domain "Permalink")5. Configure Domain

1. Go to the **Domains** tab of the `app` service
2. Add your domain (e.g., `crm.yourdomain.com`)
3. Set the container port to `8080`
4. Enable HTTPS (Dokploy handles Let's Encrypt automatically)

### [\#](#6-create-admin-user "Permalink")6. Create Admin User

Open the Dokploy terminal for the `app` container and run:

```
php artisan make:filament-user

```

Your Relaticle instance is now live at `https://crm.yourdomain.com/app`.

---

[\#](#deploying-on-coolify "Permalink")Deploying on Coolify
-----------------------------------------------------------

[Coolify](https://coolify.io/) is an open-source, self-hostable platform for deploying applications.

### [\#](#1-create-a-new-project "Permalink")1. Create a New Project

In the Coolify dashboard, click **New Project** and give it a name.

### [\#](#2-add-a-docker-compose-resource "Permalink")2. Add a Docker Compose Resource

1. Click **Add Resource** in your project
2. Select **Docker Compose**
3. Choose **Empty** as the source, then paste the contents of the [compose.yml](https://raw.githubusercontent.com/Relaticle/relaticle/main/compose.yml)

### [\#](#3-configure-environment-variables "Permalink")3. Configure Environment Variables

In the resource's **Environment Variables** section, add:

```
APP_KEY=base64:your-generated-key-here
DB_PASSWORD=your-secure-database-password
APP_URL=https://crm.yourdomain.com

```

### [\#](#4-set-up-domain "Permalink")4. Set Up Domain

1. Go to the app service's **Settings**
2. Set your domain (e.g., `crm.yourdomain.com`)
3. Coolify will automatically provision an SSL certificate

### [\#](#5-deploy "Permalink")5. Deploy

Click **Deploy**. Coolify will pull the images, create containers, and start the services.

### [\#](#6-create-admin-user-1 "Permalink")6. Create Admin User

Use Coolify's **Terminal** feature to run in the `app` container:

```
php artisan make:filament-user

```

Access your CRM at `https://crm.yourdomain.com/app`.

---

[\#](#upgrading "Permalink")Upgrading
-------------------------------------

### [\#](#1-back-up-your-data "Permalink")1. Back Up Your Data

Always back up before upgrading. See the Backup and Restore section below.

### [\#](#2-pull-the-latest-images "Permalink")2. Pull the Latest Images

```
docker compose pull

```

### [\#](#3-restart-the-containers "Permalink")3. Restart the Containers

```
docker compose up -d

```

Database migrations run automatically on startup. The app container will apply any pending migrations before serving traffic.

**Note**: Check the [release notes](https://github.com/Relaticle/relaticle/releases) before upgrading. Breaking changes will be documented there.

---

[\#](#backup-and-restore "Permalink")Backup and Restore
-------------------------------------------------------

### [\#](#database-backup "Permalink")Database Backup

```
docker compose exec postgres pg_dump -U relaticle relaticle > backup-$(date +%Y%m%d).sql

```

### [\#](#database-restore "Permalink")Database Restore

```
docker compose exec -T postgres psql -U relaticle relaticle  /backups/relaticle-$(date +\%Y\%m\%d).sql.gz

```

---

[\#](#manual-deployment "Permalink")Manual Deployment
-----------------------------------------------------

If you prefer not to use Docker, you can deploy Relaticle directly on a server.

### [\#](#requirements-1 "Permalink")Requirements

- PHP 8.4+ with extensions: pdo\_pgsql, gd, bcmath, mbstring, xml, redis
- PostgreSQL 17+
- Redis 7+
- Node.js 20+
- Composer 2+
- Nginx or Apache
- Supervisor (for queue workers)

### [\#](#installation "Permalink")Installation

1. Clone the repository:

```
git clone https://github.com/Relaticle/relaticle.git /var/www/relaticle
cd /var/www/relaticle

```

2. Install dependencies:

```
composer install --no-dev --optimize-autoloader
npm ci && npm run build

```

3. Configure the environment:

```
cp .env.example .env
php artisan key:generate

```

Edit `.env` with your database credentials, mail settings, and `APP_URL`.

4. Set up the database:

```
php artisan migrate --force
php artisan storage:link

```

5. Set permissions:

```
chown -R www-data:www-data storage bootstrap/cache
chmod -R 775 storage bootstrap/cache

```

6. Create your admin user:

```
php artisan make:filament-user

```

### [\#](#nginx-configuration "Permalink")Nginx Configuration

```
server {
    listen 80;
    server_name crm.example.com;
    root /var/www/relaticle/public;

    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

```

### [\#](#supervisor-for-horizon "Permalink")Supervisor for Horizon

Create `/etc/supervisor/conf.d/relaticle-horizon.conf`:

```
[program:relaticle-horizon]
process_name=%(program_name)s
command=php /var/www/relaticle/artisan horizon
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/relaticle/storage/logs/horizon.log
stopwaitsecs=3600

```

Then start it:

```
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start relaticle-horizon

```

### [\#](#scheduler-cron "Permalink")Scheduler Cron

Add to `www-data`'s crontab:

```
* * * * * cd /var/www/relaticle && php artisan schedule:run >> /dev/null 2>&1

```

---

[\#](#troubleshooting "Permalink")Troubleshooting
-------------------------------------------------

### [\#](#appkey-is-required-error-on-startup "Permalink")"APP\_KEY is required" error on startup

The `APP_KEY` environment variable is not set. Generate one:

```
echo "base64:$(openssl rand -base64 32)"

```

Add it to your `.env` file and restart:

```
docker compose up -d

```

### [\#](#container-restart-loops "Permalink")Container restart loops

Check the logs:

```
docker compose logs app --tail 50

```

Common causes:

- Missing required environment variables (`APP_KEY`, `DB_PASSWORD`)
- PostgreSQL not ready yet (the app waits for a health check, but custom configs may skip this)
- Insufficient memory (need at least 2 GB)

### [\#](#500-errors-after-deployment "Permalink")500 errors after deployment

1. Check `APP_DEBUG=true` temporarily to see the full error
2. View logs: `docker compose logs app --tail 100`
3. Ensure `APP_URL` matches your actual domain (including scheme)
4. Run `docker compose exec app php artisan optimize:clear` to clear all caches

### [\#](#email-not-sending "Permalink")Email not sending

1. Verify `MAIL_MAILER` is set to `smtp` (not `log`)
2. Check your SMTP credentials are correct
3. Test with: `docker compose exec app php artisan tinker --execute "Mail::raw('Test', fn(\$m) => \$m->to('you@example.com')->subject('Test'))"`
4. Check logs: `docker compose logs app | grep -i mail`

### [\#](#horizon-not-processing-jobs "Permalink")Horizon not processing jobs

1. Check Horizon status: `docker compose exec app php artisan horizon:status`
2. Verify the horizon container is running: `docker compose ps`
3. Check horizon logs: `docker compose logs horizon --tail 50`
4. Restart Horizon: `docker compose restart horizon`

### [\#](#permission-errors-on-storage "Permalink")Permission errors on storage

```
docker compose exec app chown -R www-data:www-data /var/www/html/storage
docker compose exec app chmod -R 775 /var/www/html/storage

```

### [\#](#database-connection-refused "Permalink")Database connection refused

1. Verify PostgreSQL is running: `docker compose ps postgres`
2. Check PostgreSQL logs: `docker compose logs postgres --tail 20`
3. Ensure `DB_PASSWORD` matches between the app and postgres containers (both read from the same `.env` variable by default)

 [  Edit this page on GitHub ](https://github.com/Relaticle/relaticle/edit/main/packages/Documentation/resources/markdown/self-hosting-guide.md)

  ###    On this page

 - [ Quick Start ](#quick-start)
- [ Requirements ](#requirements)
- [ Environment Variables ](#environment-variables)
- [ Architecture ](#architecture)
- [ Creating Your Admin Account ](#creating-your-admin-account)
- [ Reverse Proxy and SSL ](#reverse-proxy-and-ssl)
- [ Deploying on Dokploy ](#deploying-on-dokploy)
- [ Deploying on Coolify ](#deploying-on-coolify)
- [ Upgrading ](#upgrading)
- [ Backup and Restore ](#backup-and-restore)
- [ Manual Deployment ](#manual-deployment)
- [ Troubleshooting ](#troubleshooting)

   [                                                         ](https://relaticle.com) The open-source CRM built for AI agents. Self-hosted. No per-seat pricing. Yours to own.

  [  ](https://github.com/Relaticle/relaticle) [  ](https://x.com/relaticle) [  ](https://www.linkedin.com/company/relaticle)

 ###  Quick Links

- [ Home ](https://relaticle.com)
- [ Pricing ](https://relaticle.com/pricing)
- [ Documentation ](https://relaticle.com/docs)
- [ Features ](https://relaticle.com/#features)

 ###  Support &amp; Legal

- [ Privacy Policy ](https://relaticle.com/privacy-policy)
- [ Terms of Service ](https://relaticle.com/terms-of-service)
- [ Contact Us ](https://relaticle.com/contact)

 © 2026 Relaticle. All rights reserved.
