Skip to content

Instantly share code, notes, and snippets.

@voscarmv
Last active October 3, 2025 21:23
Show Gist options
  • Select an option

  • Save voscarmv/280a76521c3bb101b4b7b72b87331b62 to your computer and use it in GitHub Desktop.

Select an option

Save voscarmv/280a76521c3bb101b4b7b72b87331b62 to your computer and use it in GitHub Desktop.
Self-host vite in Raspberry Pi 4 in 2025

Self-hosting Vite apps

As Vercel falls from grace, hobbyists and others look for otions to circumvent it.

Here's a skeletal low-cost self-hosting option for everyone.

Hardware

  1. Raspberry Pi 4
  2. NAT-capable modem/router connected to the internet
  3. One other device, PC, mobile, laptop, etc, connected to the same modem.

Software

  1. Ubuntu 24.04 Server
  2. Raspberry Pi Imager v1.9.3
  3. nvm
  4. node
  5. vite
  6. nginx certbot python3-certbot-nginx
  7. tmux

External services

  1. duckdns.org
  2. namecheap or some other domain host

HOW-TO

  1. Burn Ubuntu 24.04 server on an SD card (64GB+) with the Raspberry Pi Imager. Set up SSH in the installer.
  2. Insert the SD card in the RaspPi4, connect it's ethernet cable to your modem/router.
  3. Set up static IP for your RaspPi4 device in the modem/router config (this is model-specific, for TELMEX watch https://youtu.be/NdHter6vAV8?si=RfPO2VGNQ7hTcx2Z)
  4. Forward ports 22, 80 and 443 with protocl TCP to your RaspPi in the modem config.
  5. Figure out your public ip from another PC connected to the same modem with curl ifconfig.me
  6. Set up a DDNS address with duckdns.org, using your public IP. E.g. yoursubdom.duckdns.org
  7. You may log into your rasppi remotely from an ssh client with ssh username@yourpublicip or ssh username@yoursubdom.duckdns.org, enter your password to login.
  8. Install duckdns.org on your rasppi crontab -e, follow https://www.duckdns.org/install.jsp
  9. Once in, set up node and vite, and create a vite react project with something like npx create-vite@latest my-react-app
  10. Your vite.config.ts file should like like this:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    host: '0.0.0.0',   // allow all network interfaces
    port: 5173,
    strictPort: true,   // optional: fail if port is in use
    cors: true,          // optional: allow cross-origin
    allowedHosts: [
      'yourdomain.com',
      'www.yourdomain.com',
      'yoursubdom.duckdns.org'
    ]
  }
})
  1. Set up your new domain name on namecheap or any other domain name host. E.g. yourdomain.com
  2. Set up your namecheap/etc DNS records as. EDIT: This will break DNS for some VPNs, instead use step 14 in this gist.
CNAME Record  @ yoursubdom.duckdns.org. Automatic
CNAME Record  www youtsubdom.duckdns.org. Automatic
  1. Note that if you are already paying for namecheap, you can bypas duckdns.org altogether by adding this script to your crontab insetad of duck.sh, follow https://www.namecheap.com/support/knowledgebase/article.aspx/29/11/how-to-dynamically-update-the-hosts-ip-with-an-https-request/ You may still keep yoursubdom.duckdns.org as a free option if you need it:
#!/bin/bash
# Update Namecheap DDNS for yourdomain.com

DOMAIN="yourdomain.com"
PASSWORD="102f110b52524a2aaf7cbae6f836be87"   # from Namecheap's Advanced DNS tab

# Update root (@)
curl -s "https://dynamicdns.park-your-domain.com/update?host=@&domain=${DOMAIN}&password=${PASSWORD}" 2>&1 >> ~/namecheap/ddns.log

# Update www
curl -s "https://dynamicdns.park-your-domain.com/update?host=www&domain=${DOMAIN}&password=${PASSWORD}" 2>&1 >> ~/namecheap/ddns.log

# Update wildcard (*)
#curl -s "https://dynamicdns.park-your-domain.com/update?host=*&domain=${DOMAIN}&password=${PASSWORD}" >/dev/null
  1. Configure nginx as such:
#!/bin/bash

sudo apt update
sudo apt install nginx -y

cat << EOF > /etc/nginx/sites-available/vite
server {
    listen 80;
    server_name yordomain.duckdns.org;  # replace with your domain

    location / {
        proxy_pass http://127.0.0.1:5173;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
EOF

sudo ln -s /etc/nginx/sites-available/vite /etc/nginx/sites-enabled/
sudo nginx -t   # test config
sudo systemctl reload nginx

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.duckdns.org

cat << EOF > /etc/nginx/sites-available/yourdomain.com
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:5173;   # or your app port
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_cache_bypass $http_upgrade;
    }
}
EOF

sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/

sudo nginx -t
sudo systemctl reload nginx

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
  1. Set up sudo apt install tmux and run tmux new-session -s myvite
  2. Once in tmux run npx vite --host inside your vite project dir.
  3. Detach from the tmux session with Ctrl+b and then d
  4. You may now log out and the vite server should be running and displaying when you visit www.mydomain.com
  5. If you want to close vite reattach tmux with tmux attach-session -t myvite and end it.

Extra SSH security

For extra security using ssh, set up a key by

  1. Running ssh-keygen -t ed25519 -C "your_email@example.com" from your client machine
  2. Then copy it to your RaspPi4 server with ssh-copy-id username@remote_host
  3. You can then test it by logging in with ssh username@remote_host, it should not ask for password this time around.
  4. Once in, disable password logins with sudo nano /etc/ssh/sshd_config and setting PasswordAuthentication no
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment