6.5 KiB
Dokploy VM Bootstrap (Verbose Noob Walkthrough)
Purpose: set up a fresh Ubuntu VM (on Proxmox) with Docker and Dokploy for Fiddy deployment, using a copy-paste sequence with verification at each step.
Scope:
- This runbook is for a new Ubuntu VM with SSH enabled.
- It assumes Dokploy will be on its own VM.
- It does not install app containers yet; it prepares the Dokploy control plane.
Important reality:
- This Codex environment cannot directly SSH into your VM or use your credentials.
- You run the commands below on your VM and paste outputs back; I verify and guide next actions.
0) What to prepare first
Collect these values before you start:
VM_IP= your Ubuntu VM LAN IP (example:192.168.7.146)SSH_USER= ssh username (example:nico)SSH_PORT= usually22TZ= timezone (example:America/Los_Angeles)
From your laptop/desktop, connect:
ssh <SSH_USER>@<VM_IP>
If this fails, fix SSH access first.
1) Baseline OS update and required tools
Run on VM:
sudo apt update
sudo apt -y upgrade
sudo apt -y install ca-certificates curl gnupg lsb-release ufw fail2ban jq
Set timezone:
sudo timedatectl set-timezone <TZ>
timedatectl
Verification:
timedatectlshows your timezone.aptcommands exit without errors.
2) Install Docker Engine (official repo)
Run on VM:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Enable/start Docker:
sudo systemctl enable docker
sudo systemctl start docker
sudo systemctl status docker --no-pager
Optional (run docker without sudo for your user):
sudo usermod -aG docker $USER
newgrp docker
docker ps
Verification:
docker psworks.docker compose versionreturns version.
3) Host firewall baseline (before Dokploy)
Goal: allow SSH + HTTP/HTTPS, deny others.
Run on VM:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3000/tcp
sudo ufw --force enable
sudo ufw status verbose
Notes:
- Dokploy UI is typically on
3000for first setup. - After reverse proxy is in place, you can restrict
3000to LAN/VPN.
4) Install Dokploy
Run on VM:
curl -sSL https://dokploy.com/install.sh | sh
Check containers:
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Open Dokploy UI from your browser:
http://<VM_IP>:3000
Create initial admin account.
Verification:
- Dokploy UI loads.
- You can sign in.
5) Immediate post-install hardening
5.1 Keep SSH secure
Edit SSH daemon config:
sudo nano /etc/ssh/sshd_config
Recommended minimum:
PermitRootLogin noPasswordAuthentication no(only if SSH key login already works)PubkeyAuthentication yes
Apply:
sudo systemctl restart ssh
5.2 Fail2ban basic protection
Create local jail file:
sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[sshd]
enabled = true
maxretry = 5
findtime = 10m
bantime = 1h
EOF
Apply:
sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status
6) Dokploy first configuration (UI)
In Dokploy:
- Create project:
fiddy - Add registry credentials:
- Host:
git.nicosaya.com - Username: same as Gitea registry user
- Password/token: registry token
- Host:
- Create app:
fiddy-web- Type: Docker image
- Image:
git.nicosaya.com/nalalangan/fiddy/web:main - Internal port:
3000 - Exposed host port:
3010 - Health path:
/api/health/ready
- Create app:
fiddy-scheduler- Type: Docker image
- Image:
git.nicosaya.com/nalalangan/fiddy/scheduler:main - No public port
- Enable Auto Deploy for both apps and copy both webhook URLs.
7) Gitea repo secrets required after Dokploy apps exist
In Gitea repo Settings -> Secrets -> Actions, set:
REGISTRY_USERREGISTRY_PASSDOKPLOY_DEPLOY_HOOK(from web app in Dokploy)DOKPLOY_SCHEDULER_DEPLOY_HOOK(from scheduler app in Dokploy)DOKPLOY_HEALTHCHECK_URL- final:
https://fiddy.nicosaya.com/api/health/ready - temporary allowed:
http://<VM_IP>:3010/api/health/ready
- final:
8) First deployment flow
From your local repo:
git commit --allow-empty -m "chore: trigger dokploy first deploy"
git push origin main
Expected .gitea/workflows/deploy-dokploy.yml behavior:
- build/push web image
- build/push scheduler image
- call Dokploy web hook
- call Dokploy scheduler hook
- wait for ready health check
Verification:
- Gitea workflow is green.
- Dokploy app logs show successful pull/start.
- Health URLs respond 200.
9) Troubleshooting quick map
- Workflow fails on registry login:
- re-check
REGISTRY_USERandREGISTRY_PASS.
- re-check
- Dokploy hook step fails:
- re-check hook URL secret values.
- Health check fails:
- verify app env vars (
DATABASE_URLetc). - verify upstream route and Nginx Proxy Manager mapping.
- verify DB reachable from VM/network.
- verify app env vars (
10) Execution log template (fill as you go)
Copy/paste this section and fill values:
# Dokploy VM Setup Execution Log
Date:
Operator:
VM IP:
Ubuntu version (`lsb_release -a`):
## Step 1 - OS prep
- Result:
- Notes:
## Step 2 - Docker install
- `docker --version`:
- `docker compose version`:
- Result:
## Step 3 - Firewall
- `ufw status verbose`:
- Result:
## Step 4 - Dokploy install
- Dokploy UI reachable: yes/no
- Result:
## Step 5 - Hardening
- SSH hardened: yes/no
- fail2ban status:
- Result:
## Step 6 - Dokploy apps
- Web app created: yes/no
- Scheduler app created: yes/no
- Hooks copied: yes/no
## Step 7 - Gitea secrets
- Secrets completed: yes/no
## Step 8 - First deploy
- Workflow URL:
- Result:
- Health checks:
## Issues encountered
-
## Final status
- Ready for NPM/domain wiring: yes/no
11) Safety notes
- Do not share raw credentials/tokens in chat or docs.
- Prefer SSH keys over passwords.
- Keep Dokploy host updated weekly (
sudo apt update && sudo apt -y upgrade). - Snapshot VM before major config changes.