Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.9.0 #475

Merged
merged 78 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
bd0bbde
feat: init multi server feature
Siumauricio Sep 8, 2024
1a34ba1
refactor: simplify docker commands
Siumauricio Sep 8, 2024
3d60236
feat: add redis installation on server and deploy applications on ser…
Siumauricio Sep 9, 2024
0a889c5
feat: deploy compose on external servers
Siumauricio Sep 9, 2024
6007427
feat: add deploy databases to external server
Siumauricio Sep 9, 2024
ea5349c
feat: add logs for each application
Siumauricio Sep 9, 2024
cf06162
refactor: show logs to each application and database
Siumauricio Sep 9, 2024
5afe164
feat: add domains in external server
Siumauricio Sep 9, 2024
95f75fd
feat: add application and databases external servers
Siumauricio Sep 9, 2024
86f1bf3
feat: add reload, stop and start in remote server
Siumauricio Sep 10, 2024
a8d714c
feat: add multi server compose
Siumauricio Sep 10, 2024
bf58ae0
feat(remote): add docker compose remote
Siumauricio Sep 12, 2024
0bd0da2
fix(raw): add raw compose remote
Siumauricio Sep 12, 2024
c412dab
refactor(multi-server): fix deploy on docker compose
Siumauricio Sep 13, 2024
c549ea1
refactor(multi-server): add error support
Siumauricio Sep 13, 2024
033bf66
chore: add dokploy dashboard in readme
Siumauricio Sep 13, 2024
d2c8632
refactor(server): add support for multi server
Siumauricio Sep 15, 2024
0d3c978
refactor(deployments): improve build error
Siumauricio Sep 15, 2024
19295ba
feat(multi server): add support for drag n drop
Siumauricio Sep 15, 2024
d8d0b60
refactor(multi-server): replace executeCommand with execAsyncRemote
Siumauricio Sep 16, 2024
4f3eb7b
Generate valid appName on changing name
mpcref Sep 16, 2024
fac984d
same thing for compose
mpcref Sep 16, 2024
7f378b1
and for database
mpcref Sep 16, 2024
e1ec0ae
replaceAll
mpcref Sep 16, 2024
2f9448d
corrections
mpcref Sep 16, 2024
8f83ecb
formatting
mpcref Sep 16, 2024
847d6ec
add trailing comma's
mpcref Sep 16, 2024
c84d39a
refactor: remove redis
Siumauricio Sep 16, 2024
9b312cd
refactor(multi-server): adapt paths on server and in dokploy ui
Siumauricio Sep 17, 2024
abe7875
refactor(multi-server): remove databases and hide monitoring when usi…
Siumauricio Sep 17, 2024
a591e02
refactor(multi-server): add deploy templates on different servers
Siumauricio Sep 17, 2024
4c3bc8e
refactor(deployment): set status error when application or compose ha…
Siumauricio Sep 17, 2024
f001a50
refactor(multi-server): show all the servers
Siumauricio Sep 17, 2024
a46e775
refactor(multi-server): add rclone to multi server
Siumauricio Sep 18, 2024
79f39db
refactor(multi-server): wip remote backups
Siumauricio Sep 19, 2024
54f855e
refactor(backups): wip postgres remote backups
Siumauricio Sep 19, 2024
6c08f33
missing transaction return
max-degterev Sep 19, 2024
b473062
Merge pull request #468 from max-degterev/canary
Siumauricio Sep 20, 2024
6159786
feat(multi-server): add backups remote server
Siumauricio Sep 20, 2024
4845c1a
refactor(multi-server): use rclone for databases backup local and ext…
Siumauricio Sep 20, 2024
9a828d4
refactor(linter): format files
Siumauricio Sep 20, 2024
0cb74c5
chore(license): update license
Siumauricio Sep 20, 2024
f3b3512
chore(ci/cd): add feature tag
Siumauricio Sep 20, 2024
a22b079
refactor(dockerfile): remove sudo
Siumauricio Sep 20, 2024
17a64a9
refactor: add conditional to prevent have value in serverId
Siumauricio Sep 20, 2024
6bdc833
chore: add unzip and update rclone installation command
Siumauricio Sep 20, 2024
4a37f85
chore: update dockerfile
Siumauricio Sep 20, 2024
ff382d2
Update installation.mdx
Siumauricio Sep 20, 2024
e90b98e
refactor: add warning when using keyboard interactive
Siumauricio Sep 20, 2024
ee5516b
refactor(server): throw error when authentication fails
Siumauricio Sep 20, 2024
0b22b69
refactor: add conditional to prevent access to terminal when is not s…
Siumauricio Sep 20, 2024
497d451
feat(multi-server): add actions to the server
Siumauricio Sep 21, 2024
8bf6a22
feat(multi server): add env and toggle dashboard remote
Siumauricio Sep 21, 2024
698ff9e
refactor(multi server): rename functions
Siumauricio Sep 21, 2024
c03c154
feat(multi-server): add docker containers view to servers
Siumauricio Sep 21, 2024
807137d
refactor(multi-server): add modals and separate server actions
Siumauricio Sep 22, 2024
069f1a7
refactor(multi-server): add serverIp
Siumauricio Sep 22, 2024
82588f3
refactor(multi-server): add flag to queues
Siumauricio Sep 22, 2024
ff482ff
refactor(multi-server): add docker cleanup cron
Siumauricio Sep 22, 2024
e317d0c
Merge branch 'canary' into 139-multi-server-feature
Siumauricio Sep 22, 2024
3de8a18
Merge branch 'canary' into 139-multi-server-feature
Siumauricio Sep 22, 2024
0465a71
feat(multi-server): enable docker terminal inside of containers
Siumauricio Sep 22, 2024
f427014
chore(lint): apply lint
Siumauricio Sep 22, 2024
245a517
refactor(compose): hide enviroment when is docker stack
Siumauricio Sep 22, 2024
9069061
fix(backups): remove schedule when updating to prevent to create anot…
Siumauricio Sep 22, 2024
f7e43fa
chore(migrations): apply single migration
Siumauricio Sep 22, 2024
1a87734
refactor(multi-server): delete server only if the server doesn't have…
Siumauricio Sep 22, 2024
f0f34df
refactor(multi-server): improve alerts and add instructions to ssh keys
Siumauricio Sep 22, 2024
31c55f7
refactor(multi-server): remove logs
Siumauricio Sep 22, 2024
14302ed
refactor: remove imports
Siumauricio Sep 22, 2024
31a4a08
refactor: remove logs
Siumauricio Sep 22, 2024
cb16de6
refactor(multi-server): copy the right value
Siumauricio Sep 22, 2024
63d5b77
refactor(multi-server): add config
Siumauricio Sep 22, 2024
0b05f8b
Merge pull request #469 from Dokploy/139-multi-server-feature
Siumauricio Sep 22, 2024
6c5c374
feat(docs): add multi server docs and troubleshooting
Siumauricio Sep 23, 2024
9a850d3
Merge pull request #453 from mpcref/patch-1
Siumauricio Sep 23, 2024
639bc0e
chore(version): bump version
Siumauricio Sep 23, 2024
b04c120
refactor(multi-server): update logs
Siumauricio Sep 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ WORKDIR /app
# Set production
ENV NODE_ENV=production

