Skip to main content

Overview

This comprehensive guide covers installing and configuring SASCOP BME SubTec for both development and production environments. The system is built with Django 4.2.7 and requires PostgreSQL as the database backend.
Estimated Time: 30-45 minutes for a complete setup

System Requirements

Software Prerequisites

Python

Version: Python 3.9 or higherVerify installation:
python --version

PostgreSQL

Version: PostgreSQL 12 or higherVerify installation:
psql --version

pip

Version: pip 21.0 or higherUpgrade pip:
pip install --upgrade pip

Git

Version: Git 2.0 or higherCheck version:
git --version

Hardware Requirements

  • CPU: 2 cores minimum
  • RAM: 4 GB minimum, 8 GB recommended
  • Storage: 10 GB available space
  • Network: Stable internet connection

Installation Steps

1. System Preparation

1

Update System Packages

sudo apt update
sudo apt upgrade -y
2

Install PostgreSQL

sudo apt install postgresql postgresql-contrib libpq-dev -y
sudo systemctl start postgresql
sudo systemctl enable postgresql
3

Install Python Development Tools

sudo apt install python3 python3-pip python3-dev python3-venv -y

2. Database Setup

1

Create PostgreSQL Database

Connect to PostgreSQL and create the database:
sudo -u postgres psql
-- Create database
CREATE DATABASE sascop_production;

-- Create user
CREATE USER sascop_user WITH PASSWORD 'secure_password_here';

-- Grant privileges
ALTER ROLE sascop_user SET client_encoding TO 'utf8';
ALTER ROLE sascop_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE sascop_user SET timezone TO 'America/Mexico_City';
GRANT ALL PRIVILEGES ON DATABASE sascop_production TO sascop_user;

-- Exit
\q
Replace secure_password_here with a strong password. Save this for later use.
2

Configure PostgreSQL Access

Edit PostgreSQL configuration to allow application access:
sudo nano /etc/postgresql/[version]/main/pg_hba.conf
Add or modify the following line:
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    sascop_production  sascop_user     127.0.0.1/32            md5
Restart PostgreSQL:
sudo systemctl restart postgresql
3

Test Database Connection

Verify you can connect:
psql -h localhost -U sascop_user -d sascop_production
Enter the password when prompted. If successful, you’ll see the PostgreSQL prompt.

3. Application Installation

1

Clone Repository

cd /opt  # or your preferred directory
git clone <repository-url> sascop
cd sascop
2

Create Virtual Environment

Create and activate a Python virtual environment:
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
Always activate the virtual environment before working with the application.
3

Install Python Dependencies

Install all required packages from requirements.txt:
pip install --upgrade pip
pip install -r requirements.txt
requirements.txt
# Web Framework
Django==4.2.7              # Main framework
gunicorn==21.2.0           # WSGI server for production

# Database
psycopg2-binary==2.9.7     # PostgreSQL adapter

# Static Files
whitenoise==6.4.0          # Static file serving

# Data Processing
pandas==2.3.3              # Data analysis
numpy==2.3.3               # Numerical computing
openpyxl==3.1.5            # Excel file handling
XlsxWriter==3.1.2          # Excel generation

# PDF Generation
reportlab==4.0.4           # PDF creation
PyPDF2==3.0.1              # PDF manipulation

# Visualization
matplotlib==3.10.8         # Charts and graphs
qrcode==7.4.2              # QR code generation

# Email
django-anymail==14.0       # Email service integration

# Utilities
python-dotenv==1.0.0       # Environment variable management
beautifulsoup4==4.12.2     # HTML parsing
requests==2.31.0           # HTTP library
See full file at: requirements.txt:1
4

Verify Installation

Check that all packages installed correctly:
pip list
python -c "import django; print(django.get_version())"
Expected output: 4.2.7

4. Configuration

1

Create Environment File

Create a .env file in the project root:
touch .env
chmod 600 .env  # Restrict access
Add the following configuration:
.env
# ======================
# SECURITY SETTINGS
# ======================
SECRET_KEY=your-unique-secret-key-generate-this-randomly
DEBUG=False

# ======================
# DATABASE CONFIGURATION
# ======================
RDS_DB_NAME=sascop_production
RDS_USERNAME=sascop_user
RDS_PASSWORD=secure_password_here
RDS_HOSTNAME=localhost
RDS_PORT=5432

# ======================
# EMAIL CONFIGURATION
# ======================
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=[email protected]
EMAIL_HOST_PASSWORD=your-email-app-password
DEFAULT_FROM_EMAIL=SASCOP <[email protected]>

