Merge branch 'main' into docs/add-customization-hint

This commit is contained in:
Mauricio Siu
2026-01-28 00:22:58 -06:00
committed by GitHub
6 changed files with 524 additions and 41 deletions

View File

@@ -60,6 +60,7 @@ In this section, you can:
- Check build and deployment logs
- Monitor deployment updates
- Update domain configuration
- Manually rebuild preview deployments
### Automatic Updates
@@ -70,6 +71,16 @@ The preview deployment will automatically:
This continuous preview system allows teams to review and test changes in isolation before merging to production.
### Manual Rebuilds
You can manually rebuild a preview deployment without downloading new code from the repository. This is useful when you need to:
- Rebuild with updated environment variables or build settings
- Retry a failed build without making code changes
- Apply configuration changes that require a rebuild
To rebuild a preview deployment, click the **Rebuild** button (hammer icon) next to the deployment and confirm the action. The rebuild will use the existing code and only re-run the build process.
<Callout type="info">
If you have security or redirects created in your application, it will inherit the same configuration for the preview deployment.
</Callout>

View File

@@ -79,6 +79,65 @@ curl -sSL https://dokploy.com/install.sh | sh
See [Manual Installation](/docs/core/manual-installation) if you want to customize your Dokploy installation.
### Advanced Installation Options
The installation script automatically detects and installs the latest stable version from GitHub. However, you can customize the installation using environment variables:
#### Install Specific Versions
**Install Canary Version (Development):**
```bash
export DOKPLOY_VERSION=canary && curl -sSL https://dokploy.com/install.sh | sh
```
**Install Latest Stable:**
```bash
export DOKPLOY_VERSION=latest && curl -sSL https://dokploy.com/install.sh | sh
```
**Install Specific Version:**
```bash
export DOKPLOY_VERSION=v0.26.6 && curl -sSL https://dokploy.com/install.sh | sh
```
#### Custom Network Configuration
If you need to customize the Docker Swarm network configuration (useful to avoid CIDR conflicts with cloud provider VPCs):
```bash
export DOCKER_SWARM_INIT_ARGS="--default-addr-pool 172.20.0.0/16 --default-addr-pool-mask-length 24"
curl -sSL https://dokploy.com/install.sh | sh
```
#### Manual Advertise Address
If the script cannot detect your server's IP automatically, specify it manually:
```bash
export ADVERTISE_ADDR=192.168.1.100
curl -sSL https://dokploy.com/install.sh | sh
```
### Proxmox LXC Support
<Callout type='info'>
The installation script automatically detects Proxmox LXC containers and applies the necessary configurations (`--endpoint-mode dnsrr`) for compatibility.
</Callout>
### Updating Dokploy
To update your Dokploy installation to the latest version:
```bash
curl -sSL https://dokploy.com/install.sh | sh -s update
```
**Update to Specific Version:**
```bash
export DOKPLOY_VERSION=v0.26.6 && curl -sSL https://dokploy.com/install.sh | sh -s update
```
## Completing the Setup
After running the installation script, Dokploy and its dependencies will be set up on your server. Here's how to finalize the setup and start using Dokploy:

View File

@@ -3,7 +3,7 @@ title: 'Manual Installation'
description: 'Learn how to manually install Dokploy on your server.'
---
If you wish to customize the Dokploy installation on your server, you can modify several enviroment variables:
If you wish to customize the Dokploy installation on your server, you can modify several environment variables:
1. **PORT** - Ideal for avoiding conflicts with other services.
2. **TRAEFIK_SSL_PORT** - Set to another port if you want to use a different port for SSL.
@@ -134,13 +134,22 @@ install_dokploy() {
chmod 777 /etc/dokploy
# Generate secure random password for Postgres
POSTGRES_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-32)
# Store password as Docker Secret (encrypted and secure)
echo "$POSTGRES_PASSWORD" | docker secret create dokploy_postgres_password - 2>/dev/null || true
echo "Generated secure database credentials (stored in Docker Secrets)"
docker service create \
--name dokploy-postgres \
--constraint 'node.role==manager' \
--network dokploy-network \
--env POSTGRES_USER=dokploy \
--env POSTGRES_DB=dokploy \
--env POSTGRES_PASSWORD=amukds4wi9001583845717ad2 \
--secret source=dokploy_postgres_password,target=/run/secrets/postgres_password \
--env POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password \
--mount type=volume,source=dokploy-postgres,target=/var/lib/postgresql/data \
postgres:16
@@ -151,9 +160,6 @@ install_dokploy() {
--mount type=volume,source=dokploy-redis,target=/data \
redis:7
docker pull traefik:v3.6.1
docker pull dokploy/dokploy:latest
# Installation
docker service create \
--name dokploy \
@@ -162,11 +168,13 @@ install_dokploy() {
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--mount type=bind,source=/etc/dokploy,target=/etc/dokploy \
--mount type=volume,source=dokploy,target=/root/.docker \
--secret source=dokploy_postgres_password,target=/run/secrets/postgres_password \
--publish published=3000,target=3000,mode=host \
--update-parallelism 1 \
--update-order stop-first \
--constraint 'node.role == manager' \
-e ADVERTISE_ADDR=$advertise_addr \
-e POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password \
dokploy/dokploy:latest
@@ -179,7 +187,7 @@ install_dokploy() {
-p 80:80/tcp \
-p 443:443/tcp \
-p 443:443/udp \
traefik:v3.6.1
traefik:v3.6.7
docker network connect dokploy-network dokploy-traefik
@@ -195,7 +203,7 @@ install_dokploy() {
# --publish mode=host,published=443,target=443 \
# --publish mode=host,published=80,target=80 \
# --publish mode=host,published=443,target=443,protocol=udp \
# traefik:v3.6.1
# traefik:v3.6.7
GREEN="\033[0;32m"
YELLOW="\033[1;33m"
@@ -258,6 +266,23 @@ To customize the --advertise-addr parameter, replace the line: `advertise_addr=$
:warning: This IP address should be accessible to all nodes that will join the Swarm.
## Proxmox LXC Considerations
If you're installing Dokploy in a Proxmox LXC container, the installation script automatically detects the environment and adds `--endpoint-mode dnsrr` to Docker services for compatibility.
For manual installations in LXC, add this flag to your service creation commands:
```bash
docker service create \
--name dokploy-postgres \
--endpoint-mode dnsrr \
# ... rest of the configuration
```
<Callout type='warn'>
**Note:** The `--endpoint-mode dnsrr` flag is required for Docker services to work properly in Proxmox LXC containers due to networking limitations.
</Callout>
## Existing Docker swarm
If you already have a Docker swarm running on your server and you want to use dokploy, you can use the following command to join it:
@@ -303,17 +328,47 @@ To upgrade Dokploy manually, you can use the following command:
curl -sSL https://dokploy.com/install.sh | sh -s update
```
To use a specific version, you can use the following command:
### Version-Specific Installation & Updates
The installation script automatically detects the latest stable version from GitHub. You can also specify a particular version:
**Install/Update to Canary (Development):**
```bash
export DOKPLOY_VERSION=canary && curl -sSL https://dokploy.com/install.sh | sh
export DOKPLOY_VERSION=feature && curl -sSL https://dokploy.com/install.sh | sh
curl -sSL https://dokploy.com/install.sh | sh (defaults to latest)
```
Alternatively, you can use `bash -s`:
**Install/Update to Latest Stable:**
```bash
export DOKPLOY_VERSION=latest && curl -sSL https://dokploy.com/install.sh | sh
```
**Install/Update to Specific Version:**
```bash
export DOKPLOY_VERSION=v0.26.6 && curl -sSL https://dokploy.com/install.sh | sh
```
**Auto-detect Latest Stable (Default):**
```bash
curl -sSL https://dokploy.com/install.sh | sh
```
Alternatively, you can use `bash -s` for inline version specification:
```bash
DOKPLOY_VERSION=canary bash -s < <(curl -sSL https://dokploy.com/install.sh)
DOKPLOY_VERSION=feature bash -s < <(curl -sSL https://dokploy.com/install.sh)
DOKPLOY_VERSION=v0.26.6 bash -s < <(curl -sSL https://dokploy.com/install.sh)
```
### Additional Environment Variables
**Custom Docker Swarm Network Configuration:**
```bash
export DOCKER_SWARM_INIT_ARGS="--default-addr-pool 172.20.0.0/16 --default-addr-pool-mask-length 24"
curl -sSL https://dokploy.com/install.sh | sh
```
**Manual Advertise Address:**
```bash
export ADVERTISE_ADDR=192.168.1.100
curl -sSL https://dokploy.com/install.sh | sh
```

View File

@@ -460,13 +460,18 @@ You should now be able to access the user interface.
In the case you want to recreate the dokploy services, you can do the following:
<Callout type='warn'>
**Important:** Before recreating services, make sure you have backups of your data. Recreating services will not delete your volumes, but it's always good to have backups.
</Callout>
Remove the dokploy-redis service:
### Recreate Redis Service
Remove and recreate the dokploy-redis service:
```bash
docker service rm dokploy-redis
# Create a new dokploy-redis service
docker service create \
docker service create \
--name dokploy-redis \
--constraint 'node.role==manager' \
--network dokploy-network \
@@ -479,18 +484,23 @@ Remove the dokploy-postgres service:
```bash
docker service rm dokploy-postgres
# Create a new dokploy-postgres service
docker service create \
# Create a new dokploy-postgres service with Docker Secrets
docker service create \
--name dokploy-postgres \
--constraint 'node.role==manager' \
--network dokploy-network \
--env POSTGRES_USER=dokploy \
--env POSTGRES_DB=dokploy \
--env POSTGRES_PASSWORD=amukds4wi9001583845717ad2 \
--secret source=dokploy_postgres_password,target=/run/secrets/postgres_password \
--env POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password \
--mount type=volume,source=dokploy-postgres,target=/var/lib/postgresql/data \
postgres:16
```
<Callout type='info'>
**Note:** Using Docker Secrets is the recommended approach for managing sensitive data like passwords. The secret is encrypted and only available to services that have been granted access to it.
</Callout>
Remove the dokploy-traefik service:
@@ -507,7 +517,7 @@ docker run -d \
-p 80:80/tcp \
-p 443:443/tcp \
-p 443:443/udp \
traefik:v3.6.1
traefik:v3.6.7
docker network connect dokploy-network dokploy-traefik
@@ -525,24 +535,27 @@ docker service create \
--publish mode=host,published=443,target=443 \
--publish mode=host,published=80,target=80 \
--publish mode=host,published=443,target=443,protocol=udp \
traefik:v3.6.1
traefik:v3.6.7
```
Remove the dokploy service:
### Recreate Dokploy Service
First, get the private IP of your server for the ADVERTISE_ADDR:
```bash
# Get the private IP of your server
ip addr show | grep -E "inet (192\.168\.|10\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.)" | head -n1 | awk '{print $2}' | cut -d/ -f1
```
Copy the IP address from the output and use it in the command below.
Remove and recreate the dokploy service:
```bash
docker service rm dokploy
# Create a new dokploy service
# We need the advertise address to be set which is the Private IP of your server, you can get it by running the following command:
# Run this command to get the private IP of your server:
# Copy this value and paste in the ADVERTISE_ADDR variable:
ip addr show | grep -E "inet (192\.168\.|10\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.)" | head -n1 | awk '{print $2}' | cut -d/ -f1
# Create the dokploy service
# Replace <YOUR_PRIVATE_IP> with the IP you got from the command above
docker service create \
--name dokploy \
--replicas 1 \
@@ -550,11 +563,34 @@ docker service create \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--mount type=bind,source=/etc/dokploy,target=/etc/dokploy \
--mount type=volume,source=dokploy,target=/root/.docker \
--secret source=dokploy_postgres_password,target=/run/secrets/postgres_password \
--publish published=3000,target=3000,mode=host \
--update-parallelism 1 \
--update-order stop-first \
--constraint 'node.role == manager' \
-e ADVERTISE_ADDR="Eg: 192.168.1.100" \
-e ADVERTISE_ADDR=<YOUR_PRIVATE_IP> \
-e POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password \
dokploy/dokploy:latest
```
**For Proxmox LXC environments**, add the `--endpoint-mode dnsrr` flag to all services:
```bash
docker service create \
--name dokploy \
--replicas 1 \
--network dokploy-network \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--mount type=bind,source=/etc/dokploy,target=/etc/dokploy \
--mount type=volume,source=dokploy,target=/root/.docker \
--secret source=dokploy_postgres_password,target=/run/secrets/postgres_password \
--publish published=3000,target=3000,mode=host \
--update-parallelism 1 \
--update-order stop-first \
--constraint 'node.role == manager' \
--endpoint-mode dnsrr \
-e ADVERTISE_ADDR=<YOUR_PRIVATE_IP> \
-e POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password \
dokploy/dokploy:latest
```

View File

@@ -1477,6 +1477,10 @@
"type": "string",
"nullable": true
},
"bitbucketRepositorySlug": {
"type": "string",
"nullable": true
},
"bitbucketId": {
"type": "string",
"nullable": true
@@ -1500,6 +1504,7 @@
"bitbucketBuildPath",
"bitbucketOwner",
"bitbucketRepository",
"bitbucketRepositorySlug",
"bitbucketId",
"applicationId",
"enableSubmodules"
@@ -2067,6 +2072,10 @@
"type": "string",
"nullable": true
},
"bitbucketRepositorySlug": {
"type": "string",
"nullable": true
},
"bitbucketOwner": {
"type": "string",
"nullable": true
@@ -3911,7 +3920,7 @@
},
"dockerImage": {
"type": "string",
"default": "postgres:15"
"default": "postgres:18"
},
"environmentId": {
"type": "string"
@@ -4408,7 +4417,7 @@
},
"dockerImage": {
"type": "string",
"default": "postgres:15"
"default": "postgres:18"
},
"command": {
"type": "string",
@@ -7961,6 +7970,10 @@
"type": "string",
"nullable": true
},
"bitbucketRepositorySlug": {
"type": "string",
"nullable": true
},
"bitbucketOwner": {
"type": "string",
"nullable": true
@@ -9384,9 +9397,6 @@
},
"currentPassword": {
"type": "string"
},
"name": {
"type": "string"
}
},
"additionalProperties": false
@@ -12723,8 +12733,18 @@
]
},
"letsEncryptEmail": {
"type": "string",
"format": "email",
"anyOf": [
{
"type": "string",
"format": "email"
},
{
"type": "string",
"enum": [
""
]
}
],
"nullable": true
},
"https": {
@@ -17024,6 +17044,266 @@
}
}
},
"/notification.createPushover": {
"post": {
"operationId": "notification-createPushover",
"tags": [
"notification"
],
"security": [
{
"Authorization": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"appBuildError": {
"type": "boolean"
},
"databaseBackup": {
"type": "boolean"
},
"volumeBackup": {
"type": "boolean"
},
"dokployRestart": {
"type": "boolean"
},
"name": {
"type": "string"
},
"appDeploy": {
"type": "boolean"
},
"dockerCleanup": {
"type": "boolean"
},
"serverThreshold": {
"type": "boolean"
},
"userKey": {
"type": "string",
"minLength": 1
},
"apiToken": {
"type": "string",
"minLength": 1
},
"priority": {
"type": "number",
"minimum": -2,
"maximum": 2,
"default": 0
},
"retry": {
"type": "number",
"minimum": 30,
"nullable": true
},
"expire": {
"type": "number",
"minimum": 1,
"maximum": 10800,
"nullable": true
}
},
"required": [
"name",
"userKey",
"apiToken"
],
"additionalProperties": false
}
}
}
},
"parameters": [],
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {}
}
},
"default": {
"$ref": "#/components/responses/error"
}
}
}
},
"/notification.updatePushover": {
"post": {
"operationId": "notification-updatePushover",
"tags": [
"notification"
],
"security": [
{
"Authorization": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"notificationId": {
"type": "string",
"minLength": 1
},
"pushoverId": {
"type": "string",
"minLength": 1
},
"organizationId": {
"type": "string"
},
"userKey": {
"type": "string",
"minLength": 1
},
"apiToken": {
"type": "string",
"minLength": 1
},
"priority": {
"type": "number",
"minimum": -2,
"maximum": 2
},
"retry": {
"type": "number",
"minimum": 30,
"nullable": true
},
"expire": {
"type": "number",
"minimum": 1,
"maximum": 10800,
"nullable": true
},
"appBuildError": {
"type": "boolean"
},
"databaseBackup": {
"type": "boolean"
},
"volumeBackup": {
"type": "boolean"
},
"dokployRestart": {
"type": "boolean"
},
"name": {
"type": "string"
},
"appDeploy": {
"type": "boolean"
},
"dockerCleanup": {
"type": "boolean"
},
"serverThreshold": {
"type": "boolean"
}
},
"required": [
"notificationId",
"pushoverId"
],
"additionalProperties": false
}
}
}
},
"parameters": [],
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {}
}
},
"default": {
"$ref": "#/components/responses/error"
}
}
}
},
"/notification.testPushoverConnection": {
"post": {
"operationId": "notification-testPushoverConnection",
"tags": [
"notification"
],
"security": [
{
"Authorization": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"userKey": {
"type": "string",
"minLength": 1
},
"apiToken": {
"type": "string",
"minLength": 1
},
"priority": {
"type": "number",
"minimum": -2,
"maximum": 2
},
"retry": {
"type": "number",
"minimum": 30,
"nullable": true
},
"expire": {
"type": "number",
"minimum": 1,
"maximum": 10800,
"nullable": true
}
},
"required": [
"userKey",
"apiToken",
"priority"
],
"additionalProperties": false
}
}
}
},
"parameters": [],
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {}
}
},
"default": {
"$ref": "#/components/responses/error"
}
}
}
},
"/notification.getEmailProviders": {
"get": {
"operationId": "notification-getEmailProviders",

View File

@@ -47,6 +47,37 @@ is_proxmox_lxc() {
return 1 # Not LXC
}
generate_random_password() {
# Generate a secure random password using multiple methods with fallbacks
local password=""
# Try using openssl (most reliable, available on most systems)
if command -v openssl >/dev/null 2>&1; then
password=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-32)
# Fallback to /dev/urandom with tr (most Linux systems)
elif [ -r /dev/urandom ]; then
password=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 32)
# Last resort fallback using date and simple hashing
else
if command -v sha256sum >/dev/null 2>&1; then
password=$(date +%s%N | sha256sum | base64 | head -c 32)
elif command -v shasum >/dev/null 2>&1; then
password=$(date +%s%N | shasum -a 256 | base64 | head -c 32)
else
# Very basic fallback - combines multiple sources of entropy
password=$(echo "$(date +%s%N)-$(hostname)-$$-$RANDOM" | base64 | tr -d "=+/" | head -c 32)
fi
fi
# Ensure we got a password of correct length
if [ -z "$password" ] || [ ${#password} -lt 20 ]; then
echo "Error: Failed to generate random password" >&2
exit 1
fi
echo "$password"
}
install_dokploy() {
# Detect version tag
VERSION_TAG=$(detect_version)
@@ -199,13 +230,22 @@ install_dokploy() {
chmod 777 /etc/dokploy
# Generate secure random password for Postgres
POSTGRES_PASSWORD=$(generate_random_password)
# Store password as Docker Secret (encrypted and secure)
echo "$POSTGRES_PASSWORD" | docker secret create dokploy_postgres_password - 2>/dev/null || true
echo "Generated secure database credentials (stored in Docker Secrets)"
docker service create \
--name dokploy-postgres \
--constraint 'node.role==manager' \
--network dokploy-network \
--env POSTGRES_USER=dokploy \
--env POSTGRES_DB=dokploy \
--env POSTGRES_PASSWORD=amukds4wi9001583845717ad2 \
--secret source=dokploy_postgres_password,target=/run/secrets/postgres_password \
--env POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password \
--mount type=volume,source=dokploy-postgres,target=/var/lib/postgresql/data \
$endpoint_mode \
postgres:16
@@ -232,6 +272,7 @@ install_dokploy() {
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--mount type=bind,source=/etc/dokploy,target=/etc/dokploy \
--mount type=volume,source=dokploy,target=/root/.docker \
--secret source=dokploy_postgres_password,target=/run/secrets/postgres_password \
--publish published=3000,target=3000,mode=host \
--update-parallelism 1 \
--update-order stop-first \
@@ -239,6 +280,7 @@ install_dokploy() {
$endpoint_mode \
$release_tag_env \
-e ADVERTISE_ADDR=$advertise_addr \
-e POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password \
$DOCKER_IMAGE
sleep 4
@@ -252,7 +294,7 @@ install_dokploy() {
-p 80:80/tcp \
-p 443:443/tcp \
-p 443:443/udp \
traefik:v3.6.1
traefik:v3.6.7
docker network connect dokploy-network dokploy-traefik
@@ -268,7 +310,7 @@ install_dokploy() {
# --publish mode=host,published=443,target=443 \
# --publish mode=host,published=80,target=80 \
# --publish mode=host,published=443,target=443,protocol=udp \
# traefik:v3.6.1
# traefik:v3.6.7
GREEN="\033[0;32m"
YELLOW="\033[1;33m"
@@ -315,4 +357,4 @@ if [ "$1" = "update" ]; then
update_dokploy
else
install_dokploy
fi
fi