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

# Installation

> Install SafariDesk with Docker Compose

# Installation

This page shows a simple, repeatable path to get SafariDesk running on a single host using Docker Compose.

## Full customer journey (from zero to usable)

Use this sequence for enterprise self-hosted onboarding:

1. Prepare host machine (Docker + Compose, networking, DNS)
2. Clone SafariDesk and create `.env`
3. Configure core settings (`DB_*`, `REDIS_*`, `SUPERUSER_*`, URLs)
4. Configure enterprise licensing values provided by SafariDesk
5. Start the stack with Docker Compose
6. Validate services, run first login, and confirm license status
7. Configure email, optional AI, backups, and monitoring

When these steps are complete, the system is ready for daily ticketing use.

## Preflight (do this first)

* Install Docker and Docker Compose on your host
* Make sure you run commands from the `Core/` directory (the Docker Compose file lives there)
* Confirm you have 4+ GB RAM available

## Operating system options

SafariDesk is Docker Compose-based and is not strictly Ubuntu-only.

* Production recommendation: Linux host (Ubuntu 22.04+ recommended)
* Also possible: Debian/RHEL-family Linux, macOS, and Windows with Docker Desktop

### Ubuntu / Debian (example)

```bash theme={null}
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
# Install Docker Engine and Docker Compose plugin per Docker docs
docker --version
docker compose version
```

### RHEL / Rocky / AlmaLinux (example)

```bash theme={null}
sudo dnf install -y dnf-plugins-core
# Install Docker Engine and Docker Compose plugin per Docker docs
docker --version
docker compose version
```

### macOS (example)

```bash theme={null}
brew install --cask docker
open /Applications/Docker.app
docker --version
docker compose version
```

### Windows (example)

```powershell theme={null}
winget install Docker.DockerDesktop
docker --version
docker compose version
```

For production workloads, prefer Linux because Docker Desktop on macOS/Windows is VM-based.

## 1. Clone the repository

Linux/macOS (bash):

```bash theme={null}
git clone https://github.com/SafariDesk-OS/Core.git
cd Core
```

Windows (PowerShell):

```powershell theme={null}
git clone https://github.com/SafariDesk-OS/Core.git
Set-Location Core
```

## 2. Create and edit the environment file

Linux/macOS (bash):

```bash theme={null}
cp .env.example .env
# Use your favorite editor to open Core/.env and set values
```

Windows (PowerShell):

```powershell theme={null}
Copy-Item .env.example .env
# Use your favorite editor to open Core/.env and set values
```

Minimum values to set before first start:

* `SECRET_KEY` — a random Django secret
* `DB_PASSWORD` — Postgres password used by the `db` container
* `SUPERUSER_USERNAME`, `SUPERUSER_PASSWORD`, `SUPERUSER_EMAIL`
* SMTP values (if you want email functionality)
* Enterprise license values from SafariDesk (see [Configuration](./configuration))

See [Configuration](./configuration) for a full list of variables and examples.

## 3. Start the stack

Run from `Core/`:

This command is the same in Linux/macOS and Windows PowerShell.

```bash theme={null}
docker compose up -d --build
```

The first run builds images and initializes the database — expect a few minutes.

## 4. Verify the deployment

Check container health and logs:

This command is the same in Linux/macOS and Windows PowerShell.

```bash theme={null}
docker compose ps
docker compose logs -f api
```

To run migrations and collect static files (safe to run after first start):

This command is the same in Linux/macOS and Windows PowerShell.

```bash theme={null}
docker compose exec api python manage.py migrate
docker compose exec api python manage.py collectstatic --noinput
```

When containers are healthy, open the frontend URL (see `FRONTEND_URL` in `.env`) and sign in with the `SUPERUSER_*` account.

## 5. Activate and verify enterprise licensing (updated UI)

The License UI is in the user Profile page and is an admin-only tab. Follow these steps after you sign in as an administrator.

1. Sign in as the admin user (created from `SUPERUSER_*` in `.env`).
2. Open your Profile page: `http://<frontend-host>/profile` (or click the Profile link in the header).
3. Select the `License` tab (next to `Security`). This page shows current license `Status`, `Edition`, `Features`, and `Last validated`.
4. Paste the enterprise license key into the `License Key` field and click `Activate`.
   * The frontend posts to `POST /api/v1/license/activate/` and the backend validates the key with the license-proxy (configured via `LICENSE_PROXY_URL` in `Core/.env`).
   * Activation requires a staff/admin account and a valid JWT access token; the frontend includes the token automatically when logged-in.
5. On success you will see license metadata (customer, edition, features) and enterprise features will be unlocked.

Behavior notes

* Admin-only: only staff users may activate or revalidate a license. Non-admin requests will receive an authorization error.
* Offline handling: if the API cannot reach the license-proxy the UI will display cached status and an "offline validation" notice; features remain available until revalidation fails.
* Security: license payloads are HMAC-signed by the proxy; the backend verifies signatures and stores license data encrypted when `LICENSE_ENCRYPTION_KEY` is set.

How to test the License UI (beginner-friendly)

* Confirm the frontend is pointing to the running API: check `Core/.env` `VITE_API_URL` (should be `http://localhost:9100/api/v1` for local setups). Rebuild the frontend if you change it.
* From the admin browser session: open DevTools → Network, click `Activate`, and verify the `POST /license/activate/` request returns HTTP 200 and JSON with license details.
* If you see CORS errors in the browser console (e.g. "No 'Access-Control-Allow-Origin' header"), add your frontend origin to `CORS_ALLOWED_ORIGINS` in `Core/backend/RNSafarideskBack/settings/base.py`, then restart the API.
* If activation fails with 4xx, capture the response JSON (it contains a helpful `detail` field). If the API returns 500, tail the API logs:

```bash theme={null}
docker compose -f Core/docker-compose.yml logs -f api --tail 200
```

Look for a traceback or signature/connection errors. Common fixes: ensure `LICENSE_PROXY_URL` is reachable (start the local `license-proxy` service) and `LICENSE_RESPONSE_SIGNING_SECRET` matches the proxy if you're running a private proxy.

Quick curl examples (use a logged-in admin token if required):

```bash theme={null}
# Check current status
curl -v http://localhost:9100/api/v1/license/status/

# Activate (single-line PowerShell example; replace <TOKEN> and <KEY>)
curl -v -X POST http://localhost:9100/api/v1/license/activate/ -H "Authorization: Bearer <TOKEN>" -H "Content-Type: application/json" -d '{"license_key":"<KEY>"}'
```

When activation is successful, perform a quick smoke test of an enterprise feature (for example, verify the admin-only report page or integration settings appear). If a feature is missing after activation, restart the frontend to ensure the SPA loaded the latest runtime configuration.

## Quick recovery tips

* If the API is failing, `docker compose logs api` shows the error
* If Postgres is not ready, wait and retry `migrate`
* If a container fails to build, check the build output and rerun `docker compose up -d --build`

If you need help, see [Troubleshooting](./troubleshooting).
