Implementación de AWS EC2#
Guía completa para implementar Construbot en instancias EC2 de Amazon Web Services.
Descripción general#
Esta guía cubre la implementación de Construbot en AWS EC2 utilizando Docker Compose. Esta configuración es adecuada para implementaciones pequeñas y medianas (hasta varios miles de usuarios).
Qué construirás:
Instancia EC2 que ejecuta Ubuntu 22.04
Docker Compose orquestando todos los servicios
Base de datos RDS PostgreSQL (recomendada) o autohospedada
ElastiCache Redis (opcional) o autohospedado
S3 para almacenamiento de archivos multimedia
Ruta 53 para DNS (opcional)
Certificado SSL de Let’s Encrypt
Costo estimado: $20-80/mes dependiendo del tamaño de las instancias
Requisitos previos#
Configuración de la cuenta de AWS#
✓ AWS account with billing enabled
✓ AWS CLI installed and configured
✓ SSH key pair for EC2 access
✓ Domain name (for HTTPS)
Instalar AWS CLI:
# macOS
brew install awscli
# Linux
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Configure
aws configure
Requisitos locales#
✓ SSH client
✓ Git
✓ Basic Linux administration knowledge
Paso 1: iniciar la instancia EC2#
Selección de instancia#
Especificaciones recomendadas:
Tipo de instancia: t3.small (2 vCPU, 2 GB de RAM) mínimo, t3.medium (2 vCPU, 4 GB de RAM) recomendado
SO: Servidor Ubuntu 22.04 LTS
Almacenamiento: 30 GB gp3 SSD mínimo
Región: Elija la más cercana a sus usuarios
A través de la consola de AWS:
Navegue al Panel de EC2
Haga clic en «Iniciar instancia»
Elija «Ubuntu Server 22.04 LTS (HVM), tipo de volumen SSD»
Seleccione el tipo de instancia (t3.small o mayor)
Configurar el almacenamiento (30 GB mínimo)
Agregar etiquetas: Nombre=construbot-producción
Configurar el grupo de seguridad (ver más abajo)
Revisión y lanzamiento
A través de AWS CLI:
aws ec2 run-instances \\
--image-id ami-0557a15b87f6559cf \\ # Ubuntu 22.04 (us-east-1)
--instance-type t3.small \\
--key-name your-key-pair \\
--security-group-ids sg-xxxxx \\
--subnet-id subnet-xxxxx \\
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}]' \\
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=construbot-production}]'
Configuración del grupo de seguridad#
Reglas requeridas:
Type Protocol Port Range Source Description
SSH TCP 22 Your IP SSH access
HTTP TCP 80 0.0.0.0/0 HTTP traffic
HTTPS TCP 443 0.0.0.0/0 HTTPS traffic
A través de la consola de AWS:
Panel EC2 → Grupos de seguridad → Crear grupo de seguridad
Agregue reglas de entrada como se indica arriba
Nombre: construbot-sg
A través de AWS CLI:
# Create security group
aws ec2 create-security-group \\
--group-name construbot-sg \\
--description "Construbot security group"
# Add rules
aws ec2 authorize-security-group-ingress \\
--group-name construbot-sg \\
--protocol tcp --port 22 --cidr your-ip/32
aws ec2 authorize-security-group-ingress \\
--group-name construbot-sg \\
--protocol tcp --port 80 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress \\
--group-name construbot-sg \\
--protocol tcp --port 443 --cidr 0.0.0.0/0
IP elástica#
Asignar IP estática:
# Allocate Elastic IP
aws ec2 allocate-address
# Associate with instance
aws ec2 associate-address \\
--instance-id i-xxxxx \\
--allocation-id eipalloc-xxxxx
Advertencia
Cargos de IP elástica: Se le cobra cuando se asigna la IP pero se detiene la instancia. Libere las IP elásticas no utilizadas para evitar cargos.
Paso 2: conectarse a la instancia#
Conexión SSH#
# Get instance public IP
aws ec2 describe-instances \\
--instance-ids i-xxxxx \\
--query 'Reservations[0].Instances[0].PublicIpAddress'
# Connect via SSH
ssh -i ~/.ssh/your-key.pem ubuntu@<public-ip>
Conexión por primera vez:
Verás un mensaje sobre la autenticidad del host. Escriba sí para continuar.
Paso 3: configuración del servidor#
Actualizaciones del sistema#
# Update package list
sudo apt update
# Upgrade packages
sudo apt upgrade -y
# Install basic tools
sudo apt install -y git curl wget vim
Instalar ventana acoplable#
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add ubuntu user to docker group
sudo usermod -aG docker ubuntu
# Install Docker Compose
sudo apt install -y docker-compose-plugin
# Verify installation
docker --version
docker compose version
# Log out and back in for group changes to take effect
exit
Configurar cortafuegos#
# Enable UFW
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw --force enable
# Check status
sudo ufw status
Paso 4: implementar la aplicación#
Repositorio de clones#
# Create application directory
sudo mkdir -p /opt/construbot
sudo chown ubuntu:ubuntu /opt/construbot
# Clone repository
cd /opt/construbot
git clone https://github.com/javier-llamas/construbot.git .
Configurar el entorno#
# Copy environment template
cp .env.example .env
# Edit environment file
nano .env
Producción mínima .env:
# Django
DJANGO_SETTINGS_MODULE=construbot.config.settings.production
DJANGO_DEBUG=False
DJANGO_SECRET_KEY=<generate-with-openssl-rand-base64-50>
DJANGO_ALLOWED_HOSTS=your-domain.com,www.your-domain.com
# Database (self-hosted)
DATABASE_URL=postgresql://construbot:strong-password@postgres:5432/construbot
# Redis
REDIS_URL=redis://redis:6379/0
# Email (example with Mailgun)
DJANGO_EMAIL_BACKEND=anymail.backends.mailgun.EmailBackend
MAILGUN_API_KEY=your-api-key
MAILGUN_SENDER_DOMAIN=mg.your-domain.com
DEFAULT_FROM_EMAIL=noreply@your-domain.com
# Static/Media
USE_S3=True
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_STORAGE_BUCKET_NAME=construbot-media
AWS_S3_REGION_NAME=us-east-1
# Security
DJANGO_SECURE_SSL_REDIRECT=True
DJANGO_SECURE_HSTS_SECONDS=31536000
# Monitoring
SENTRY_DSN=your-sentry-dsn
Construir y comenzar#
# Build production images
docker compose build
# Start services
docker compose up -d
# Check status
docker compose ps
Inicializar base de datos#
# Run migrations
docker compose run --rm django python manage.py migrate
# Create superuser
docker compose run --rm django python manage.py createsuperuser
# Collect static files
docker compose run --rm django python manage.py collectstatic --no-input
Paso 5: configurar el dominio y SSL#
Configuración de DNS#
Usando la Ruta 53:
# Create hosted zone (if not exists)
aws route53 create-hosted-zone --name your-domain.com --caller-reference $(date +%s)
# Get hosted zone ID
aws route53 list-hosted-zones
# Create A record
aws route53 change-resource-record-sets \\
--hosted-zone-id Z1234567890ABC \\
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "your-domain.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [{"Value": "your-elastic-ip"}]
}
}]
}'
Usando otros proveedores de DNS:
Agregue un registro que apunte a su IP elástica:
Type: A
Name: @
Value: <your-elastic-ip>
TTL: 3600
Certificado SSL (Vamos a cifrar)#
# Install certbot
sudo apt install -y certbot python3-certbot-nginx
# Stop nginx in Docker (if running)
docker compose stop nginx
# Obtain certificate
sudo certbot certonly --standalone -d your-domain.com -d www.your-domain.com
# Certificates saved to:
# /etc/letsencrypt/live/your-domain.com/fullchain.pem
# /etc/letsencrypt/live/your-domain.com/privkey.pem
# Set up auto-renewal
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
Actualice docker-compose.yml para montar certificados:
nginx:
volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro
Reiniciar nginx:
docker compose up -d nginx
Paso 6: configurar los servicios de AWS#
RDS PostgreSQL (recomendado)#
Beneficios:
Copias de seguridad automatizadas
Alta disponibilidad (Multi-AZ)
Conmutación por error automática
Actualizaciones administradas
Crear instancia RDS:
aws rds create-db-instance \\
--db-instance-identifier construbot-db \\
--db-instance-class db.t3.micro \\
--engine postgres \\
--engine-version 14.7 \\
--master-username construbot \\
--master-user-password strong-password \\
--allocated-storage 20 \\
--backup-retention-period 7 \\
--vpc-security-group-ids sg-xxxxx \\
--publicly-accessible
Actualizar .env:
DATABASE_URL=postgresql://construbot:password@construbot-db.abc123.us-east-1.rds.amazonaws.com:5432/construbot
Elimine postgres de docker-compose.yml.
ElastiCache Redis (opcional)#
aws elasticache create-cache-cluster \\
--cache-cluster-id construbot-redis \\
--engine redis \\
--cache-node-type cache.t3.micro \\
--num-cache-nodes 1 \\
--security-group-ids sg-xxxxx
Actualizar .env:
REDIS_URL=redis://construbot-redis.abc123.cache.amazonaws.com:6379/0
S3 para archivos multimedia#
# Create S3 bucket
aws s3 mb s3://construbot-media-your-domain
# Block public access (use signed URLs)
aws s3api put-public-access-block \\
--bucket construbot-media-your-domain \\
--public-access-block-configuration \\
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
# Create IAM user for S3 access
aws iam create-user --user-name construbot-s3-user
# Attach S3 policy
aws iam put-user-policy \\
--user-name construbot-s3-user \\
--policy-name S3Access \\
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": ["arn:aws:s3:::construbot-media-your-domain/*"]
}]
}'
# Create access keys
aws iam create-access-key --user-name construbot-s3-user
Actualizar .env:
USE_S3=True
AWS_ACCESS_KEY_ID=<access-key>
AWS_SECRET_ACCESS_KEY=<secret-key>
AWS_STORAGE_BUCKET_NAME=construbot-media-your-domain
Paso 7: automatizar el inicio#
Servicio Systemd#
Cree /etc/systemd/system/construbot.service:
[Unit]
Description=Construbot Docker Compose
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/construbot
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
[Install]
WantedBy=multi-user.target
Habilitar servicio:
sudo systemctl enable construbot
sudo systemctl start construbot
La aplicación ahora se inicia automáticamente al arrancar.
Paso 8: Monitoreo y Mantenimiento#
Monitoreo de CloudWatch#
Habilitar monitoreo detallado:
aws ec2 monitor-instances --instance-ids i-xxxxx
Crear alarmas de CloudWatch:
# CPU alarm
aws cloudwatch put-metric-alarm \\
--alarm-name construbot-high-cpu \\
--alarm-description "Alert when CPU > 80%" \\
--metric-name CPUUtilization \\
--namespace AWS/EC2 \\
--statistic Average \\
--period 300 \\
--evaluation-periods 2 \\
--threshold 80 \\
--comparison-operator GreaterThanThreshold \\
--dimensions Name=InstanceId,Value=i-xxxxx
Copias de seguridad automatizadas#
Crear script de respaldo /opt/construbot/scripts/backup.sh:
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BUCKET="s3://construbot-backups"
# Database backup (if using self-hosted)
docker compose exec -T postgres pg_dump -U construbot construbot | \\
gzip > /tmp/db_backup_$DATE.sql.gz
# Upload to S3
aws s3 cp /tmp/db_backup_$DATE.sql.gz $BUCKET/database/
# Cleanup
rm /tmp/db_backup_$DATE.sql.gz
Programar con cron:
# crontab -e
0 2 * * * /opt/construbot/scripts/backup.sh
Gestión de registros#
Enviar registros a CloudWatch:
# Install CloudWatch agent
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i amazon-cloudwatch-agent.deb
# Configure agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
Paso 9: Escalar#
Escalado vertical#
# Stop instance
aws ec2 stop-instances --instance-ids i-xxxxx
# Wait for stopped state
aws ec2 wait instance-stopped --instance-ids i-xxxxx
# Change instance type
aws ec2 modify-instance-attribute \\
--instance-id i-xxxxx \\
--instance-type "{\"Value\": \"t3.medium\"}"
# Start instance
aws ec2 start-instances --instance-ids i-xxxxx
Escala horizontal#
Para implementación de múltiples instancias:
Utilice el equilibrador de carga de aplicaciones (ALB)
Crear grupo de Auto Scaling
Utilice RDS para la base de datos (obligatorio)
Utilice ElastiCache para Redis (obligatorio)
Utilice S3 para archivos multimedia (obligatorio)
Esto va más allá del alcance de un solo servidor: considere usar ECS o EKS para la orquestación de contenedores.
Solución de problemas#
Instancia no accesible#
# Check instance status
aws ec2 describe-instance-status --instance-ids i-xxxxx
# Check security group
aws ec2 describe-security-groups --group-ids sg-xxxxx
# Verify Elastic IP association
aws ec2 describe-addresses
La aplicación no se inicia#
# SSH into instance
ssh -i ~/.ssh/your-key.pem ubuntu@<elastic-ip>
# Check Docker logs
cd /opt/construbot
docker compose logs
# Check service status
docker compose ps
Sin espacio en disco#
# Check disk usage
df -h
# Clean Docker
docker system prune -a -f
# Resize volume (AWS Console or CLI)
aws ec2 modify-volume --volume-id vol-xxxxx --size 50
Optimización de costos#
Reducir costos#
Utilice instancias reservadas: ahorre hasta un 75 % con un compromiso de 1 a 3 años
Instancias del tamaño adecuado: supervise y ajuste según el uso real
Utilice instancias puntuales: ahorre hasta un 90 % (para cargas de trabajo no críticas)
Habilitar niveles inteligentes de S3: optimización automática de costos
Configurar alertas de presupuesto - Supervisar el gasto
Costos mensuales estimados (us-east-1):
t3.small EC2 instance: $15-20
30 GB gp3 storage: $3
RDS db.t3.micro: $15
50 GB S3 storage: $1
Data transfer (100 GB): $9
--------------------------------
Total: $43-48/month
Ver también#
Lista de verificación de producción - Pre-deployment checklist
Docker Compose para producción - Docker Compose configuration
Variables de entorno - Environment setup
Archivos estáticos y multimedia - S3 configuration