...
How to install dokploy on ubuntu vps
Learn how to install dokploy on ubuntu vps!

This article provides a guide demonstrating how to install Dokploy on Ubuntu VPS.

Table of Contents

What is Dokploy?

Dokploy is a self-hosted Platform as a Service, or PaaS, that provides a web interface for deploying and managing applications, databases, Docker Compose projects, domains, SSL certificates, environment variables, and automated deployments.

It is designed as a self-hosted alternative to services such as Heroku, Vercel, and Netlify. Dokploy uses Docker for application workloads and Traefik for HTTP and HTTPS routing.

This guide demonstrates how to install Dokploy on a fresh Ubuntu VPS and prepare it for production use.

Deployment overview

The completed installation will use the following general architecture:

Internet
   |
   | TCP 80 and 443
   v
Traefik reverse proxy
   |
   +-- Dokploy administration panel
   |
   +-- Application containers
   |
   +-- Database containers
   |
   +-- Docker Compose projects

Dokploy installs and manages several components, including:

  • Docker Engine
  • Docker Swarm
  • Dokploy
  • PostgreSQL for Dokploy’s internal data
  • Traefik for reverse proxying and TLS
  • Docker networks and persistent volumes

For a basic single-server deployment, Dokploy, Traefik, application containers, and databases can all run on the same VPS.

Requirements and planning

Recommended server specifications

Dokploy officially recommends at least:

  • 2 GB RAM
  • 30 GB storage
  • A supported Linux distribution
  • Available ports 80, 443, and 3000

Ubuntu 20.04, 22.04, and 24.04 LTS are among the officially tested Ubuntu versions.

Although 2 GB is the documented minimum, a production installation should generally start with:

CPU:      2 or more vCPU
Memory:   4 GB RAM or more
Storage:  50 GB SSD or more
Network:  Public IPv4 address
OS:       Ubuntu 24.04 LTS

Use additional CPU, memory, and storage when the server will:

  • Build large applications
  • Run several databases
  • Host multiple customer applications
  • Build Node.js, Java, Rust, or other memory-intensive projects
  • Retain many Docker images
  • Run monitoring or log-collection services

A small swap file is also useful as an emergency buffer, although swap should not replace adequate physical memory.

Required network ports

The standard installation requires these inbound ports:

Port Protocol Purpose
22 TCP SSH administration
80 TCP HTTP and Let’s Encrypt validation
443 TCP HTTPS application traffic
443 UDP HTTP/3, when enabled through Traefik
3000 TCP Initial Dokploy administration interface

Ports 80, 443, and 3000 must be unused before the installation begins. The installer stops when another service already occupies one of these ports.

Port 3000 should only remain publicly accessible long enough to create the initial administrator account and configure a secure domain.

See Also: How to Install Coroot on Ubuntu VPS

Choose a hostname

Select a fully qualified hostname for the Dokploy control panel.

For example:

dokploy.example.com

Create an A record pointing the hostname to the VPS public IPv4 address:

Type:   A
Name:   dokploy
Value:  203.0.113.20
TTL:    300

When IPv6 is configured and working correctly, you may also create an AAAA record.

Verify DNS resolution before configuring HTTPS:

dig +short dokploy.example.com

Or:

getent ahostsv4 dokploy.example.com

The returned address should match the VPS public IPv4 address.
Launch 100% ssd ubuntu vps from $3. 19/mo!


Compare Ubuntu VPS Plans

KVM-SSD-1
KVM-SSD-8
KVM-SSD-16
KVM-SSD-32
CPU
1 Core
2 Cores
4 Cores
8 Cores
Memory
1 GB
8 GB
16 GB
32 GB
Storage
16 GB NVMe
128 GB NVMe
256 GB NVMe
512 GB NVMe
Bandwidth
1 TB
4 TB
8 TB
16 TB
Network
1 Gbps
1 Gbps
1 Gbps
1 Gbps
Delivery Time
⏱️ Instant
⏱️ Instant
⏱️ Instant
⏱️ Instant
Location
US/EU/APAC
US/EU/APAC
US/EU/APAC
US/EU/APAC
Price
$7.58*
$39.50*
$79.40*
$151.22*
KVM-SSD-1
$7.58*
CPU 1 Core
Memory 1 GB
Storage 16 GB NVMe
Bandwidth 1 TB
Network 1 Gbps
Delivery Time ⏱️ Instant
Location US/EU/APAC
KVM-SSD-8
$39.50*
CPU 2 Cores
Memory 8 GB
Storage 128 GB NVMe
Bandwidth 4 TB
Network 1 Gbps
Delivery Time ⏱️ Instant
Location US/EU/APAC
KVM-SSD-16
$79.40*
CPU 4 Cores
Memory 16 GB
Storage 256 GB NVMe
Bandwidth 8 TB
Network 1 Gbps
Delivery Time ⏱️ Instant
Location US/EU/APAC
KVM-SSD-32
$151.22*
CPU 8 Cores
Memory 32 GB
Storage 512 GB NVMe
Bandwidth 16 TB
Network 1 Gbps
Delivery Time ⏱️ Instant
Location US/EU/APAC

How to Install Dokploy on Ubuntu VPS

