Back to Blog
Tutorial4 min read

Deploy Your Side Project with a Custom Domain in Under 5 Minutes

DT
DomainDock Team
Engineering · May 20, 2026

You've built the thing. It works locally. Now you want it on the internet with a real URL and HTTPS, not http://1.2.3.4:3000 and not a 40-character deployment platform URL.

This tutorial walks you through the fastest path: a VPS, Docker, and DomainDock. Everything from the blank server to yourproject.digitalweb.host in under 5 minutes.

What You'll Need

  • A VPS with a public IP address (any provider works: Hetzner, DigitalOcean, Vultr, etc.)
  • Docker installed on the VPS
  • A DomainDock account (free, no credit card)

That's it. No domain registrar. No Cloudflare account. No SSL configuration on your end.

Minute 1: Start Your App on the VPS

SSH into your VPS and get your app running. For this tutorial, we'll use a Node.js app as an example. The steps are identical for any language or framework.

If your app is already running, skip to Minute 2.

Option A: Docker (recommended)

docker run -d \
  --name myapp \
  --restart unless-stopped \
  -p 127.0.0.1:3000:3000 \
  your-docker-image:latest

Binding to 127.0.0.1:3000 exposes the port only on loopback. Traefik (added in the next step) will proxy traffic to it. Your app is never directly exposed on port 3000 to the internet.

Option B: Direct process

node server.js &
# or
pm2 start server.js --name myapp

Make sure the app listens on localhost:3000 (or whatever port you choose).

Verify it's responding:

curl http://localhost:3000

If you get HTML or JSON back, you're good.

Minute 2: Start Traefik

Traefik is the reverse proxy that handles HTTPS and domain routing. Run it with Docker:

mkdir -p ~/traefik/letsencrypt ~/traefik/dynamic
touch ~/traefik/letsencrypt/acme.json
chmod 600 ~/traefik/letsencrypt/acme.json

Create ~/traefik/traefik.yml:

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"

certificatesResolvers:
  letsencrypt:
    acme:
      email: you@example.com
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

providers:
  file:
    directory: /etc/traefik/dynamic
    watch: true

Create ~/traefik/docker-compose.yml:

services:
  traefik:
    image: traefik:v3.3
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./traefik.yml:/etc/traefik/traefik.yml:ro
      - ./dynamic:/etc/traefik/dynamic:ro
      - ./letsencrypt:/letsencrypt
    restart: unless-stopped
    network_mode: host

Using network_mode: host lets Traefik reach processes on 127.0.0.1:3000 without any extra Docker networking configuration.

Start Traefik:

cd ~/traefik && docker compose up -d

Traefik is now running. It's watching port 80 and 443, and watching the dynamic directory for routing rules.

Minute 3: Claim Your Domain on DomainDock

  1. Go to DomainDock and create a free account
  2. Click New project and give it a name
  3. Click Add domain
  4. Enter your domain prefix (this becomes yourprefix.digitalweb.host)
  5. Enter your VPS IP address
  6. Enter port 3000 (or whatever port your app uses)
  7. Click Create

DomainDock creates a Cloudflare DNS A record pointing yourprefix.digitalweb.host to your VPS IP.

Within 30–60 seconds, the DNS is globally propagated.

Minute 4: Write the Traefik Routing Rule

Create ~/traefik/dynamic/myapp.yml on your VPS:

http:
  routers:
    myapp:
      rule: "Host(`yourprefix.digitalweb.host`)"
      service: myapp-svc
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt

  services:
    myapp-svc:
      loadBalancer:
        servers:
          - url: "http://127.0.0.1:3000"

Replace yourprefix with the prefix you chose in DomainDock.

Traefik detects the new file immediately (no restart needed) and:

  1. Starts routing requests for yourprefix.digitalweb.host to 127.0.0.1:3000
  2. Requests a Let's Encrypt certificate for yourprefix.digitalweb.host
  3. Stores the certificate and starts serving HTTPS

Minute 5: Test It

Open your browser and navigate to https://yourprefix.digitalweb.host.

If everything is correct, you'll see your app with a valid HTTPS certificate in the browser.

If it's not working yet, wait 30 more seconds. Certificate issuance occasionally takes a moment on the first request.

Troubleshooting

502 Bad Gateway

Traefik is routing but can't reach your app. Check that your app is actually running: curl http://localhost:3000. If it responds, verify the port in your routing rule matches.

404 from Traefik

The routing rule isn't being picked up. Check that the file is in ~/traefik/dynamic/ and the YAML syntax is valid: docker exec traefik traefik healthcheck.

Certificate not issued

Let's Encrypt needs port 80 to be reachable from the internet for the HTTP-01 challenge. Check your VPS firewall: ufw allow 80 and ufw allow 443.

DNS not resolving

Wait a bit longer, or check with dig yourprefix.digitalweb.host A from your local machine. If it returns your VPS IP, DNS is correct and the issue is elsewhere.

What You Just Set Up

In under 5 minutes, you deployed an app with:

  • A clean custom domain: yourprefix.digitalweb.host, globally routable
  • Automatic HTTPS: Let's Encrypt certificate, auto-renewed by Traefik
  • HTTP to HTTPS redirect: anyone who visits over HTTP is redirected automatically
  • Health monitoring: DomainDock is already running health checks on your domain
  • Branded error page: if your app goes down, visitors see a clean status page instead of a browser error

Scaling Up

This setup handles one app. To add more:

  1. Start another app on a different port (e.g., 127.0.0.1:4000)
  2. Create another domain in DomainDock with the same VPS IP, port 4000
  3. Add ~/traefik/dynamic/anotherapp.yml with the corresponding routing rule

The same Traefik instance handles all of it. No restarts. No new certificates. Each domain gets its own Let's Encrypt cert automatically.


Your project deserves a real address. Create your free domain on DomainDock.

deploymentside projecttutorialVPSDNSSSL
Newsletter

Developer infrastructure, in your inbox

DNS patterns, SSL guides, routing tips, and DomainDock updates. Monthly, no fluff.

No spam. Unsubscribe any time.