Overview
This guide covers deploying Dashboard Dilemmas on a server running Apache. The application is a PHP-based system that can be deployed as a traditional LAMP stack application.
If migrating from a Next.js version, this guide also covers Apache reverse proxy configuration for Node.js applications.
Prerequisites
Before deploying, ensure your server has:
Apache 2.4 or higher
PHP 7.4 or higher
MySQL 5.7 or higher (or MariaDB)
WordPress installation (for authentication)
Domain name pointing to your server
SSL certificate (recommended for production)
PHP Application Deployment
Standard LAMP Deployment
Prepare the Server
Install required packages: sudo apt update
sudo apt install apache2 php php-mysql php-mbstring php-xml php-curl mysql-server
Enable necessary Apache modules: sudo a2enmod rewrite
sudo a2enmod headers
sudo a2enmod expires
sudo systemctl restart apache2
Upload Application Files
Transfer your application files to the server: # Using SCP
scp -r dashboard-dilemas/ user@server:/var/www/
# Or using rsync
rsync -avz --exclude 'dev/' --exclude '.git/' dashboard-dilemas/ user@server:/var/www/dashboard-dilemas/
Set proper permissions: sudo chown -R www-data:www-data /var/www/dashboard-dilemas
sudo chmod -R 755 /var/www/dashboard-dilemas
Configure Database
Create the production database: CREATE DATABASE dilemas_prod CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER ' dilemas_user '@ 'localhost' IDENTIFIED BY 'secure_password' ;
GRANT ALL PRIVILEGES ON dilemas_prod. * TO 'dilemas_user' @ 'localhost' ;
FLUSH PRIVILEGES;
Import the database schema: mysql -u dilemas_user -p dilemas_prod < sql/database.sql
mysql -u dilemas_user -p dilemas_prod < sql/users.sql
mysql -u dilemas_user -p dilemas_prod < sql/areas_schema.sql
Configure Application
Update includes/config.php with production settings: <? php
// Production Site Configuration
define ( 'SITE_URL' , 'https://dashboard.dilemaseticos.com' );
define ( 'WP_SITE_URL' , 'https://dilemaseticos.com' );
define ( 'WP_PATH' , '/var/www/wordpress' );
// Production Database (if using separate DB)
define ( 'DB_HOST' , 'localhost' );
define ( 'DB_USER' , 'dilemas_user' );
define ( 'DB_PASSWORD' , 'secure_password' );
define ( 'DB_NAME' , 'dilemas_prod' );
// SMTP Settings
define ( 'SMTP_HOST' , 'smtp-relay.brevo.com' );
define ( 'SMTP_USER' , '[email protected] ' );
define ( 'SMTP_PASS' , 'your_smtp_password' );
define ( 'SMTP_PORT' , 587 );
define ( 'SMTP_SECURE' , 'tls' );
define ( 'SMTP_FROM_EMAIL' , '[email protected] ' );
define ( 'SMTP_FROM_NAME' , 'Dilemas Eticos' );
// Gemini AI API Key
define ( 'GEMINI_API_KEY' , 'your_production_api_key' );
?>
Never commit production credentials to version control. Use environment-specific config files or environment variables.
Configure Apache Virtual Host
Create a new virtual host configuration: sudo nano /etc/apache2/sites-available/dashboard.conf
Add the following configuration: /etc/apache2/sites-available/dashboard.conf
< VirtualHost *:80 >
ServerName dashboard.dilemaseticos.com
ServerAdmin [email protected]
DocumentRoot /var/www/dashboard-dilemas
< Directory /var/www/dashboard-dilemas >
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</ Directory >
# Security Headers
< IfModule mod_headers.c >
Header set X-Content-Type- Options "nosniff"
Header set X-Frame- Options "SAMEORIGIN"
Header set X-XSS-Protection " 1 ; mode=block"
</ IfModule >
ErrorLog ${APACHE_LOG_DIR}/dashboard-error.log
CustomLog ${APACHE_LOG_DIR}/dashboard-access.log combined
</ VirtualHost >
Enable the site: sudo a2ensite dashboard.conf
sudo systemctl reload apache2
Enable SSL with Let's Encrypt
Install Certbot and obtain an SSL certificate: sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d dashboard.dilemaseticos.com
Certbot will automatically configure HTTPS and set up auto-renewal.
Verify Deployment
Test your deployment:
Visit https://dashboard.dilemaseticos.com
Check Apache error logs for issues:
sudo tail -f /var/log/apache2/dashboard-error.log
Verify database connection using dev/debug/debug_db.php
Test authentication flow
Next.js Deployment (Alternative)
If deploying a Next.js version of the application, use Apache as a reverse proxy.
Prerequisites for Next.js
Node.js v18 or higher
PM2 process manager
MySQL database
Build the Application
On your server, navigate to the project directory: cd /var/www/dashboard-dilemas
npm install
npm run build
Install and Configure PM2
Install PM2 globally: Start the application: pm2 start npm --name "dashboard-dilemas" -- start -- -p 3000
Save PM2 configuration for auto-restart: This ensures the app starts automatically after server reboots.
Configure Apache Reverse Proxy
Enable required modules: sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
sudo systemctl restart apache2
Create virtual host configuration: /etc/apache2/sites-available/dashboard.conf
< VirtualHost *:80 >
ServerName dashboard.dilemaseticos.com
ServerAdmin [email protected]
ProxyPreserveHost On
ProxyPass / http://localhost: 3000 /
ProxyPassReverse / http://localhost: 3000 /
# WebSocket support (for Next.js dev features)
ProxyPass /ws ws://localhost: 3000 /ws
ProxyPassReverse /ws ws://localhost: 3000 /ws
ErrorLog ${APACHE_LOG_DIR}/dashboard-error.log
CustomLog ${APACHE_LOG_DIR}/dashboard-access.log combined
</ VirtualHost >
Enable the site: sudo a2ensite dashboard.conf
sudo systemctl reload apache2
Configure Environment Variables
Create a .env file on the server: DB_HOST = localhost
DB_USER = dilemas_user
DB_PASSWORD = secure_password
DB_NAME = dilemas_prod
# Application URL
NEXT_PUBLIC_API_URL = https://dashboard.dilemaseticos.com
# SMTP Configuration
SMTP_HOST = smtp-relay.brevo.com
SMTP_USER = [email protected]
SMTP_PASSWORD = your_smtp_password
Restart the application to apply changes: pm2 restart dashboard-dilemas
PM2 Process Management
Common PM2 Commands
# View running processes
pm2 list
# View logs
pm2 logs dashboard-dilemas
# Restart application
pm2 restart dashboard-dilemas
# Stop application
pm2 stop dashboard-dilemas
# Monitor resources
pm2 monit
# Delete process
pm2 delete dashboard-dilemas
Auto-restart on Changes
For development servers, enable watch mode:
pm2 start npm --name "dashboard-dilemas" --watch -- start -- -p 3000
Do not use watch mode in production as it may cause unnecessary restarts.
Security Best Practices
File Permissions
# Set secure permissions
sudo chown -R www-data:www-data /var/www/dashboard-dilemas
sudo find /var/www/dashboard-dilemas -type d -exec chmod 755 {} \;
sudo find /var/www/dashboard-dilemas -type f -exec chmod 644 {} \;
# Protect configuration files
sudo chmod 600 /var/www/dashboard-dilemas/includes/config.php
Database Security
Use strong passwords for database users
Limit database user permissions to only required operations
Disable remote root login
Regular backups:
# Create backup script
mysqldump -u dilemas_user -p dilemas_prod > backup_ $( date +%Y%m%d ) .sql
# Automate with cron (daily at 2 AM)
0 2 * * * /usr/bin/mysqldump -u dilemas_user -pPASSWORD dilemas_prod > /backups/dilemas_ $( date + \% Y \% m \% d ) .sql
Apache Security
Add security headers to your virtual host:
< IfModule mod_headers.c >
Header set X-Content-Type- Options "nosniff"
Header set X-Frame- Options "SAMEORIGIN"
Header set X-XSS-Protection " 1 ; mode=block"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</ IfModule >
Monitoring and Logging
Apache Logs
# View real-time error log
sudo tail -f /var/log/apache2/dashboard-error.log
# View access log
sudo tail -f /var/log/apache2/dashboard-access.log
# Search for errors
sudo grep -i error /var/log/apache2/dashboard-error.log
Application Logs
For Next.js/Node.js deployments:
# PM2 logs
pm2 logs dashboard-dilemas
# PM2 error logs only
pm2 logs dashboard-dilemas --err
# Clear logs
pm2 flush
Enable Apache Caching
The .htaccess file includes caching configuration:
< IfModule mod_expires.c >
ExpiresActive On
ExpiresDefault "access plus 1 month"
ExpiresByType text/css "access plus 4 hours"
ExpiresByType application/javascript "access plus 4 hours"
</ IfModule >
< IfModule mod_headers.c >
< FilesMatch "\.(js|css)$" >
Header set Cache-Control "max-age= 14400 , public, must-revalidate"
</ FilesMatch >
</ IfModule >
Database Optimization
Apply performance indexes:
mysql -u dilemas_user -p dilemas_prod < sql/add_performance_indexes.sql
mysql -u dilemas_user -p dilemas_prod < sql/optimizations.sql
Enable Gzip Compression
Add to your Apache configuration:
< IfModule mod_deflate.c >
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
AddOutputFilterByType DEFLATE application/javascript application/json
</ IfModule >
Troubleshooting
Common Issues
500 Internal Server Error
Check Apache error logs
Verify .htaccess syntax
Ensure AllowOverride All is set in virtual host
Check PHP error logs: sudo tail -f /var/log/apache2/error.log
Database Connection Failed
Verify database credentials in config.php
Test database connection: mysql -u dilemas_user -p
Check MySQL is running: sudo systemctl status mysql
Verify firewall allows MySQL connections
PM2 Application Won't Start
Check PM2 logs: pm2 logs dashboard-dilemas
Verify Node.js version: node --version
Rebuild application: npm run build
Check port 3000 is available: sudo lsof -i :3000
Apache Reverse Proxy Issues
Verify proxy modules are enabled:
apache2ctl -M | grep proxy
Check application is running: pm2 list
Test direct access: curl http://localhost:3000
Review Apache error logs
Rollback Procedure
If deployment fails, follow these steps to rollback:
# 1. Stop the new version
pm2 stop dashboard-dilemas
# 2. Restore previous code
cd /var/www/dashboard-dilemas
git reset --hard < previous-commit-has h >
# 3. Restore database (if needed)
mysql -u dilemas_user -p dilemas_prod < backup_YYYYMMDD.sql
# 4. Rebuild and restart
npm install
npm run build
pm2 restart dashboard-dilemas
Next Steps
Setup Guide Return to development setup
File Structure Review project organization