# Optional: SendGrid
# SENDGRID_API_KEY=your-sendgrid-api-key

# ======================
# PAYMENT GATEWAY (Optional)
# ======================
OPENPAY_MERCHANT_ID=
OPENPAY_PRIVATE_KEY=
OPENPAY_PRODUCTION=False
Generate a Secure SECRET_KEY:
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
Copy the output and use it as your SECRET_KEY.
2

Configure Settings

The main settings file is at bme_subtec/settings.py. Key configurations:
# From settings.py:9-30
SECRET_KEY = os.getenv('SECRET_KEY', 'django-insecure-bme-subtec-default-key-change-in-production')
DEBUG = os.getenv('DEBUG', 'True') == 'True'

ALLOWED_HOSTS = [
    'localhost',
    '127.0.0.1',
    '0.0.0.0',
    'your-production-domain.com',
]

CSRF_TRUSTED_ORIGINS = [
    'http://localhost',
    'http://127.0.0.1',
    'https://your-production-domain.com',
]
The custom SessionTimeoutMiddleware automatically logs out users after 2 hours of inactivity (configurable via SESSION_COOKIE_AGE).
3

Configure Localization

The system is configured for Mexican timezone and Spanish language:
settings.py
# From settings.py:124-127
LANGUAGE_CODE = 'es-mx'
TIME_ZONE = 'America/Mexico_City'
USE_I18N = True
USE_TZ = True
Adjust these settings for your region if needed.

5. Database Migration

1

Run Initial Migrations

Create all database tables:
python manage.py migrate
This creates tables for:
  • Authentication: User accounts and permissions
  • PTEs: Technical project proposals (pte_header, pte_detalle)
  • OTEs: Work orders (ot, ot_detalle)
  • Catalogs: Reference data (tipo, frente, estatus, sitio, etc.)
  • Production: Production tracking (produccion, reporte_mensual, reporte_diario)
  • Contracts: Contract and pricing (contrato, anexo_contrato, concepto_maestro)
  • Estimations: Financial estimations (estimacion_header, estimacion_detalle)
  • Activity Logs: User activity tracking (registro_actividad)
2

Create Superuser Account

Create an administrator account:
python manage.py createsuperuser
Enter the requested information:
3

Verify Database Schema

Connect to the database and verify tables were created:
psql -h localhost -U sascop_user -d sascop_production
\dt  -- List all tables
You should see tables like: pte_header, ot, produccion, etc.

6. Static Files Configuration

1

Collect Static Files

Gather all static assets:
python manage.py collectstatic --noinput
This copies files from:
  • Django admin (django.contrib.admin)
  • Application static files (operaciones/static/)
To the STATIC_ROOT directory (staticfiles/).
2

Configure Static Files Serving

The system uses WhiteNoise for efficient static file serving:
settings.py
# From settings.py:129-131
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_DIRS = [
    BASE_DIR / 'operaciones' / 'static',
]
WhiteNoise is configured in middleware (settings.py:51):
'whitenoise.middleware.WhiteNoiseMiddleware',
3

Set Correct Permissions

Ensure static files are readable:
chmod -R 755 staticfiles/

7. Testing the Installation

1

Run Development Server

Start the Django development server:
python manage.py runserver 0.0.0.0:8000
The application will be available at http://localhost:8000/
2

Access the Application

Open your browser and navigate to:

Login Page

http://localhost:8000/accounts/login/Test the custom login functionality that accepts username or email.

Admin Panel

http://localhost:8000/admin/Login with your superuser credentials.
3

Verify Core Functionality

After logging in, check:
  1. Dashboard (/): Main dashboard loads
  2. PTE List (/operaciones/pte/): PTE management interface
  3. OT List (/operaciones/ot/): Work order management
  4. Production (/operaciones/produccion/): Production tracking
  5. Centro de Consulta (/operaciones/centro_consulta/centro-consulta/): BI dashboard

Production Deployment

Using Gunicorn

1

Create Gunicorn Configuration

Create gunicorn_config.py in the project root:
gunicorn_config.py
import multiprocessing

# Server socket
bind = "0.0.0.0:8000"
backlog = 2048

# Worker processes
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = 'sync'
worker_connections = 1000
timeout = 120
keepalive = 5

# Logging
accesslog = '/var/log/sascop/access.log'
errorlog = '/var/log/sascop/error.log'
loglevel = 'info'

# Process naming
proc_name = 'sascop_bme_subtec'

