summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-20 15:39:53 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-20 15:39:53 -1000
commit845dda44574fb69cf7af3c2b4df9021451db8b11 (patch)
tree198a013de085c6febe8bb911508be9f45191d4a2
parentcb592195189685471f054578390b5a6f3440187e (diff)
Add VPS deployment artifacts and documentation
Include systemd service file, Apache reverse proxy config, and comprehensive deployment guide for Linux VPS setup. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
-rw-r--r--SESSION_STATE.md22
-rw-r--r--deployment/apache.conf45
-rw-r--r--deployment/task-dashboard.service25
-rw-r--r--docs/deployment.md177
4 files changed, 256 insertions, 13 deletions
diff --git a/SESSION_STATE.md b/SESSION_STATE.md
index fe2d480..6c7164c 100644
--- a/SESSION_STATE.md
+++ b/SESSION_STATE.md
@@ -1,20 +1,16 @@
# Session State
-**Active Task:** None (Authentication Complete)
+**Active Task:** None
**Completed Tasks:**
-- **Obsidian Removal:** Completed and verified.
-- **Authentication:**
- - `internal/auth` implementation (Service, Handlers, Middleware) ✅
- - Database migration `migrations/004_add_auth.sql` ✅
- - Login template `web/templates/login.html` ✅
- - Wired up in `cmd/dashboard/main.go` ✅
- - Unit tests (`auth_test.go`, `handlers_test.go`) ✅
- - CSRF protection middleware ✅
- - Acceptance tests updated ✅
- - All tests passing ✅
+- **Obsidian Removal:** ✅
+- **Authentication:** ✅
+- **VPS Deployment Preparation:** ✅
+ - Added `STATIC_DIR` env var support
+ - Created `deployment/task-dashboard.service` (systemd)
+ - Created `deployment/apache.conf` (reverse proxy)
+ - Created `docs/deployment.md` (full deployment guide)
**Current Status:** [APPROVED]
-**Next Task Candidates:**
-1. `issues/task_003_deployment_prep.md` - VPS Deployment Preparation
+**All Planned Tasks Complete**
diff --git a/deployment/apache.conf b/deployment/apache.conf
new file mode 100644
index 0000000..3942bf6
--- /dev/null
+++ b/deployment/apache.conf
@@ -0,0 +1,45 @@
+<VirtualHost *:80>
+ ServerName ${FQDN}
+
+ # Redirect HTTP to HTTPS
+ RewriteEngine On
+ RewriteCond %{HTTPS} off
+ RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
+</VirtualHost>
+
+<VirtualHost *:443>
+ ServerName ${FQDN}
+
+ # SSL Configuration (adjust paths as needed)
+ SSLEngine on
+ SSLCertificateFile /etc/letsencrypt/live/${FQDN}/fullchain.pem
+ SSLCertificateKeyFile /etc/letsencrypt/live/${FQDN}/privkey.pem
+
+ # Document root for static files served directly by Apache
+ DocumentRoot /site/${FQDN}/public
+
+ # Serve static files directly via Apache (bypasses Go app)
+ <Directory /site/${FQDN}/public>
+ Options -Indexes +FollowSymLinks
+ AllowOverride None
+ Require all granted
+
+ # Cache static assets
+ <FilesMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$">
+ Header set Cache-Control "max-age=31536000, public"
+ </FilesMatch>
+ </Directory>
+
+ # Static files served by Apache
+ Alias /static /site/${FQDN}/public
+
+ # Proxy all other requests to Go application
+ ProxyPreserveHost On
+ ProxyPass /static !
+ ProxyPass / http://127.0.0.1:8080/
+ ProxyPassReverse / http://127.0.0.1:8080/
+
+ # Logging
+ ErrorLog ${APACHE_LOG_DIR}/${FQDN}-error.log
+ CustomLog ${APACHE_LOG_DIR}/${FQDN}-access.log combined
+</VirtualHost>
diff --git a/deployment/task-dashboard.service b/deployment/task-dashboard.service
new file mode 100644
index 0000000..7afd9d9
--- /dev/null
+++ b/deployment/task-dashboard.service
@@ -0,0 +1,25 @@
+[Unit]
+Description=Task Dashboard - Personal task aggregation dashboard
+After=network.target
+
+[Service]
+Type=simple
+User=www-data
+Group=www-data
+WorkingDirectory=/site/%i
+ExecStart=/site/%i/app
+Restart=always
+RestartSec=5
+
+# Environment file for secrets and configuration
+EnvironmentFile=/site/%i/.env
+
+# Security hardening
+NoNewPrivileges=true
+ProtectSystem=strict
+ProtectHome=true
+ReadWritePaths=/site/%i/data
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
diff --git a/docs/deployment.md b/docs/deployment.md
new file mode 100644
index 0000000..89d2bc6
--- /dev/null
+++ b/docs/deployment.md
@@ -0,0 +1,177 @@
+# Deployment Guide
+
+Deploy Task Dashboard to a VPS using Apache2 as reverse proxy and Systemd for process management.
+
+## Prerequisites
+
+- Linux VPS (Ubuntu/Debian recommended)
+- Apache2 with `mod_proxy`, `mod_proxy_http`, `mod_ssl`, `mod_headers`, `mod_rewrite`
+- Go 1.21+ (for building)
+- SSL certificate (Let's Encrypt recommended)
+
+## Directory Structure
+
+```
+/site/{fqdn}/
+├── app # Compiled binary
+├── data/
+│ └── dashboard.db # SQLite database
+├── public/ # Static assets (served by Apache)
+│ ├── css/
+│ └── js/
+├── templates/ # HTML templates
+└── .env # Environment configuration
+```
+
+## Build
+
+On your development machine or CI:
+
+```bash
+# Build for Linux
+GOOS=linux GOARCH=amd64 go build -o app cmd/dashboard/main.go
+```
+
+## Setup
+
+### 1. Create Directory Structure
+
+```bash
+export FQDN="your-domain.com"
+sudo mkdir -p /site/${FQDN}/{data,public,templates}
+sudo chown -R www-data:www-data /site/${FQDN}
+```
+
+### 2. Deploy Files
+
+```bash
+# Copy binary
+sudo cp app /site/${FQDN}/
+
+# Copy static assets
+sudo cp -r web/static/* /site/${FQDN}/public/
+
+# Copy templates
+sudo cp -r web/templates/* /site/${FQDN}/templates/
+
+# Set permissions
+sudo chmod +x /site/${FQDN}/app
+```
+
+### 3. Configure Environment
+
+Create `/site/${FQDN}/.env`:
+
+```bash
+# Required API Keys
+TODOIST_API_KEY=your_todoist_api_key
+TRELLO_API_KEY=your_trello_api_key
+TRELLO_TOKEN=your_trello_token
+
+# Optional
+PLANTOEAT_API_KEY=your_plantoeat_api_key
+
+# Paths (adjust for deployment structure)
+DATABASE_PATH=/site/${FQDN}/data/dashboard.db
+TEMPLATE_DIR=/site/${FQDN}/templates
+STATIC_DIR=/site/${FQDN}/public
+
+# Server
+PORT=8080
+DEBUG=false
+CACHE_TTL_MINUTES=5
+
+# Default user credentials (change after first login!)
+DEFAULT_USER=admin
+DEFAULT_PASS=your_secure_password
+```
+
+Secure the file:
+
+```bash
+sudo chmod 600 /site/${FQDN}/.env
+sudo chown www-data:www-data /site/${FQDN}/.env
+```
+
+### 4. Install Systemd Service
+
+```bash
+# Copy and customize service file
+sudo cp deployment/task-dashboard.service /etc/systemd/system/task-dashboard@.service
+
+# Enable and start service
+sudo systemctl daemon-reload
+sudo systemctl enable task-dashboard@${FQDN}
+sudo systemctl start task-dashboard@${FQDN}
+
+# Check status
+sudo systemctl status task-dashboard@${FQDN}
+```
+
+### 5. Configure Apache
+
+```bash
+# Enable required modules
+sudo a2enmod proxy proxy_http ssl headers rewrite
+
+# Copy and customize Apache config
+# Replace ${FQDN} with your actual domain in the config file
+sudo cp deployment/apache.conf /etc/apache2/sites-available/${FQDN}.conf
+
+# Edit the file to replace ${FQDN} placeholders
+sudo sed -i "s/\${FQDN}/${FQDN}/g" /etc/apache2/sites-available/${FQDN}.conf
+
+# Enable site
+sudo a2ensite ${FQDN}
+
+# Test and reload
+sudo apache2ctl configtest
+sudo systemctl reload apache2
+```
+
+### 6. SSL Certificate (Let's Encrypt)
+
+```bash
+sudo apt install certbot python3-certbot-apache
+sudo certbot --apache -d ${FQDN}
+```
+
+## Verification
+
+1. Check service is running: `sudo systemctl status task-dashboard@${FQDN}`
+2. Check logs: `sudo journalctl -u task-dashboard@${FQDN} -f`
+3. Visit `https://${FQDN}` and login with configured credentials
+
+## Updating
+
+```bash
+# Stop service
+sudo systemctl stop task-dashboard@${FQDN}
+
+# Deploy new binary
+sudo cp app /site/${FQDN}/
+
+# Update static assets if changed
+sudo cp -r web/static/* /site/${FQDN}/public/
+
+# Update templates if changed
+sudo cp -r web/templates/* /site/${FQDN}/templates/
+
+# Start service
+sudo systemctl start task-dashboard@${FQDN}
+```
+
+## Troubleshooting
+
+### Service won't start
+- Check logs: `sudo journalctl -u task-dashboard@${FQDN} -e`
+- Verify .env file exists and has correct permissions
+- Ensure database directory is writable
+
+### 502 Bad Gateway
+- Check if Go app is running: `sudo systemctl status task-dashboard@${FQDN}`
+- Verify PORT in .env matches Apache ProxyPass
+
+### Static files not loading
+- Ensure `/site/${FQDN}/public/` contains CSS/JS files
+- Check Apache logs: `sudo tail -f /var/log/apache2/${FQDN}-error.log`