Nginx SSL Setup and Blog Automation Pipeline Fixes
Today I tackled two related issues that were blocking my automated blog post workflow: SSL certificate errors when accessing the automation dashboard, and the need to update my capture script to properly categorize entries in the blog database.
Initial State
The automation dashboard was running on port 3000, exposed directly to the internet, which meant browsers were throwing security warnings. The vibe-coding-capture script was also just dumping entries into a general "posts" table without proper categorization. Not ideal for organizing this series.
Setting Up Nginx Reverse Proxy
Started by installing nginx on the production server:
sudo apt install nginx
Created a new site configuration at /etc/nginx/sites-available/dashboard:
server {
listen 443 ssl;
server_name dashboard.vibecoding.com;
ssl_certificate /etc/letsencrypt/live/dashboard.vibecoding.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dashboard.vibecoding.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Hit a snag when certbot failed to validate the domain. Realized I needed to temporarily allow HTTP access for the challenge. Added this block to handle the certification process:
server {
listen 80;
server_name dashboard.vibecoding.com;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
}
After getting the cert, enabled the site:
sudo ln -s /etc/nginx/sites-available/dashboard /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Updating the Capture Script
The capture script needed modification to properly categorize these entries. Updated the database schema first:
ALTER TABLE posts ADD COLUMN category VARCHAR(50);
CREATE INDEX idx_category ON posts(category);
Modified /scripts/vibe-coding-capture.js to include the new category:
const saveEntry = async (content) => {
const result = await db.query(
'INSERT INTO posts (content, category, created_at) VALUES ($1, $2, NOW())',
[content, 'vibe-coding']
);
return result.rows[0];
}
Had to debug an issue where the database connection was timing out. Added connection pooling:
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});
Final State
The dashboard is now properly secured behind SSL at https://dashboard.vibecoding.com. Blog entries are being correctly categorized in the database, making it easier to manage the series separately from other content.
Still need to:
1. Set up automated cert renewal
2. Add monitoring for the nginx service
3. Create a backup system for the SSL certificates
4. Add validation for the post category field
The basic infrastructure is working though, and I can focus on content creation rather than fighting with security warnings. Learned quite a bit about nginx configuration and the importance of proper connection pooling for database reliability.