Skip to main content

Deployment Overview

RALQ can be deployed in two primary ways:
  1. Docker deployment (recommended) - Containerized application with consistent environment
  2. Traditional Apache deployment - Direct installation on a web server

Environment Requirements

System Requirements

PHP
8.2+
required
PHP runtime with Apache module support
MySQL
5.7+ or 8.0+
required
MySQL database server
Apache
2.4+
required
Apache web server with mod_rewrite enabled
Node.js
14+
required
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

1

Build Docker Image

cd /path/to/ralq
docker build -t ralq-app .
2

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.
Create a complete stack with web server and database:
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/validar.php
<?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

1

Prepare Files

Ensure you have:
  • Dockerfile (or Dockerfile.production)
  • docker-compose.yml
  • init.sql
  • Application source code
2

Build and Start Services

docker-compose up -d --build
3

Verify Deployment

# Check running containers
docker-compose ps

# Check logs
docker-compose logs web
docker-compose logs db
4

Access Application

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

1

Update System

sudo apt update
sudo apt upgrade -y
2

Install Apache

sudo apt install apache2 -y
sudo systemctl enable apache2
sudo systemctl start apache2
3

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
4

Install MySQL

sudo apt install mysql-server -y
sudo systemctl enable mysql
sudo systemctl start mysql

# Secure MySQL installation
sudo mysql_secure_installation
5

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
6

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
7

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;
8

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";
9

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');"

Building CSS Assets

Development Build

1

Install Node.js Dependencies

cd /var/www/ralq
npm install
2

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

# 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:
expose_php = Off
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
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

Performance Optimization

Enable Gzip Compression

.htaccess
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
</IfModule>

Browser Caching

.htaccess
<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

backup.sh
#!/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

Symptoms: “Conexión fallida” errorSolutions:
  1. Check MySQL is running: sudo systemctl status mysql
  2. Verify credentials in php/validar.php
  3. Test connection: mysql -u ralq_user -p -h localhost registro_RALQ
  4. Check PHP mysqli extension: php -m | grep mysqli
Symptoms: “Failed to write session data”Solutions:
  1. Check session directory: ls -la /var/lib/php/sessions
  2. Fix permissions: sudo chown www-data:www-data /var/lib/php/sessions
  3. Check PHP configuration: php -i | grep session.save_path
Symptoms: Only index.php works, other pages return 404Solutions:
  1. Enable mod_rewrite: sudo a2enmod rewrite
  2. Check AllowOverride in Apache config: AllowOverride All
  3. Restart Apache: sudo systemctl restart apache2
Symptoms: Page displays without CSS stylingSolutions:
  1. Build CSS: npx tailwindcss -i ./src/input.css -o ./build/output.css
  2. Check file exists: ls -la build/output.css
  3. Verify file permissions: chmod 644 build/output.css
  4. Check browser console for errors

Health Check

Create a health check endpoint for monitoring:
health.php
<?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.

Build docs developers (and LLMs) love