On your server, create a directory for your application:
# Create application directory
sudo mkdir -p /opt/gooneral-wheelchair
sudo chown $USER:$USER /opt/gooneral-wheelchair
cd /opt/gooneral-wheelchair
Upload these files to your server:
/opt/gooneral-wheelchair/
├── dist/ # Built frontend files
├── backend/ # Backend application
│ ├── server.js
│ ├── start-production.js
│ ├── package.json
│ ├── .env.production # Configure this!
│ ├── auth.js
│ ├── themes.js
│ └── node_modules/ # Install dependencies
├── public/
│ └── posts/ # Your blog posts
├── Caddyfile # Caddy configuration
└── DEPLOYMENT.md # This file
Edit /opt/gooneral-wheelchair/backend/.env.production:
# REQUIRED: Change these values!
NODE_ENV=production
PORT=3001
SESSION_SECRET=your-super-secret-session-key-generate-a-strong-one
FRONTEND_URL=https://yourdomain.com
# Optional: Customize paths if needed
POSTS_DIR=../public/posts
THEMES_FILE=./themes.json
SESSIONS_DIR=./sessions
# Security settings
COOKIE_SECURE=true
COOKIE_SAME_SITE=strict
⚠️ IMPORTANT: Generate a strong session secret:
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
cd /opt/gooneral-wheelchair/backend
npm install --production
mkdir -p sessions
mkdir -p ../public/posts
# Create a system user for the application
sudo useradd --system --shell /bin/false --home /opt/gooneral-wheelchair gooneral
# Change ownership
sudo chown -R gooneral:gooneral /opt/gooneral-wheelchair
# Make start script executable
sudo chmod +x /opt/gooneral-wheelchair/backend/start-production.js
Create /etc/systemd/system/gooneral-wheelchair.service:
[Unit]
Description=Gooneral Wheelchair CMS Backend
After=network.target
[Service]
Type=simple
User=gooneral
WorkingDirectory=/opt/gooneral-wheelchair/backend
Environment=NODE_ENV=production
ExecStart=/usr/bin/node start-production.js
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=gooneral-wheelchair
[Install]
WantedBy=multi-user.target
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable gooneral-wheelchair
sudo systemctl start gooneral-wheelchair
sudo systemctl status gooneral-wheelchair
Update the Caddyfile with your domain:
# Replace 'yourdomain.com' with your actual domain
yourdomain.com {
# ... rest of configuration
}
Copy Caddyfile to Caddy's configuration directory:
sudo cp /opt/gooneral-wheelchair/Caddyfile /etc/caddy/Caddyfile
Test and reload Caddy:
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
SSH into your server and create an admin user:
cd /opt/gooneral-wheelchair/backend
node -e "
const bcrypt = require('bcryptjs');
const fs = require('fs');
const path = require('path');
const username = 'admin';
const password = 'your-secure-password'; // Change this!
const hashedPassword = bcrypt.hashSync(password, 10);
const usersFile = path.join(__dirname, 'users.json');
const users = [
{
id: 1,
username: username,
password: hashedPassword,
role: 'admin'
}
];
fs.writeFileSync(usersFile, JSON.stringify(users, null, 2));
console.log('Admin user created:', username);
"
# Backend logs
sudo journalctl -u gooneral-wheelchair -f
# Caddy logs
sudo journalctl -u caddy -f
# Application logs (if configured)
sudo tail -f /var/log/caddy/gooneral-wheelchair.log
Upload markdown files to /opt/gooneral-wheelchair/public/posts/
dist/ directoryRestart services:
sudo systemctl restart gooneral-wheelchair
sudo systemctl reload caddy
sudo systemctl status gooneral-wheelchair
sudo journalctl -u gooneral-wheelchair -n 50
dist/ directory contains built filesRegular backups should include:
/opt/gooneral-wheelchair/public/posts/ (your blog posts)/opt/gooneral-wheelchair/backend/users.json (user accounts)/opt/gooneral-wheelchair/backend/themes.json (theme settings)/opt/gooneral-wheelchair/backend/sessions/ (active sessions - optional)