import { Callout, Tabs, Steps } from 'nextra/components';

# Self-hosting

<Callout>OpenPanel is not stable yet. If you still want to self-host you can go ahead. Bear in mind that new changes might give a little headache to keep up with.</Callout>

This is a simple guide how to get started with OpenPanel on your own VPS.

## Instructions

### Prerequisites

- VPS of any kind (only tested on Ubuntu 24.04)
  - 🙋‍♂️ This should work on any system if you have pre-installed docker, node and pnpm
- [Clerk.com](https://clerk.com) account (they have a free tier)

### Quickstart

```bash
git clone https://github.com/Openpanel-dev/openpanel && cd openpanel/self-hosting && ./setup
# After setup is complete run `./start` to start OpenPanel
```

<Steps>

### Clone

Clone the repository to your VPS

```bash
git clone https://github.com/Openpanel-dev/openpanel.git
```

### Run the setup script

The setup script will do 3 things

1. Install node (if you accept)
2. Install docker (if you accept)
3. Execute a node script that will ask some questions about your setup
4. After this is done you'll need to point a webhook inside Clerk (https://your-domain.com/api/webhook/clerk)

> Setup takes 1-2 minutes depending on your VPS

```bash
cd openpanel/self-hosting
./setup
```

⚠️ If the `./setup` script fails to run, you can do it manually.

1. Install docker
2. Install node
3. Install pnpm
4. Run the `npx jiti ./quiz.ts` script inside the self-hosting folder

### Start 🚀

Run the `./start` script located inside the self-hosting folder

```bash
./start
```
</Steps>

## Clerk.com

<Callout>
Some might wonder why we use Clerk.com for authentication. The main reason for this is that Clerk have great support for iOS and Android apps. We're in the process of building an iOS app and we want to have a seamless experience for our users. 

**next-auth** is great, but lacks good support for mobile apps.
</Callout>

You'll need to create an account at [Clerk.com](https://clerk.com) and create a new project. You'll need the 3 keys that Clerk provides you with.

- **Publishable key** `pk_live_xxx`
- **Secret key** `sk_live_xxx`
- **Signing secret** `"whsec_xxx"`

### Webhooks

You'll also need to add a webhook to your domain. We listen on some events from Clerk to keep our database in sync.

#### URL

- **Path**: `/api/webhook/clerk`
- **Example**: `https://your-domain.com/api/webhook/clerk`

#### Events we listen to

- `organizationMembership.created`
- `user.created`
- `organizationMembership.deleted`
- `user.updated`
- `user.deleted`

## Good to know

### Always use correct api url

When self-hosting you'll need to provide your api url when initializing the SDK.

The path should be `/api` and the domain should be your domain.

```html filename="index.html" {4}
<script>
  window.op = window.op||function(...args){(window.op.q=window.op.q||[]).push(args);};
  window.op('init', {
    apiUrl: 'https://your-domain.com/api',
    clientId: 'YOUR_CLIENT_ID',
    trackScreenViews: true,
    trackOutgoingLinks: true,
    trackAttributes: true,
  });
</script>
<script src="https://openpanel.dev/op1.js" defer async></script>
```

```js filename="op.ts" {4}
import { OpenPanel } from '@openpanel/sdk';

const op = new OpenPanel({
  apiUrl: 'https://your-domain.com/api',
  clientId: 'YOUR_CLIENT_ID',
  trackScreenViews: true,
  trackOutgoingLinks: true,
  trackAttributes: true,
});
``` 