diff options
| -rw-r--r-- | SESSION_STATE.md | 22 | ||||
| -rw-r--r-- | deployment/apache.conf | 45 | ||||
| -rw-r--r-- | deployment/task-dashboard.service | 25 | ||||
| -rw-r--r-- | docs/deployment.md | 177 |
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` |
