Deployment Overview
RALQ can be deployed in two primary ways:
Docker deployment (recommended) - Containerized application with consistent environment
Traditional Apache deployment - Direct installation on a web server
Environment Requirements
System Requirements
PHP runtime with Apache module support
Apache web server with mod_rewrite enabled
Required for building Tailwind CSS (development only)
PHP Extensions
Required PHP extensions:
mysqli - MySQL database connectivity
session - Session management (usually built-in)
json - JSON handling (built-in in PHP 8.2)
Docker Deployment
Dockerfile
The application includes a simple Dockerfile for containerization:
FROM php:8.2-apache
# Copy project files to container
COPY . /var/www/html/
# Enable Apache rewrite module
RUN a2enmod rewrite
Basic Docker Deployment
Build Docker Image
cd /path/to/ralq
docker build -t ralq-app .
Run Container
docker run -d -p 8080:80 --name ralq ralq-app
Access the application at http://localhost:8080
This basic setup does not include MySQL . The application will fail to connect to the database. Use Docker Compose for a complete setup.
Docker Compose Deployment (Recommended)
Create a complete stack with web server and database:
docker-compose.yml
init.sql
Dockerfile.production
version : '3.8'
services :
web :
build : .
ports :
- "80:80"
depends_on :
- db
volumes :
- ./:/var/www/html
environment :
- DB_HOST=db
- DB_USER=ralq_user
- DB_PASS=secure_password_here
- DB_NAME=registro_RALQ
networks :
- ralq-network
db :
image : mysql:8.0
command : --default-authentication-plugin=mysql_native_password
environment :
MYSQL_ROOT_PASSWORD : rootpassword
MYSQL_DATABASE : registro_RALQ
MYSQL_USER : ralq_user
MYSQL_PASSWORD : secure_password_here
volumes :
- mysql_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
networks :
- ralq-network
phpmyadmin :
image : phpmyadmin/phpmyadmin
ports :
- "8081:80"
environment :
PMA_HOST : db
PMA_USER : root
PMA_PASSWORD : rootpassword
depends_on :
- db
networks :
- ralq-network
volumes :
mysql_data :
networks :
ralq-network :
Update Database Configuration
Modify php/validar.php to use environment variables:
<? php
// Use environment variables or fallback to defaults
$servername = getenv ( 'DB_HOST' ) ?: 'localhost' ;
$username = getenv ( 'DB_USER' ) ?: 'root' ;
$password = getenv ( 'DB_PASS' ) ?: '1234' ;
$dbname = getenv ( 'DB_NAME' ) ?: 'registro_RALQ' ;
// Create connection
$conn = new mysqli ( $servername , $username , $password , $dbname );
// Check connection
if ( $conn -> connect_error ) {
error_log ( "Database connection failed: " . $conn -> connect_error );
die ( "Service temporarily unavailable. Please try again later." );
}
?>
Deploy with Docker Compose
Prepare Files
Ensure you have:
Dockerfile (or Dockerfile.production)
docker-compose.yml
init.sql
Application source code
Build and Start Services
docker-compose up -d --build
Verify Deployment
# Check running containers
docker-compose ps
# Check logs
docker-compose logs web
docker-compose logs db
Docker Management Commands
# Stop services
docker-compose down
# Stop and remove volumes (⚠️ deletes database data)
docker-compose down -v
# Restart specific service
docker-compose restart web
# View logs
docker-compose logs -f web
# Execute command in container
docker-compose exec web bash
# Database backup
docker-compose exec db mysqldump -u root -prootpassword registro_RALQ > backup.sql
Traditional Apache Deployment
Server Requirements
Ubuntu 20.04+ / Debian 11+ / CentOS 8+
Apache 2.4+
PHP 8.2+
MySQL 8.0+ or MariaDB 10.5+
2GB RAM minimum
5GB disk space
Installation Steps
Ubuntu/Debian
CentOS/RHEL
Update System
sudo apt update
sudo apt upgrade -y
Install Apache
sudo apt install apache2 -y
sudo systemctl enable apache2
sudo systemctl start apache2
Install PHP 8.2
# Add PHP repository
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
# Install PHP and extensions
sudo apt install php8.2 php8.2-mysqli php8.2-cli php8.2-common \
php8.2-curl php8.2-mbstring php8.2-xml -y
# Enable Apache PHP module
sudo a2enmod php8.2
Install MySQL
sudo apt install mysql-server -y
sudo systemctl enable mysql
sudo systemctl start mysql
# Secure MySQL installation
sudo mysql_secure_installation
Configure Apache
# Enable mod_rewrite
sudo a2enmod rewrite
# Create virtual host
sudo nano /etc/apache2/sites-available/ralq.conf
Add configuration: < VirtualHost *:80 >
ServerName ralq.example.com
DocumentRoot /var/www/ralq
< Directory /var/www/ralq >
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</ Directory >
ErrorLog ${APACHE_LOG_DIR}/ralq_error.log
CustomLog ${APACHE_LOG_DIR}/ralq_access.log combined
</ VirtualHost >
Enable site: sudo a2ensite ralq.conf
sudo systemctl reload apache2
Deploy Application
# Create web directory
sudo mkdir -p /var/www/ralq
# Copy files (adjust source path)
sudo cp -r /path/to/source/ * /var/www/ralq/
# Set permissions
sudo chown -R www-data:www-data /var/www/ralq
sudo chmod -R 755 /var/www/ralq
Setup Database
# Connect to MySQL
sudo mysql -u root -p
Execute SQL: CREATE DATABASE registro_RALQ CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER ' ralq_user '@ 'localhost' IDENTIFIED BY 'secure_password' ;
GRANT SELECT , INSERT , UPDATE ON registro_RALQ. * TO 'ralq_user' @ 'localhost' ;
FLUSH PRIVILEGES;
USE registro_RALQ;
CREATE TABLE usuarios (
id INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR ( 100 ) NOT NULL ,
apellido_paterno VARCHAR ( 100 ) NOT NULL ,
apellido_materno VARCHAR ( 100 ) NOT NULL ,
email VARCHAR ( 255 ) NOT NULL UNIQUE ,
password VARCHAR ( 255 ) NOT NULL ,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_email (email)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
Configure Application
# Edit database configuration
sudo nano /var/www/ralq/php/validar.php
Update credentials: $servername = "localhost" ;
$username = "ralq_user" ;
$password = "secure_password" ;
$dbname = "registro_RALQ" ;
Verify Installation
# Check Apache status
sudo systemctl status apache2
# Check PHP
php -v
# Test database connection
php -r "new mysqli('localhost', 'ralq_user', 'secure_password', 'registro_RALQ');"
Install Apache
sudo dnf install httpd -y
sudo systemctl enable httpd
sudo systemctl start httpd
Install PHP 8.2
# Enable EPEL and Remi repositories
sudo dnf install epel-release -y
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm -y
# Install PHP
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.2 -y
sudo dnf install php php-mysqli php-cli php-common -y
Install MySQL
sudo dnf install mysql-server -y
sudo systemctl enable mysqld
sudo systemctl start mysqld
sudo mysql_secure_installation
Configure SELinux
# Allow Apache to connect to database
sudo setsebool -P httpd_can_network_connect_db 1
# Set file contexts
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/ralq(/.*)?"
sudo restorecon -Rv /var/www/ralq
Configure Firewall
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Building CSS Assets
Development Build
Install Node.js Dependencies
cd /var/www/ralq
npm install
Build Tailwind CSS
# One-time build
npx tailwindcss -i ./src/input.css -o ./build/output.css
# Watch mode (development)
npx tailwindcss -i ./src/input.css -o ./build/output.css --watch
Production Build
# Build minified CSS for production
npx tailwindcss -i ./src/input.css -o ./build/output.css --minify
The application uses both the compiled CSS (build/output.css) and Tailwind CDN. For production, remove the CDN link from HTML files and rely solely on the compiled CSS.
File Permissions
Recommended Permissions
# Set ownership
sudo chown -R www-data:www-data /var/www/ralq
# Set directory permissions
sudo find /var/www/ralq -type d -exec chmod 755 {} \;
# Set file permissions
sudo find /var/www/ralq -type f -exec chmod 644 {} \;
# Make PHP files readable
sudo chmod 644 /var/www/ralq/php/ * .php
Session Directory
# Ensure PHP can write session files
sudo mkdir -p /var/lib/php/sessions
sudo chown www-data:www-data /var/lib/php/sessions
sudo chmod 700 /var/lib/php/sessions
Production Considerations
Security Best Practices
Install Let’s Encrypt SSL certificate: # Install Certbot
sudo apt install certbot python3-certbot-apache -y
# Obtain certificate
sudo certbot --apache -d ralq.example.com
# Auto-renewal is configured automatically
Edit /etc/php/8.2/apache2/php.ini:
Secure Session Configuration
Edit /etc/php/8.2/apache2/php.ini: session.cookie_httponly = 1
session.cookie_secure = 1
session.cookie_samesite = "Strict"
session.use_strict_mode = 1
session.gc_maxlifetime = 1800
Disable Directory Listing
In Apache virtual host: < Directory /var/www/ralq >
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</ Directory >
Install and configure ModSecurity or fail2ban: # Install fail2ban
sudo apt install fail2ban -y
# Create Apache jail
sudo nano /etc/fail2ban/jail.local
Add configuration: [apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/ralq_error.log
maxretry = 5
bantime = 3600
Enable Gzip Compression < IfModule mod_deflate.c >
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
</ IfModule >
Browser Caching < IfModule mod_expires.c >
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</ IfModule >
PHP OPcache Enable in php.ini: opcache.enable =1
opcache.memory_consumption =128
opcache.interned_strings_buffer =8
opcache.max_accelerated_files =10000
MySQL Query Cache SET GLOBAL query_cache_size = 67108864 ;
SET GLOBAL query_cache_type = 1 ;
Monitoring and Logging
# Monitor Apache access logs
sudo tail -f /var/log/apache2/ralq_access.log
# Monitor Apache error logs
sudo tail -f /var/log/apache2/ralq_error.log
# Monitor MySQL slow queries
sudo tail -f /var/log/mysql/mysql-slow.log
# Check disk usage
df -h
# Check memory usage
free -h
Backup Strategy
Automated Backup Script
#!/bin/bash
# Configuration
BACKUP_DIR = "/backups/ralq"
DATE = $( date +%Y%m%d_%H%M%S )
DB_USER = "ralq_user"
DB_PASS = "secure_password"
DB_NAME = "registro_RALQ"
WEB_DIR = "/var/www/ralq"
# Create backup directory
mkdir -p $BACKUP_DIR
# Backup database
mysqldump -u $DB_USER -p $DB_PASS $DB_NAME | gzip > $BACKUP_DIR /db_ $DATE .sql.gz
# Backup files
tar -czf $BACKUP_DIR /files_ $DATE .tar.gz $WEB_DIR
# Keep only last 7 days of backups
find $BACKUP_DIR -name "*.gz" -mtime +7 -delete
echo "Backup completed: $DATE "
Schedule with cron:
# Edit crontab
crontab -e
# Add daily backup at 2 AM
0 2 * * * /usr/local/bin/backup.sh
Troubleshooting
Database Connection Errors
Symptoms : “Conexión fallida” errorSolutions :
Check MySQL is running: sudo systemctl status mysql
Verify credentials in php/validar.php
Test connection: mysql -u ralq_user -p -h localhost registro_RALQ
Check PHP mysqli extension: php -m | grep mysqli
Symptoms : “Failed to write session data”Solutions :
Check session directory: ls -la /var/lib/php/sessions
Fix permissions: sudo chown www-data:www-data /var/lib/php/sessions
Check PHP configuration: php -i | grep session.save_path
Symptoms : Only index.php works, other pages return 404Solutions :
Enable mod_rewrite: sudo a2enmod rewrite
Check AllowOverride in Apache config: AllowOverride All
Restart Apache: sudo systemctl restart apache2
Symptoms : Page displays without CSS stylingSolutions :
Build CSS: npx tailwindcss -i ./src/input.css -o ./build/output.css
Check file exists: ls -la build/output.css
Verify file permissions: chmod 644 build/output.css
Check browser console for errors
Health Check
Create a health check endpoint for monitoring:
<? php
header ( 'Content-Type: application/json' );
$health = [
'status' => 'ok' ,
'timestamp' => time (),
'checks' => []
];
// Check database
try {
require_once 'php/validar.php' ;
if ( $conn -> ping ()) {
$health [ 'checks' ][ 'database' ] = 'ok' ;
} else {
$health [ 'checks' ][ 'database' ] = 'error' ;
$health [ 'status' ] = 'degraded' ;
}
$conn -> close ();
} catch ( Exception $e ) {
$health [ 'checks' ][ 'database' ] = 'error' ;
$health [ 'status' ] = 'degraded' ;
}
// Check PHP version
$health [ 'checks' ][ 'php_version' ] = PHP_VERSION ;
echo json_encode ( $health , JSON_PRETTY_PRINT );
?>
Access at http://your-domain/health.php to verify system status.