RUN apt-get update && apt-get install -y curl apache2-utils && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y curl unzip apache2-utils && rm -rf /var/lib/apt/lists/*

# Copy only the necessary files
COPY --from=build /prod/dokploy/.next ./.next
Expand All @@ -42,7 +42,7 @@ COPY --from=build /prod/dokploy/node_modules ./node_modules


# Install docker
RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh && rm get-docker.sh
RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh && rm get-docker.sh && curl https://rclone.org/install.sh | bash

# Install Nixpacks and tsx
# | VERBOSE=1 VERSION=1.21.0 bash
Expand All @@ -55,4 +55,4 @@ RUN curl -sSL https://nixpacks.com/install.sh -o install.sh \
COPY --from=buildpacksio/pack:0.35.0 /usr/local/bin/pack /usr/local/bin/pack

EXPOSE 3000
CMD [ "pnpm", "start" ]
CMD [ "pnpm", "start" ]
35 changes: 18 additions & 17 deletions apps/docs/content/docs/core/extra/comparison.mdx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
---
title: 'Comparison'
description: 'A comparison of Dokploy, CapRover, Dokku, and Coolify'
title: "Comparison"
description: "A comparison of Dokploy, CapRover, Dokku, and Coolify"
---

Comparison of the following deployment tools:

| Feature | Dokploy | CapRover | Dokku | Coolify |
|-----------------------------------|---------------------------------------|--------------------------------------|--------------------------------------|--------------------------------------|
| **User Interface** | ✅ | ✅ | ❌ | ✅ |
| **Docker compose support** | ✅ | ❌ | ❌ | ✅ |
| **API/CLI** | ✅ | ✅ | ✅ | ✅ |
| **Multi node support** | ✅ | ✅ | ❌ | ✅ |
| **Traefik Integration** | ✅ | ✅ | Available via Plugins | ✅ |
| **User Permission Management** | ✅ | ❌ | ❌ | ✅ |
| **Advanced User Permission Management** | ✅ | ❌ | ❌ | ❌ |
| **Terminal Access Built In** | ✅ | ❌ | ❌ | ✅ |
| **Database Support** | ✅ | ✅ | ❌ | ✅ |
| **Monitoring** | ✅ | ✅ | ❌ | ❌ |
| **Backups** | ✅ | Available via Plugins | Available via Plugins | ✅ |
| **Open Source** | ✅ | ✅ | ✅ | ✅ |
| **Cloud/Paid Version** | ❌ | ✅ | ❌ | ✅ |
| Feature | Dokploy | CapRover | Dokku | Coolify |
| --------------------------------------- | ------- | --------------------- | --------------------- | ------- |
| **User Interface** | ✅ | ✅ | ❌ | ✅ |
| **Docker compose support** | ✅ | ❌ | ❌ | ✅ |
| **API/CLI** | ✅ | ✅ | ✅ | ✅ |
| **Multi node support** | ✅ | ✅ | ❌ | ✅ |
| **Traefik Integration** | ✅ | ✅ | Available via Plugins | ✅ |
| **User Permission Management** | ✅ | ❌ | ❌ | ✅ |
| **Advanced User Permission Management** | ✅ | ❌ | ❌ | ❌ |
| **Terminal Access Built In** | ✅ | ❌ | ❌ | ✅ |
| **Database Support** | ✅ | ✅ | ❌ | ✅ |
| **Monitoring** | ✅ | ✅ | ❌ | ❌ |
| **Backups** | ✅ | Available via Plugins | Available via Plugins | ✅ |
| **Open Source** | ✅ | ✅ | ✅ | ✅ |
| **Multi Server Support** | ✅ | ❌ | ❌ | ✅ |
| **Cloud/Paid Version** | ❌ | ✅ | ✅ | ✅ |
2 changes: 1 addition & 1 deletion apps/docs/content/docs/core/get-started/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ We have tested on the following Linux Distros:

### Providers

- [Hostinger](https://www.hostinger.com/vps-hosting?ref=dokploy) Get 20% Discount using this referral link: [Referral Link](https://hostinger.com?REFERRALCODE=1SIUMAURICI97)
- [Hostinger](https://www.hostinger.com/vps-hosting?ref=dokploy) Get 20% Discount using this referral link: [Referral Link](https://www.hostinger.com/vps-hosting?REFERRALCODE=1SIUMAURICI97)
- [DigitalOcean](https://www.digitalocean.com/pricing/droplets#basic-droplets) Get 200$ credits for free with this referral link: [Referral Link](https://m.do.co/c/db24efd43f35)
- [Hetzner](https://www.hetzner.com/cloud/) Get 20€ credits for free with this referral link: [Referral Link](https://hetzner.cloud/?ref=vou4fhxJ1W2D)
- [Linode](https://www.linode.com/es/pricing/#compute-shared)
Expand Down
3 changes: 3 additions & 0 deletions apps/docs/content/docs/core/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
"docker/overview",
"---Monitoring---",
"monitoring/overview",
"---Multi Server---",
"multi-server/overview",
"multi-server/example",
"---Cluster---",
"cluster/overview",
"---Deployments---",
Expand Down
117 changes: 117 additions & 0 deletions apps/docs/content/docs/core/multi-server/example.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
title: Example
description: "Example to setup a remote server and deploy application in a VPS."
---

import { Callout } from "fumadocs-ui/components/callout";

Multi server allows you to deploy your apps remotely to different servers without needing to build and run them where the Dokploy UI is installed.

## Requirements

1. To install Dokploy UI, follow the [installation guide](en/docs/core/get-started/installation).

2. Create an SSH key by going to `/dashboard/settings/ssh-keys` and add a new key. Be sure to copy the public key.

<ImageZoom
src="/assets/ssh-keys.png"
alt="Architecture Diagram"
width={1000}
height={600}
className="rounded-lg"
/>

3. Decide which remote server to deploy your apps on. We recommend these reliable providers:

- [Hostinger](https://www.hostinger.com/vps-hosting?ref=dokploy) Get 20% off with this [referral link](https://www.hostinger.com/vps-hosting?REFERRALCODE=1SIUMAURICI97).
- [DigitalOcean](https://www.digitalocean.com/pricing/droplets#basic-droplets) Get $200 credits for free with this [referral link](https://m.do.co/c/db24efd43f35).
- [Hetzner](https://www.hetzner.com/cloud/) Get €20 credits with this [referral link](https://hetzner.cloud/?ref=vou4fhxJ1W2D).
- [Linode](https://www.linode.com/es/pricing/#compute-shared).
- [Vultr](https://www.vultr.com/pricing/#cloud-compute).
- [Scaleway](https://www.scaleway.com/en/pricing/?tags=baremetal,available).
- [Google Cloud](https://cloud.google.com/).
- [AWS](https://aws.amazon.com/ec2/pricing/).

4. When creating the server, it should ask for SSH keys. Ideally, use your computer's public key and the key you generated in the previous step. Here's how to add the public key in Hostinger:

<ImageZoom
src="/assets/hostinger-add-sshkey.png"
alt="Adding SSH key"
width={1000}
height={600}
className="rounded-lg"
/>

<Callout>The steps are similar across other providers.</Callout>

5. Copy the server’s IP address and ensure you know the username (often `root`). Fill in all fields and click `Create`.

<ImageZoom
src="/assets/multi-server-add-server.png"
alt="Add server"
width={1000}
height={600}
className="rounded-lg"
/>

6. To test connectivity, open the server dropdown and click `Enter Terminal`. If everything is correct, you should be able to interact with the remote server.

7. Click `Setup Server` to proceed. There are two tabs: SSH Keys and Deployments. This guide explains the easy way, but you can follow the manual process via the Dokploy UI if you prefer.

<ImageZoom
src="/assets/multi-server-setup-2.png"
alt="Setup process"
width={1000}
height={600}
className="rounded-lg"
/>

8. Click `Deployments`, then `Setup Server`. If everything is correct, you should see output similar to this:

<ImageZoom
src="/assets/multi-server-setup-3.png"
alt="Server setup output"
width={1000}
height={600}
className="rounded-lg"
/>

<Callout>
You only need to run this setup once. If Dokploy updates later, check the
release notes to see if rerunning this command is required.
</Callout>

9. You're ready to deploy your apps! Let's test it out:

<ImageZoom
src="/assets/multi-server-add-app.png"
alt="Add app"
width={1000}
height={600}
className="rounded-lg"
/>

10. To check which server an app belongs to, you’ll see the server name at the top. If no server is selected, it defaults to `Dokploy Server`. Click `Deploy` to start building your app on the remote server. You can check the `Logs` tab to see the build process. For this example, we’ll use a test repo:
Repo: `https://github.com/Dokploy/examples.git`
Branch: `main`
Build Path: `/astro`

<ImageZoom
src="/assets/multi-server-setup-app.png"
alt="App setup"
width={1000}
height={600}
className="rounded-lg"
/>

11. Once the build is done, go to `Domains` and create a free domain. Just click `Create` and you’re good to go! 🎊

{" "}

<ImageZoom
src="/assets/multi-server-finish.png"
alt="Finished setup"
width={1000}
height={600}
className="rounded-lg"
/>
29 changes: 29 additions & 0 deletions apps/docs/content/docs/core/multi-server/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Overview
description: "Deploy your apps to multiple servers remotely."
---

import { Callout } from "fumadocs-ui/components/callout";

Multi server allows you to deploy your apps remotely to different servers without needing to build and run them where the Dokploy UI is installed.

To use the multi-server feature, you need to have Dokploy UI installed either locally or on a remote server. We recommend using a remote server for better connectivity, security, and isolation, for remote instances we install only a traefik instance.

If you plan to only deploy apps to remote servers and use Dokploy UI for managing deployments, Dokploy will use around 250 MB of RAM and minimal CPU, so a low-resource server should be sufficient.

All the features we have documented previously are supported by Dokploy Multi Server. The only feature not supported is remote server monitoring, due to performance reasons. However, all functionalities should work the same as when deploying on the same server where Dokploy UI is installed.

## Features

1. **Enter the terminal**: Allows you to access the terminal of the remote server.
2. **Setup Server**: Allows you to configure the remote server.
- **SSH Keys**: Steps to add SSH keys to the remote server.
- **Deployments**: Steps to configure the remote server for deploying applications.
3. **Edit Server**: Allows you to modify the remote server's details, such as SSH key, name, description, IP, etc.
4. **View Actions**: Lets you perform actions like managing the Traefik instance, storage, and activating Docker cleanup.
5. **Show Traefik File System**: Displays the contents of the remote server's directory.
6. **Show Docker Containers**: Shows the Docker containers running on the remote server.

<Callout>
Remote server monitoring is not supported due to performance reasons.
</Callout>
88 changes: 87 additions & 1 deletion apps/docs/content/docs/core/troubleshooting/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,90 @@ title: Overview
description: Solve the most common problems that occur when using Dokploy.
---

WIP
## Applications Domain Not Working?

You see the deployment succeeded, and logs are running, but the domain isn't working? Here's what to check:

1. **Correct Port Mapping**: Ensure the domain is using the correct port for your application. For example, if you're using Next.js, the port should be `3000`, or for Laravel, it should be `8000`. If you change the app port, update the domain to reflect that.
2. **Avoid Using `Ports` in Advanced Settings**: Generally, there's no need to use the `Ports` feature unless you want to access your app via `IP:port`. Leaving this feature enabled may interfere with your domain.

3. **Let's Encrypt Certificates**: It's crucial to point the domain to your server’s IP **before** adding it in Dokploy. If the domain is added first, the certificate won’t be generated, and you may need to recreate the domain or restart Traefik.

4. **Listen on 0.0.0.0, Not 127.0.0.1**: If your app is bound to `127.0.0.1` (which is common in Vite apps), switch it to `0.0.0.0` to allow external access.

## Logs and Monitoring Not Working After Changing Application Placement?

This is expected behavior. If the application is running on a different node (worker), the UI won’t have access to logs or monitoring, as they're not on the same node.

## Mounts Are Causing My Application Not to Run?

Docker Swarm won't run your application if there are invalid mounts, even if the deployment shows as successful. Double-check your mounts to ensure they are valid.

## Volumes in Docker Compose Not Working?

For Docker Compose, all file mounts defined in the `volumes` section will be stored in the `files` folder. This is the default directory structure:

## I added a volume to my docker compose, but is not finding the volume?

For docker compose all the file mounts you've created in the volumes section will be stored to files folder, this is the default structure of the docker compose.

```
/application-name
/code
/files
```

So instead of using this invalid way to mount a volume:

```yaml
volumes:
- "/folder:/path/in/container" ❌
```

You should use this format:

```yaml
volumes:
- "../files/my-database:/var/lib/mysql" ✅
- "../files/my-configs:/etc/my-app/config" ✅
```

## Logs Not Loading When Deploying to a Remote Server?

There are a few potential reasons for this:

1. **Slow Server:**: If the server is too slow, it may struggle to handle concurrent requests, leading to SSL handshake errors.
2. **Insufficient Disk Space:** If the server doesn't have enough disk space, the logs may not load.

## Docker Compose Domain Not Working?

When adding a domain in your Docker Compose file, it’s not necessary to expose the ports directly. Simply specify the port where your app is running. Exposing the ports can lead to conflicts with other applications or ports.

Example of what not to do:

```yaml
services:
app:
image: dokploy/dokploy:latest
ports:
- 3000:3000
```

Recommended approach:

```yaml
services:
app:
image: dokploy/dokploy:latest
ports:
- 3000
- 80
```

Then, when creating the domain in Dokploy, specify the service name and port, like this:

```yaml
domain: my-app.com
serviceName: app
port: 3000
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/docs/public/assets/ssh-keys.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions apps/dokploy/LICENSE.MD
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ See the License for the specific language governing permissions and limitations

## Additional Terms for Specific Features

The following additional terms apply to the multi-node support and Docker Compose file support features of Dokploy. In the event of a conflict, these provisions shall take precedence over those in the Apache License:
The following additional terms apply to the multi-node support, Docker Compose file and Multi Server features of Dokploy. In the event of a conflict, these provisions shall take precedence over those in the Apache License:

- **Self-Hosted Version Free**: All features of Dokploy, including multi-node support and Docker Compose file support, will always be free to use in the self-hosted version.
- **Restriction on Resale**: The multi-node support and Docker Compose file support features cannot be sold or offered as a service by any party other than the copyright holder without prior written consent.
- **Modification Distribution**: Any modifications to the multi-node support and Docker Compose file support features must be distributed freely and cannot be sold or offered as a service.
- **Self-Hosted Version Free**: All features of Dokploy, including multi-node support, Docker Compose file support and Multi Server, will always be free to use in the self-hosted version.
- **Restriction on Resale**: The multi-node support, Docker Compose file support and Multi Server features cannot be sold or offered as a service by any party other than the copyright holder without prior written consent.
- **Modification Distribution**: Any modifications to the multi-node support, Docker Compose file support and Multi Server features must be distributed freely and cannot be sold or offered as a service.

For further inquiries or permissions, please contact us directly.
Loading
Loading