To install Dokploy on Ubuntu VPS, follow the steps outlined below:

  1. Connect to the VPS

    Connect as root:

    ssh root@203.0.113.20
    

    Alternatively, connect as a sudo-enabled administrator:

    ssh administrator@203.0.113.20
    

    Then open a root shell:

    sudo -i
    

    The Dokploy installation script must run with root privileges.

  2. Verify the operating system

    Display the Ubuntu release:

    cat /etc/os-release
    

    Example:

    PRETTY_NAME="Ubuntu 24.04.2 LTS"
    NAME="Ubuntu"
    VERSION_ID="24.04"
    

    Check the kernel:

    uname -r
    

    Check the server architecture:

    dpkg --print-architecture
    

    Most VPS installations should report:

    amd64
    

    Dokploy should be installed directly on a VPS or virtual machine, not inside a regular Docker container. The official installation script checks for containerized environments and exits when it detects one.

  3. Update Ubuntu

    Update the package index and install available updates:

    apt update
    apt full-upgrade -y
    

    Install common administration utilities:

    apt install -y \
        curl \
        wget \
        ca-certificates \
        gnupg \
        jq \
        unzip \
        nano \
        vim \
        git \
        ufw \
        dnsutils \
        htop \
        lsof
    

    Reboot when the upgrade installed a new kernel or important system libraries:

    reboot
    

    Reconnect after the server restarts.

  4. Configure the hostname

    Set a descriptive system hostname:

    hostnamectl set-hostname dokploy01.example.com
    

    Confirm it:

    hostnamectl
    

    Add the hostname to /etc/hosts when necessary:

    nano /etc/hosts
    

    Example:

    127.0.0.1 localhost
    127.0.1.1 dokploy01.example.com dokploy01
    

    Do not map the public control-panel hostname to 127.0.0.1 if applications on the server must resolve it to the public address.

  5. Configure the timezone

    List available timezones:

    timedatectl list-timezones
    

    Set the appropriate timezone:

    timedatectl set-timezone America/Chicago
    

    Verify the setting:

    timedatectl
    

    Dokploy also supports a configurable TZ environment variable for customized installations.

  6. Configure time synchronization

    Check the system clock:

    timedatectl status
    

    Enable systemd time synchronization:

    timedatectl set-ntp true
    

    Confirm that synchronization is active:

    timedatectl timesync-status
    

    Accurate time is important for TLS certificates, authentication, scheduled jobs, logs, and database operations.

  7. Add swap space

    Check whether swap is already available:

    See Also: cPanel Shared Hosting Server Specs

    swapon --show
    free -h
    

    For a small VPS with no swap, create a 2 GB swap file:

    fallocate -l 2G /swapfile
    

    Restrict access:

    chmod 600 /swapfile
    

    Initialize it:

    mkswap /swapfile
    

    Enable it:

    swapon /swapfile
    

    Make it persistent:

    echo '/swapfile none swap sw 0 0' >> /etc/fstab
    

    Set a conservative swappiness value:

    cat > /etc/sysctl.d/99-dokploy-memory.conf <<'EOF'
    vm.swappiness=10
    vm.vfs_cache_pressure=50
    EOF
    

    Apply the settings:

    sysctl --system
    

    Verify:

    swapon --show
    free -h
    
  8. Inspect ports 80, 443, and 3000

    Run:

    ss -lntup | grep -E ':(80|443|3000)\b' || true
    

    You can also check each port individually:

    lsof -iTCP:80 -sTCP:LISTEN
    lsof -iTCP:443 -sTCP:LISTEN
    lsof -iTCP:3000 -sTCP:LISTEN
    

    There should be no output.

    Common conflicting services include:

    • Apache
    • Nginx
    • Caddy
    • An existing Traefik instance
    • A Node.js application using port 3000
    • Another hosting control panel

    To stop Apache:

    systemctl disable --now apache2
    

    To stop Nginx:

    systemctl disable --now nginx
    

    To stop Caddy:

    systemctl disable --now caddy
    

    Remove a conflicting web server only when it is no longer needed:

    apt remove --purge -y apache2 apache2-utils
    

    Or:

    apt remove --purge -y nginx nginx-common
    

    Recheck the ports:

    ss -lntup | grep -E ':(80|443|3000)\b' || true
    
  9. Check for an existing Docker Swarm

    If Docker is already installed, inspect its Swarm status:

    docker info 2>/dev/null | grep -i swarm || true
    

    Do not run the normal Dokploy installer on a server already participating in a production Docker Swarm. The official installer forces the node to leave its current Swarm and initializes a new one, which can disrupt existing services.

    A clean VPS is strongly recommended.

  10. Configure a provider-level firewall

    When your VPS provider offers a network firewall, allow:

    TCP 22    from your trusted administration IP addresses
    TCP 80    from anywhere
    TCP 443   from anywhere
    UDP 443   from anywhere, when HTTP/3 is desired
    TCP 3000  temporarily from your trusted administration IP
    

    A provider firewall is especially useful for restricting the initial port 3000 exposure.

    For example, permit port 3000 only from:

    198.51.100.25/32
    

    After configuring a domain and HTTPS, remove the port 3000 rule.

  11. Configure UFW

    Before enabling UFW, permit SSH:

    ufw allow OpenSSH
    

    Or restrict SSH to your workstation address:

    ufw allow from 198.51.100.25 to any port 22 proto tcp
    

    Permit HTTP and HTTPS:

    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw allow 443/udp
    

    Temporarily permit the Dokploy interface from your IP:

    See Also: How to Migrate Your Website from A2 Hosting to Rad Web Hosting

    ufw allow from 198.51.100.25 to any port 3000 proto tcp
    

    Set default policies:

    ufw default deny incoming
    ufw default allow outgoing
    

    Enable UFW:

    ufw enable
    

    Review the rules:

    ufw status numbered
    
    Important Docker firewall consideration

    Docker creates its own packet-filtering and port-publication rules. Published container ports may therefore require controls beyond ordinary UFW rules. Docker recommends placing custom filtering rules in the DOCKER-USER chain rather than disabling Docker’s firewall management, because disabling Docker-managed rules can break container networking.

    For this reason, use the provider-level firewall as the primary restriction for the temporary port 3000 exposure whenever possible.

  12. Review the installer before running it

    The official one-line installation command is:

    curl -sSL https://dokploy.com/install.sh | sh
    

    For a production server, it is safer to download and inspect the script first:

    curl -fsSL https://dokploy.com/install.sh -o /root/install-dokploy.sh
    

    Review it:

    less /root/install-dokploy.sh
    

    Optionally calculate a local checksum for your records:

    sha256sum /root/install-dokploy.sh
    

    Make it executable:

    chmod 700 /root/install-dokploy.sh
    

    Run it:

    /root/install-dokploy.sh
    

    The script installs Docker automatically when Docker is not already present and deploys the required Dokploy services.

  13. Install the latest stable release explicitly

    To explicitly select the latest stable release:

    export DOKPLOY_VERSION=latest
    /root/install-dokploy.sh
    

    Alternatively:

    curl -fsSL https://dokploy.com/install.sh | DOKPLOY_VERSION=latest sh
    

    Avoid the canary release on production systems. Canary builds are development versions:

    export DOKPLOY_VERSION=canary
    curl -sSL https://dokploy.com/install.sh | sh
    

    Use canary only for testing or when instructed by the Dokploy project.

    The installer supports latest, canary, and specific release tags through DOKPLOY_VERSION.

  14. Pin a specific Dokploy version

    For a controlled production rollout, choose a specific current release from the official Dokploy release page and pass the tag:

    export DOKPLOY_VERSION=v0.29.13
    /root/install-dokploy.sh
    

    At the time this guide was prepared, the official release list identified v0.29.13 as the latest release. Always verify the current release and security notes before installation.

    Pinning provides more predictable behavior, while latest automatically selects the newest stable version available to the installer.

  15. Specify the Docker Swarm advertise address

    On a VPS with multiple network interfaces, private networking, or a VPN, the installer may select the wrong address.

    List IPv4 addresses:

    See Also: Migrating Email Accounts Using Imapsync (Quick 5 Minute Guide)

    ip -4 address show
    

    Display the default route:

    ip route
    

    Run the installer with an explicit Swarm advertise address:

    curl -fsSL https://dokploy.com/install.sh | \
        ADVERTISE_ADDR=203.0.113.20 sh
    

    When using sudo, pass the environment variable inline:

    curl -fsSL https://dokploy.com/install.sh | \
        sudo ADVERTISE_ADDR=203.0.113.20 sh
    

    Do not assume that an exported variable will survive sudo, because sudo normally resets the environment. Dokploy’s documentation specifically recommends passing ADVERTISE_ADDR inline in this situation.

    When the VPS has a reliable private network, that private address may be preferable for future multi-node Swarm communication.

  16. Avoid Docker network conflicts

    Docker networks must not overlap with:

    • The VPS private network
    • A WireGuard network
    • A Tailscale network
    • Office or management networks
    • Other container platforms

    For example, initialize Dokploy with a custom Docker Swarm address pool:

    export DOCKER_SWARM_INIT_ARGS="--default-addr-pool 172.20.0.0/16 --default-addr-pool-mask-length 24"
    curl -fsSL https://dokploy.com/install.sh | sh
    

    Choose a range that does not conflict with existing routes.

    Inspect current routes first:

    ip route
    

    The official installer supports DOCKER_SWARM_INIT_ARGS specifically for avoiding address conflicts with provider networks and VPCs.

  17. Check Docker

    Verify the Docker service:

    systemctl status docker --no-pager
    

    Check its version:

    docker version
    

    Display general information:

    docker info
    

    Confirm that Docker Swarm is active:

    docker info | grep -i swarm
    

    Expected:

    Swarm: active
    

    Check the node:

    docker node ls
    

    A single-server installation should show the local server as a Swarm manager.

  18. Check Dokploy services

    List Docker Swarm services:

    docker service ls
    

    You should normally see services such as:

    dokploy
    dokploy-postgres
    

    Traefik may appear as a standalone container, depending on the installed Dokploy version.

    List running containers:

    docker ps
    

    Current self-hosted Dokploy installations normally include:

    • Dokploy
    • PostgreSQL
    • Traefik

    Older releases before Dokploy 0.29.9 may also include Redis; newer self-hosted versions no longer use it.

  19. Check listening ports

    Run:

    ss -lntup | grep -E ':(80|443|3000)\b'
    

    Expected listeners include:

    0.0.0.0:80
    0.0.0.0:443
    0.0.0.0:3000
    

    Check the local Dokploy response:

    curl -I http://127.0.0.1:3000
    

    Also test the server’s public address:

    curl -I http://203.0.113.20:3000
    
  20. Inspect logs

    Dokploy logs:

    docker service logs --tail 100 dokploy
    

    Follow the logs live:

    docker service logs -f dokploy
    

    PostgreSQL logs:

    docker service logs --tail 100 dokploy-postgres
    

    Traefik logs:

    docker logs --tail 100 dokploy-traefik
    

    Follow Traefik logs:

    See Also: Install Coder on AlmaLinux VPS and Connect Workspace to VS Code (5 Minute Quick-Start Guide)

    docker logs -f dokploy-traefik
    

    These are the primary log commands recommended in Dokploy’s troubleshooting documentation.

  21. Open the Dokploy dashboard

    Open the following address in a browser:

    http://203.0.113.20:3000
    

    You should see the initial account-creation page.

    Create the first administrator account using:

    • A unique email address
    • A long, randomly generated password
    • Credentials not reused on other systems

    The first account becomes the Dokploy administrator.

    Do not leave the initial registration page exposed longer than necessary.

  22. Enable multifactor authentication

    After logging in, open the account security settings and enable two-factor authentication when available.

    Store the following safely:

    • TOTP secret or QR-code recovery data
    • Recovery codes
    • Administrative password
    • Server SSH recovery credentials

    Keep recovery data outside the Dokploy server.

  23. Confirm DNS

    Confirm the panel hostname resolves to the VPS:

    dig +short dokploy.example.com A
    

    Expected:

    203.0.113.20
    

    Check from an external computer as well:

    nslookup dokploy.example.com
    

    Do not request a certificate until public DNS points to the correct server.

  24. Add the Dokploy panel domain

    Inside Dokploy:

    1. Open the server or web-server settings.
    2. Locate the domain configuration for the Dokploy panel.
    3. Add:
    dokploy.example.com
    
    1. Enable HTTPS.
    2. Select Let’s Encrypt as the certificate provider.
    3. Save the configuration.
    4. Allow Dokploy and Traefik to generate the routing configuration.

    The panel should become available at:

    https://dokploy.example.com
    

    Dokploy supports domain TLS configurations including Let’s Encrypt, Cloudflare, and custom certificates.

  25. Verify the certificate

    Test HTTPS:

    curl -I https://dokploy.example.com
    

    Inspect the certificate:

    openssl s_client \
        -connect dokploy.example.com:443 \
        -servername dokploy.example.com \
        </dev/null 2>/dev/null |
    openssl x509 -noout -issuer -subject -dates
    

    Confirm:

    • The certificate subject matches the hostname.
    • The certificate is currently valid.
    • The issuer is trusted.
    • HTTP redirects to HTTPS as expected.

    Test the redirect:

    curl -I http://dokploy.example.com
    
  26. Cloudflare considerations

    When the domain uses Cloudflare:

    1. Initially set the DNS record to DNS only.
    2. Complete the origin certificate issuance.
    3. Verify direct HTTPS access.
    4. Enable Cloudflare proxying afterward, when desired.
    5. Use Full (strict) SSL mode whenever the origin has a valid certificate.

    Dokploy’s Cloudflare documentation describes end-to-end encrypted configurations and the use of strict origin validation.

    Avoid Cloudflare’s Flexible mode because it does not provide encrypted traffic between Cloudflare and the origin server.

  27. Confirm the domain works first

    Before removing direct access, verify:

    https://dokploy.example.com
    

    Test it from:

    • Your normal browser
    • A private or incognito browser window
    • A separate internet connection where possible

    Do not continue until HTTPS access works reliably.

  28. Remove Dokploy’s published port

    Dokploy officially recommends removing the direct IP:3000 publication after the secure domain is working.

    See Also: 6 Ways to Customize the VPS Panel With Your Branding – Cloud Admin Guide

    Run:

    docker service update \
        --publish-rm "published=3000,target=3000,mode=host" \
        dokploy
    

    This removes public port 3000 while allowing Traefik to reach Dokploy over the internal Docker network.

    Verify:

    docker service inspect dokploy \
        --format '{{json .Endpoint.Spec.Ports}}' | jq
    

    Check listening ports:

    ss -lntup | grep ':3000\b' || true
    

    The public listener should be gone.

  29. Remove firewall access to port 3000

    List UFW rules:

    ufw status numbered
    

    Delete the rule by number:

    ufw delete RULE_NUMBER
    

    For example:

    ufw delete 4
    

    Also remove the corresponding rule from the VPS provider firewall.

    The final public exposure should normally be:

    22/tcp   restricted to trusted management sources
    80/tcp   public
    443/tcp  public
    443/udp  public when HTTP/3 is used
    
  30. Create a project

    In Dokploy:

    1. Open Projects.
    2. Select Create Project.
    3. Enter a project name:
    test-project
    
    1. Create an environment:
    production
    
    1. Add an application.
  31. Deploy from a public Git repository

    Choose a public Git provider or repository URL.

    Configure:

    Repository: https://github.com/example/example-app.git
    Branch:     main
    

    Select the appropriate build method:

    • Dockerfile
    • Docker Compose
    • Nixpacks
    • Railpack
    • Static site, where supported

    Specify the application port. For example:

    3000
    

    Add required environment variables, then click Deploy.

    Monitor:

    • Build logs
    • Deployment logs
    • Container logs
    • Health status
  32. Assign an application domain

    Create another DNS record:

    Type:   A
    Name:   app
    Value:  203.0.113.20
    

    Inside the application:

    1. Open Domains.
    2. Add:
    app.example.com
    
    1. Enter the application’s internal container port.
    2. Enable HTTPS.
    3. Select Let’s Encrypt.
    4. Save and redeploy when prompted.

    Open:

    https://app.example.com
    

    Do not publish the application’s internal port directly unless external port access is specifically required. Let Traefik route normal HTTP and HTTPS traffic.

  33. Add an SSH key for private repositories

    Create a dedicated key on a secure administration workstation or through Dokploy’s SSH-key interface.

    Command-line example:

    ssh-keygen -t ed25519 -C "dokploy-deploy-key"
    

    Use a dedicated deployment key rather than a personal administrative key.

    Add the public key to:

    • GitHub deploy keys
    • GitLab deploy keys
    • Bitbucket access keys
    • Your private Git server

    Store the private key in Dokploy’s SSH-key configuration.

    Grant read-only repository access unless Dokploy specifically needs write access.

  34. Configure automatic deployment

    For supported Git providers:

    1. Add the Git provider integration.
    2. Authorize only the required repositories.
    3. Select the branch to deploy.
    4. Enable automatic deployment.
    5. Configure watch paths when using a monorepo.
    6. Trigger a test commit.
    7. Confirm that the webhook starts a deployment.

    Use separate credentials or Git applications for production environments.

  35. Create a non-root SSH administrator

    Create an account:

    See Also: Ultimate Guide to VPS Security Hardening

    adduser deployadmin
    

    Grant sudo access:

    usermod -aG sudo deployadmin
    

    Copy the SSH key configuration:

    rsync --archive --chown=deployadmin:deployadmin \
        /root/.ssh /home/deployadmin/
    

    Test the new account in a separate terminal:

    ssh deployadmin@203.0.113.20
    

    Confirm sudo access:

    sudo -i
    

    Do not disable root access until the new account has been tested successfully.

  36. Harden SSH

    Create a configuration drop-in:

    nano /etc/ssh/sshd_config.d/99-hardening.conf
    

    Example:

    PermitRootLogin prohibit-password
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    PubkeyAuthentication yes
    X11Forwarding no
    AllowTcpForwarding yes
    MaxAuthTries 4
    LoginGraceTime 30
    

    Validate the configuration:

    sshd -t
    

    Reload SSH:

    systemctl reload ssh
    

    Keep the current SSH session open while testing a new connection.

    Once key-based access is confirmed, you may change:

    PermitRootLogin no
    
  37. Install Fail2ban

    Install it:

    apt install -y fail2ban
    

    Create a local configuration:

    cat > /etc/fail2ban/jail.d/sshd.local <<'EOF'
    [sshd]
    enabled = true
    port = ssh
    backend = systemd
    maxretry = 5
    findtime = 10m
    bantime = 1h
    EOF
    

    Enable it:

    systemctl enable --now fail2ban
    

    Check status:

    fail2ban-client status
    fail2ban-client status sshd
    
  38. Enable automatic security updates

    Install the package:

    apt install -y unattended-upgrades
    

    Enable automatic configuration:

    dpkg-reconfigure -plow unattended-upgrades
    

    Verify timers:

    systemctl list-timers | grep apt
    

    Review:

    cat /etc/apt/apt.conf.d/20auto-upgrades
    

    Application maintenance windows should still be planned for kernel upgrades and Docker restarts.

  39. Protect Dokploy accounts

    Use these account practices:

    • Enable two-factor authentication.
    • Use separate accounts for each administrator.
    • Do not share the owner account.
    • Grant the minimum required permissions.
    • Remove former users promptly.
    • Rotate API keys and Git credentials.
    • Restrict provider integrations to required repositories.
    • Keep recovery codes offline.

    Dokploy supports owner, administrator, and member roles with different access levels. The owner has the highest privileges, while members can be assigned narrower permissions.

  40. Do not expose databases unnecessarily

    Applications connected to a database on an internal Docker network should use internal credentials and hostnames.

    Avoid publishing:

    5432
    3306
    27017
    6379
    

    to the public internet unless external database access is explicitly required.

    When external access is required:

    • Restrict the source IP.
    • Require TLS.
    • Use strong credentials.
    • Create a limited database user.
    • Prefer VPN or SSH-tunnel access.

    Dokploy distinguishes internal database connections from externally exposed connections; internal connections avoid unnecessary public exposure.

  41. Configure an S3-compatible destination

    Dokploy supports S3-compatible destinations for backups.

    See Also: Connect BigBlueButton Server to Moodle LMS for Integrated eLearning

    Possible storage targets include:

    • Amazon S3
    • Cloudflare R2
    • Backblaze B2 S3
    • Wasabi
    • MinIO
    • Other S3-compatible object stores

    In Dokploy:

    1. Open Settings.
    2. Open Destinations or S3 Destinations.
    3. Create a destination.
    4. Enter the endpoint, region, bucket, access key, and secret key.
    5. Test the connection.

    Use a dedicated bucket and limited-access credentials.

  42. Back up Dokploy itself

    Navigate to:

    Web Server → Backups
    

    Create a backup configuration and choose the S3 destination.

    A full Dokploy backup includes:

    • The Dokploy PostgreSQL database
    • The /etc/dokploy filesystem
    • A compressed backup archive uploaded to the configured S3 destination

    Dokploy’s restoration process can restore both its internal database and /etc/dokploy configuration.

    Example daily schedule:

    30 3 * * *
    

    This runs at 3:30 a.m. according to the applicable server or application timezone.

  43. Back up application databases

    For each managed database:

    1. Open the database.
    2. Select Backups.
    3. Choose the S3 destination.
    4. Enter the database name.
    5. Set a schedule.
    6. Enter a unique object prefix.
    7. Enable the backup.
    8. Click Test.
    9. Confirm the backup appears in the bucket.

    Dokploy provides scheduled database backups and a test function that performs an immediate backup to confirm the destination is working.

  44. Back up persistent volumes

    Applications using persistent Docker named volumes need separate volume backups.

    Dokploy supports volume backups to S3-compatible storage. This is useful for:

    • SQLite data
    • User uploads
    • Application-generated files
    • CMS content
    • Persistent service data

    Dokploy volume backups work with Docker named volumes, not arbitrary bind mounts.

    Document every application’s persistence model so that database and filesystem data are both protected.

  45. Test restoration

    A backup is not complete until it has been restored successfully.

    At least quarterly:

    1. Provision a temporary VPS.
    2. Install a compatible Dokploy version.
    3. Restore the Dokploy backup.
    4. Restore one or more application databases.
    5. Restore persistent volumes.
    6. Update temporary DNS or local hosts-file entries.
    7. Test the applications.
    8. Document the recovery time and any missing steps.
    9. Destroy the temporary environment after testing.

    Store backup credentials separately from the production server.

  46. Monitor host resources

    Check CPU and memory:

    htop
    

    Check memory:

    free -h
    

    Check storage:

    df -hT
    

    Check inode usage:

    df -ih
    

    Check Docker disk consumption:

    docker system df
    

    Check container utilization:

    docker stats
    

    Check failed services:

    systemctl --failed
    

    Storage deserves special attention because application builds and old Docker images can consume space rapidly. Dokploy notes that insufficient storage can prevent its PostgreSQL database and web interface from operating normally.

  47. Configure Docker log rotation

    Check the current Docker configuration:

    See Also: Announcing RWHServers for WHMCS: PAYG VPS & Dedicated Server Reselling

    cat /etc/docker/daemon.json 2>/dev/null || echo "No daemon.json present"
    

    For a new installation with no existing configuration, create:

    mkdir -p /etc/docker
    
    cat > /etc/docker/daemon.json <<'EOF'
    {
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "10m",
        "max-file": "5"
      }
    }
    EOF
    

    Validate the JSON:

    jq . /etc/docker/daemon.json
    

    Restarting Docker interrupts containers briefly, so perform this during a maintenance window:

    systemctl restart docker
    

    Confirm Docker returns:

    docker ps
    docker service ls
    

    Do not overwrite an existing daemon.json. Merge new properties into the existing JSON object.

  48. Clean unused Docker data carefully

    Review usage first:

    docker system df
    

    Remove unused build cache:

    docker builder prune
    

    Remove unused images:

    docker image prune
    

    Remove unused networks:

    docker network prune
    

    A more aggressive cleanup is:

    docker system prune -a
    

    This may remove images needed for fast rollback or redeployment. Review the prompt carefully and verify backups before using aggressive pruning on production systems.

    Do not add automatic volume pruning without thoroughly understanding the effect.

  49. Back up before updating

    Before every update:

    1. Create a fresh Dokploy backup.
    2. Confirm the backup is present in object storage.
    3. Back up important application databases.
    4. Review the release notes.
    5. Confirm available disk space.
    6. Record the currently installed version.
    7. Schedule a maintenance window.

    Display current services:

    docker service ls
    

    Display the current Dokploy image:

    docker service inspect dokploy \
        --format '{{.Spec.TaskTemplate.ContainerSpec.Image}}'
    
  50. Update to the latest version

    Run the official update command:

    curl -fsSL https://dokploy.com/install.sh | sh -s update
    

    Dokploy documents this command as the standard method for updating to the latest version.

    Monitor the update:

    docker service ps dokploy
    

    Follow logs:

    docker service logs -f --tail 100 dokploy
    

    Verify afterward:

    docker service ls
    docker ps
    curl -I https://dokploy.example.com
    
  51. Update to a specific release

    To deploy a specific version:

    export DOKPLOY_VERSION=v0.29.13
    curl -fsSL https://dokploy.com/install.sh | sh -s update
    

    When invoking through sudo, pass the variable inline or preserve the environment appropriately:

    curl -fsSL https://dokploy.com/install.sh | \
        sudo DOKPLOY_VERSION=v0.29.13 sh -s update
    

    Use only documented release tags from the official Dokploy repository.

  52. The installer reports that a port is already in use

    Identify the process:

    ss -lntup | grep -E ':(80|443|3000)\b'
    

    Or:

    fuser -v 80/tcp
    fuser -v 443/tcp
    fuser -v 3000/tcp
    

    Check common services:

    systemctl status nginx apache2 caddy --no-pager
    

    Stop the conflicting service:

    See Also: How to Deploy gVisor on Ubuntu VPS

    systemctl disable --now nginx
    

    Run the installer again only after all three required ports are free.

  53. Docker Swarm initialization fails

    A typical error is:

    must specify a listening address because the address to advertise
    is not recognized as a system address
    

    List server addresses:

    ip -4 addr
    

    Choose the correct address and rerun:

    curl -fsSL https://dokploy.com/install.sh | \
        sudo ADVERTISE_ADDR=203.0.113.20 sh
    

    Dokploy recommends explicitly setting ADVERTISE_ADDR when automatic detection fails or the server has multiple interfaces.

  54. The dashboard is unreachable

    Check services:

    docker service ls
    docker ps
    

    Check port 3000:

    ss -lntup | grep ':3000\b'
    

    Test locally:

    curl -v http://127.0.0.1:3000
    

    Check logs:

    docker service logs --tail 200 dokploy
    docker service logs --tail 200 dokploy-postgres
    docker logs --tail 200 dokploy-traefik
    

    Check firewall rules:

    ufw status verbose
    

    Check provider firewall rules as well.

    If the Dokploy service started before PostgreSQL and cannot resolve dokploy-postgres, restart it by scaling down and back up:

    docker service scale dokploy=0
    docker service scale dokploy=1
    

    This is the recovery procedure documented for a Dokploy/PostgreSQL startup race condition.

  55. Traefik is not routing applications

    Check Traefik:

    docker ps --filter name=dokploy-traefik
    docker logs --tail 200 dokploy-traefik
    

    Restart it:

    docker restart dokploy-traefik
    

    Inspect the Dokploy Traefik configuration:

    find /etc/dokploy/traefik -maxdepth 3 -type f -print
    

    Validate YAML files carefully before editing them.

    Common causes include:

    • Invalid YAML indentation
    • Incorrect router names
    • Incorrect internal container ports
    • A missing Docker network
    • DNS pointing to the wrong server
    • Port 80 or 443 blocked upstream
    • Invalid custom Traefik configuration

    Dokploy’s troubleshooting documentation recommends using the Traefik logs to identify the exact dynamic configuration file containing an error.

  56. Let’s Encrypt certificate issuance fails

    Check DNS:

    dig +short dokploy.example.com A
    

    Check HTTP access:

    curl -I http://dokploy.example.com
    

    Check port 80:

    ss -lntup | grep ':80\b'
    

    Review Traefik logs:

    docker logs --tail 300 dokploy-traefik
    

    Common causes include:

    • DNS has not propagated.
    • The record points to the wrong IP.
    • Port 80 is blocked.
    • An AAAA record points to a nonfunctional IPv6 address.
    • Cloudflare proxy settings interfere with initial validation.
    • The Let’s Encrypt rate limit has been reached.
    • The hostname contains a typographical error.

    Temporarily remove an incorrect AAAA record when IPv6 is not fully configured.

  57. Builds fail with DNS errors

    Symptoms may include:

    Could not resolve host: github.com
    

    Or:

    lookup ghcr.io: server misbehaving
    

    Test container DNS:

    See Also: How to Install Discourse on Ubuntu VPS

    docker run --rm alpine nslookup github.com
    

    Inspect Docker configuration:

    cat /etc/docker/daemon.json
    

    When the file does not exist, create:

    mkdir -p /etc/docker
    
    cat > /etc/docker/daemon.json <<'EOF'
    {
      "dns": [
        "1.1.1.1",
        "8.8.8.8"
      ]
    }
    EOF
    

    Validate:

    jq . /etc/docker/daemon.json
    

    Restart Docker during a maintenance window:

    systemctl restart docker
    

    Retest:

    docker run --rm alpine nslookup github.com
    

    When daemon.json already contains settings, merge the dns property instead of replacing the file. Dokploy documents this correction for Docker build environments that cannot use the VPS provider’s default resolver.

  58. Docker reports that all predefined address pools are exhausted

    The error may appear as:

    all predefined address pools have been fully subnetted
    

    Count Docker networks:

    docker network ls | wc -l
    

    Remove unused networks:

    docker network prune -f
    

    For a long-term fix, configure additional address pools in /etc/docker/daemon.json.

    Example:

    {
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "10m",
        "max-file": "5"
      },
      "default-address-pools": [
        {
          "base": "172.17.0.0/12",
          "size": 24
        },
        {
          "base": "10.100.0.0/16",
          "size": 24
        }
      ]
    }
    

    Validate:

    jq . /etc/docker/daemon.json
    

    Restart Docker during a maintenance window:

    systemctl restart docker
    

    Verify:

    docker info | grep -A 5 "Default Address Pools"
    

    Choose ranges that do not overlap with the VPS network, VPNs, or private infrastructure. Dokploy documents expanded Docker address pools as the permanent fix for exhausted network allocations.

  59. Services cannot communicate through Docker Swarm

    Check whether the IPVS kernel module is available:

    modprobe ip_vs
    lsmod | grep ip_vs
    

    Inspect kernel configuration:

    grep -E \
    'CONFIG_IP_VS|CONFIG_NETFILTER_XT_MATCH_IPVS|CONFIG_NETFILTER_XT_MARK' \
    /boot/config-$(uname -r)
    

    A standard Ubuntu VPS kernel should normally support the required Swarm networking features. Minimal or custom kernels may not.

    When IPVS is unavailable and the kernel cannot be changed, install using DNS round-robin mode:

    curl -fsSL https://dokploy.com/install.sh | \
        sudo ENDPOINT_MODE=dnsrr sh
    

    DNSRR has limitations, including different load-balancing behavior and restrictions on ingress-mode published ports. It should therefore be treated as a compatibility workaround rather than the default configuration.

  60. Disk space is exhausted

    Check usage:

    df -h
    df -ih
    docker system df
    

    Find large directories:

    du -xhd1 /var/lib/docker 2>/dev/null | sort -h
    du -xhd1 /etc/dokploy 2>/dev/null | sort -h
    

    Clean build cache:

    docker builder prune
    

    Remove unused images:

    docker image prune -a
    

    Remove unused containers and networks:

    docker system prune
    

    Use:

    docker system prune -a
    

    only after reviewing its impact.

    See Also: 🚀 Deploy ERPNext on Ubuntu VPS

    Do not delete Docker volumes manually from /var/lib/docker.

  61. Dokploy does not return after a reboot

    Check Docker:

    systemctl status docker --no-pager
    

    Start it if necessary:

    systemctl enable --now docker
    

    Check services:

    docker service ls
    docker service ps dokploy
    docker service ps dokploy-postgres
    

    Check logs:

    docker service logs --tail 200 dokploy
    docker service logs --tail 200 dokploy-postgres
    docker logs --tail 200 dokploy-traefik
    

    Restart Dokploy:

    docker service scale dokploy=0
    sleep 5
    docker service scale dokploy=1
    

    Restart Traefik:

    docker restart dokploy-traefik
    

    Avoid restarting the entire server repeatedly without first examining the logs.

