This guide covers production-grade installation of DevolutionSync, including database setup, application configuration, Docker deployment, and security hardening.
This installation guide assumes you have system administrator access and basic knowledge of Linux, MySQL, and Docker.
Log into your MySQL server and create the DevolutionSync database:
CREATE DATABASE IF NOT EXISTS devolutionsync;USE devolutionsync;
2
Create Database User
Create a dedicated user with appropriate permissions:
CREATE USER 'devolution_user'@'%' IDENTIFIED BY 'your_secure_password';GRANT SELECT, INSERT, UPDATE, DELETE ON devolutionsync.* TO 'devolution_user'@'%';FLUSH PRIVILEGES;
Replace your_secure_password with a strong password. Never use default credentials in production.
3
Import Database Schema
Import the complete database schema from Script_BD/Script_DB.sql:
mysql -u root -p devolutionsync < Script_BD/Script_DB.sql
This creates the following tables:
Script_BD/Script_DB.sql
-- Tabla de devolucionesCREATE TABLE IF NOT EXISTS devoluciones ( id INT AUTO_INCREMENT PRIMARY KEY, nit VARCHAR(20) NOT NULL, nombre_cliente VARCHAR(255) NOT NULL, direccion TEXT, codigo_producto VARCHAR(50) NOT NULL, descripcion_producto TEXT, unidad VARCHAR(20), kg DECIMAL(10,2), motivo ENUM('devolucion', 'faltante', 'sobrante') NOT NULL, cantidad_und INT, cantidad_kg DECIMAL(10,2), evidencia VARCHAR(255), observacion TEXT, estado ENUM('pendiente', 'aprobado', 'rechazado') DEFAULT 'pendiente', observacion_admin TEXT, codigo_admin VARCHAR(50), fecha_creacion TIMESTAMP DEFAULT CURRENT_TIMESTAMP, fecha_revision TIMESTAMP NULL, usuario_creador VARCHAR(50) NOT NULL, usuario_revisor VARCHAR(50));-- Tabla de notificacionesCREATE TABLE IF NOT EXISTS notificaciones ( id INT AUTO_INCREMENT PRIMARY KEY, id_devolucion INT NOT NULL, mensaje TEXT NOT NULL, leida BOOLEAN DEFAULT FALSE, fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP, usuario_destino VARCHAR(50) NOT NULL, FOREIGN KEY (id_devolucion) REFERENCES devoluciones(id));-- Tabla login_attemptsCREATE TABLE IF NOT EXISTS login_attempts ( id INT AUTO_INCREMENT PRIMARY KEY, ip_address VARCHAR(45) NOT NULL, username VARCHAR(50) NOT NULL, attempts INT DEFAULT 0, last_attempt DATETIME, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);-- Tabla usuariosCREATE TABLE `usuarios` ( `USR` VARCHAR(50) NOT NULL, `PAS` VARCHAR(50) NOT NULL, `NOMBRE` VARCHAR(100) NOT NULL, `GRADO` INT NOT NULL, PRIMARY KEY (`USR`));
Change these default passwords immediately after installation using the admin user management interface.
5
Configure Indexes (Optional)
For better query performance on large datasets:
CREATE INDEX idx_estado ON devoluciones(estado);CREATE INDEX idx_fecha_creacion ON devoluciones(fecha_creacion);CREATE INDEX idx_usuario_creador ON devoluciones(usuario_creador);CREATE INDEX idx_motivo ON devoluciones(motivo);
# Usa la imagen oficial de PHP con ApacheFROM php:8.2-apache# Habilita extensiones necesariasRUN docker-php-ext-install pdo pdo_mysql mysqli# Copia todos los archivos del proyecto al contenedorCOPY . /var/www/html/# Ajusta permisosRUN chown -R www-data:www-data /var/www/html \ && chmod -R 755 /var/www/html# Expone el puerto del servidor ApacheEXPOSE 80
2
Configure Docker Compose
Edit Docker-compose.yml for your environment:
Docker-compose.yml
services: web: build: context: . dockerfile: Dockerfile container_name: Proyecto_UCP ports: - "8097:80" # Change to 80:80 for production volumes: - ./:/var/www/html # Remove in production environment: - DB_HOST=192.200.100.40 - DB_NAME=devolutionsync - DB_USER=devolution_user - DB_PASS=${DB_PASSWORD} # From .env file networks: - red_local restart: unless-stoppedvolumes: db_data:networks: red_local:
Remove the volumes mount in production to prevent live code editing. Rebuild the image instead.
3
Build and Launch
Build the Docker image and start the container:
# Build the imagedocker-compose build# Start in detached modedocker-compose up -d# Check container statusdocker ps# View logsdocker logs -f Proyecto_UCP
4
Verify Installation
Test the application is running correctly:
# Check web server responsecurl -I http://localhost:8097# Test database connectivitydocker exec -it Proyecto_UCP php -r "require 'Config/Conexion.php'; Conexion::Conectar(); echo 'Connected!\n';"# Check file permissionsdocker exec -it Proyecto_UCP ls -la uploads/
-- Update admin passwordUPDATE usuarios SET PAS = 'new_secure_password' WHERE USR = 'ANALISTA';-- Update auxiliary passwordUPDATE usuarios SET PAS = 'new_secure_password' WHERE USR = 'AUXILIAR';-- Update consultation passwordUPDATE usuarios SET PAS = 'new_secure_password' WHERE USR = 'CONSULTA';
Consider implementing password hashing using password_hash() instead of plain text passwords.
Enable HTTPS
Configure Apache with SSL certificate:
<VirtualHost *:443> ServerName devolutionsync.example.com DocumentRoot /var/www/html SSLEngine on SSLCertificateFile /etc/ssl/certs/devolutionsync.crt SSLCertificateKeyFile /etc/ssl/private/devolutionsync.key <Directory /var/www/html> Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory></VirtualHost>
Session Security
The application implements session timeout (3 minutes of inactivity):
Views/auth/login.php
// Detectar si venimos de un timeout de sesiónwindow.addEventListener('DOMContentLoaded', () => { const urlParams = new URLSearchParams(window.location.search); if (urlParams.get('timeout') === '1') { showAlert('Su sesión ha expirado por inactividad.', 'warning'); }});