# Server mechanics
daemon = False
pidfile = '/var/run/sascop.pid'
user = None
group = None
tmp_upload_dir = None
2

Create Systemd Service

Create /etc/systemd/system/sascop.service:
sascop.service
[Unit]
Description=SASCOP BME SubTec Gunicorn daemon
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/opt/sascop
Environment="PATH=/opt/sascop/venv/bin"
EnvironmentFile=/opt/sascop/.env
ExecStart=/opt/sascop/venv/bin/gunicorn \
          --config /opt/sascop/gunicorn_config.py \
          bme_subtec.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
3

Start and Enable Service

# Reload systemd
sudo systemctl daemon-reload

# Start service
sudo systemctl start sascop

# Enable on boot
sudo systemctl enable sascop

# Check status
sudo systemctl status sascop

Nginx Configuration

1

Install Nginx

sudo apt install nginx -y
2

Create Nginx Configuration

Create /etc/nginx/sites-available/sascop:
sascop.conf
upstream sascop_app {
    server 127.0.0.1:8000 fail_timeout=0;
}

server {
    listen 80;
    server_name your-domain.com www.your-domain.com;
    
    client_max_body_size 100M;
    
    # Redirect to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name your-domain.com www.your-domain.com;

    ssl_certificate /etc/ssl/certs/your-cert.crt;
    ssl_certificate_key /etc/ssl/private/your-key.key;
    
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    client_max_body_size 100M;
    
    # Static files
    location /static/ {
        alias /opt/sascop/staticfiles/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
    
    # Media files
    location /media/ {
        alias /opt/sascop/media/;
    }
    
    # Application
    location / {
        proxy_pass http://sascop_app;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
        proxy_buffering off;
    }
}
3

Enable Site and Restart Nginx

sudo ln -s /etc/nginx/sites-available/sascop /etc/nginx/sites-enabled/
sudo nginx -t  # Test configuration
sudo systemctl restart nginx

Post-Installation

1

Load Initial Data

If you have fixtures or initial data:
python manage.py loaddata initial_data.json
Or import Excel files using the admin interface or management commands.
2

Configure Backup Strategy

Set up automated PostgreSQL backups:
backup.sh
#!/bin/bash
BACKUP_DIR="/backup/sascop"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")

pg_dump -h localhost -U sascop_user sascop_production | \
    gzip > $BACKUP_DIR/sascop_$TIMESTAMP.sql.gz

# Keep only last 30 days
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
Add to crontab:
0 2 * * * /opt/sascop/backup.sh
3

Set Up Monitoring

Monitor application health:
  • Check Gunicorn logs: /var/log/sascop/
  • Monitor PostgreSQL: sudo systemctl status postgresql
  • Check Nginx access: /var/log/nginx/access.log
  • Monitor disk space: df -h

Troubleshooting

This indicates the PostgreSQL adapter isn’t installed:
# Install system dependencies first
sudo apt install libpq-dev python3-dev

# Reinstall psycopg2
pip install --upgrade psycopg2-binary
Check PostgreSQL is running and accepting connections:
sudo systemctl status postgresql
sudo systemctl start postgresql
Verify connection parameters:
psql -h localhost -U sascop_user -d sascop_production
Check pg_hba.conf for proper authentication settings.
  1. Ensure WhiteNoise is in MIDDLEWARE
  2. Run collectstatic:
    python manage.py collectstatic --noinput --clear
    
  3. Check file permissions:
    ls -la staticfiles/
    
  4. Verify STATIC_ROOT path is correct
Set correct ownership and permissions:
# Change ownership to web server user
sudo chown -R www-data:www-data /opt/sascop

# Set directory permissions
find /opt/sascop -type d -exec chmod 755 {} \;

# Set file permissions
find /opt/sascop -type f -exec chmod 644 {} \;

# Make manage.py executable
chmod +x /opt/sascop/manage.py
If migrations fail:
  1. Check database connectivity
  2. Verify user has CREATE permission
  3. Try running migrations with verbosity:
    python manage.py migrate --verbosity 3
    
  4. If needed, fake migrations (use with caution):
    python manage.py migrate --fake
    

Next Steps

Architecture Overview

Learn about the system architecture and data models

User Roles

Configure user permissions and roles

Workflow Guide

Understand the PTE to OTE workflow

Quick Start

Quick reference for common tasks
This installation guide is based on the production configuration at bme_subtec/settings.py. Customize settings based on your specific deployment requirements.

Build docs developers (and LLMs) love