Final production checklist

Before hosting production workloads, confirm all of the following:

[ ] Ubuntu is fully updated.
[ ] The server has at least 2 GB RAM and 30 GB storage.
[ ] Adequate production capacity has been allocated.
[ ] Swap is configured on small VPS instances.
[ ] Ports 80 and 443 are publicly reachable.
[ ] SSH is restricted to trusted sources where practical.
[ ] The Dokploy administrator account has been created.
[ ] Two-factor authentication is enabled.
[ ] The Dokploy panel uses a dedicated HTTPS hostname.
[ ] Direct IP:3000 access has been removed.
[ ] Port 3000 has been removed from external firewalls.
[ ] Root password login is disabled.
[ ] A non-root sudo administrator has been tested.
[ ] Automatic security updates are enabled.
[ ] Git credentials use least privilege.
[ ] Databases are not publicly exposed unnecessarily.
[ ] An S3-compatible backup destination is configured.
[ ] Dokploy configuration backups are scheduled.
[ ] Database backups are scheduled and tested.
[ ] Persistent application volumes are backed up.
[ ] A restoration test has been completed.
[ ] Disk, memory, Docker usage, and service health are monitored.
[ ] Docker log rotation is configured.
[ ] Update and rollback procedures are documented.

Useful command reference

Service status

