βοΈ Nginx Setup & Subdomain Hosting
Learn how to install Nginx, serve static sites, and host multiple apps on one server using subdomains like second-brain.dkbrainhub.com.
π€ What Is Nginx?β
Nginx (pronounced "engine-x") is a web server that receives HTTP requests and routes them to the right place.
π¨ Analogy: Your cloud server is a hotel building. Nginx is the front desk receptionist. When a guest arrives asking for
second-brain.dkbrainhub.com, the receptionist checks which room (app/folder) to send them to.
One Nginx instance can serve many different sites and apps on the same server β each identified by its hostname/subdomain.
π¦ Step 1 β Install Nginxβ
SSH into your server:
ssh root@YOUR_SERVER_IP
Install Nginx on Ubuntu/Debian:
apt update
apt install nginx -y
# Start and enable on boot
systemctl start nginx
systemctl enable nginx
# Verify it's running
systemctl status nginx
Open your browser and visit http://YOUR_SERVER_IP β you should see the Nginx default welcome page.
π Step 2 β Understand the Key Files & Foldersβ
/etc/nginx/
βββ nginx.conf # Main config (don't touch unless you know what you're doing)
βββ sites-available/ # All site config files live here (enabled or not)
β βββ default # Default site (disable this)
β βββ second-brain # Your app's config file
βββ sites-enabled/ # Symlinks to active configs in sites-available
βββ second-brain -> ../sites-available/second-brain
/var/www/ # Default web root (store your apps here)
βββ second-brain/ # Static files for second-brain.dkbrainhub.com
βββ index.html
π Key idea: Nginx reads only files in
sites-enabled/. To activate a config, you symlink it fromsites-available/tosites-enabled/.
π Step 3 β Create Your First Site Configβ
3a β Create the web root folderβ
mkdir -p /var/www/second-brain
# Add a test page
echo '<h1>Hello from second-brain.dkbrainhub.com!</h1>' > /var/www/second-brain/index.html
# Set ownership so Nginx can read the files
chown -R www-data:www-data /var/www/second-brain
chmod -R 755 /var/www/second-brain
3b β Create the Nginx config fileβ
nano /etc/nginx/sites-available/second-brain
Paste this configuration:
server {
listen 80;
listen [::]:80;
server_name second-brain.dkbrainhub.com;
root /var/www/second-brain;
index index.html;
# Gzip compression β speeds up page loads
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
# Cache static assets for 1 year (images, fonts, JS, CSS)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Handle client-side routing (React, Vue, Docusaurus SPAs)
location / {
try_files $uri $uri/ /index.html;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
server_tokens off; # Don't reveal Nginx version in error responses
error_page 404 /404.html;
}
3c β Enable the site and reload Nginxβ
# Create a symlink to enable the site
ln -s /etc/nginx/sites-available/second-brain /etc/nginx/sites-enabled/
# Disable the default placeholder site
rm -f /etc/nginx/sites-enabled/default
# Test your configuration for syntax errors
nginx -t
# Reload Nginx (zero-downtime β no restart needed)
systemctl reload nginx
Visit http://second-brain.dkbrainhub.com β your site is live! π
ποΈ Step 4 β Host Multiple Apps on One Serverβ
This is where subdomains shine. Each app gets its own config file and subdomain.
π’ Analogy: One apartment building, multiple tenants. Each tenant (app) has their own front door (subdomain) and room (folder).
Adding a second app: api.dkbrainhub.comβ
# Create folder and add content
mkdir -p /var/www/api
echo '{"status": "ok"}' > /var/www/api/index.html
chown -R www-data:www-data /var/www/api
# Create Nginx config
cat > /etc/nginx/sites-available/api << 'EOF'
server {
listen 80;
listen [::]:80;
server_name api.dkbrainhub.com;
root /var/www/api;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
EOF
# Enable it
ln -s /etc/nginx/sites-available/api /etc/nginx/sites-enabled/
# Reload
nginx -t && systemctl reload nginx
Adding a third app: portfolio.dkbrainhub.comβ
mkdir -p /var/www/portfolio
# ... copy your app files here ...
chown -R www-data:www-data /var/www/portfolio
cat > /etc/nginx/sites-available/portfolio << 'EOF'
server {
listen 80;
listen [::]:80;
server_name portfolio.dkbrainhub.com;
root /var/www/portfolio;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
EOF
ln -s /etc/nginx/sites-available/portfolio /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
What it looks like when you have multiple appsβ
Server IP: 152.42.157.67
second-brain.dkbrainhub.com β /var/www/second-brain/ (Docusaurus docs site)
api.dkbrainhub.com β /var/www/api/ (REST API or JSON files)
portfolio.dkbrainhub.com β /var/www/portfolio/ (Personal portfolio)
blog.dkbrainhub.com β /var/www/blog/ (Static blog)
All served by the same single server and same Nginx β no extra cost!
π Step 5 β Add HTTPS with Let's Encrypt (Free SSL)β
Once your DNS is pointing to your server, get a free SSL certificate:
# Install Certbot
apt install certbot python3-certbot-nginx -y
# Get certificate for one subdomain
certbot --nginx -d second-brain.dkbrainhub.com
# Or get certificates for multiple subdomains at once
certbot --nginx \
-d second-brain.dkbrainhub.com \
-d api.dkbrainhub.com \
-d portfolio.dkbrainhub.com
# Certbot auto-renews every 90 days. Test renewal:
certbot renew --dry-run
After running Certbot, your Nginx config is automatically updated to redirect HTTP β HTTPS.
π Proxy Pass β Running Node.js / Python Appsβ
If your app runs on a local port (e.g., Node.js on port 3000), use Nginx as a reverse proxy:
server {
listen 80;
server_name app.dkbrainhub.com;
location / {
proxy_pass http://localhost:3000; # Forward to your local app
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;
}
}
π Analogy: Nginx acts as a power strip β the outside world plugs into Nginx (port 80/443), and Nginx plugs into whichever internal socket (port) your app is running on.
π§° Useful Nginx Commandsβ
nginx -t # Test config for syntax errors
systemctl reload nginx # Reload config (zero downtime)
systemctl restart nginx # Full restart
systemctl status nginx # Check if running
nginx -v # Show version
# View live access logs
tail -f /var/log/nginx/access.log
# View live error logs
tail -f /var/log/nginx/error.log
# List all enabled sites
ls -la /etc/nginx/sites-enabled/
πΊοΈ Full Architecture Overviewβ
Internet
β
βΌ
Your Domain (dkbrainhub.com)
β DNS A record β 152.42.157.67
βΌ
DigitalOcean Droplet (152.42.157.67)
β Port 80 (HTTP) / 443 (HTTPS)
βΌ
Nginx (reverse proxy / web server)
βββ second-brain.dkbrainhub.com β /var/www/second-brain/
βββ api.dkbrainhub.com β localhost:3000 (Node.js)
βββ portfolio.dkbrainhub.com β /var/www/portfolio/
π Resourcesβ
| Resource | Link |
|---|---|
| Nginx Docs | nginx.org/en/docs |
| DigitalOcean Nginx Guide | How To Install Nginx on Ubuntu |
| Certbot (Let's Encrypt) | certbot.eff.org |
| Nginx Config Generator | nginxconfig.io |
Last updated: February 2026