docker service ls
docker ps
docker node ls

Dokploy logs

docker service logs -f dokploy

PostgreSQL logs

docker service logs -f dokploy-postgres

Traefik logs

docker logs -f dokploy-traefik

Resource usage

docker stats
docker system df
free -h
df -hT

Network inspection

ss -lntup
docker network ls
ip address
ip route

Restart Dokploy

docker service scale dokploy=0
docker service scale dokploy=1

Restart Traefik

docker restart dokploy-traefik

Update Dokploy

curl -fsSL https://dokploy.com/install.sh | sh -s update

Remove direct port 3000 access

docker service update \
    --publish-rm "published=3000,target=3000,mode=host" \
    dokploy

Launch 100% ssd ubuntu vps from $3. 19/mo!

Conclusion

You now know how to install Dokploy on Ubuntu VPS. Dokploy provides a convenient self-hosted deployment platform while retaining direct control over the underlying VPS, containers, applications, domains, and data.

A secure production deployment should not stop after running the installation script. The administrator should also:

See Also: 🚀 Deploy Virtualmin on AlmaLinux VPS (5 Minute Quick-Start Guide)

  • Configure a dedicated HTTPS hostname
  • Remove direct port 3000 exposure
  • Harden SSH access
  • Protect administrator accounts with multifactor authentication
  • Restrict database ports
  • Configure off-server backups
  • Monitor storage and Docker resource consumption
  • Review release notes and back up before upgrades

Once these controls are in place, the Ubuntu VPS is ready to host applications, databases, Docker Compose stacks, and automated Git-based deployments through Dokploy.

Avatar of editorial staff

Editorial Staff

Rad Web Hosting is a leading provider of web hosting, Cloud VPS, and Dedicated Servers in Dallas, TX.

Leave a Reply

lg