📌 Requisitos previos
- VPS con Ubuntu 24.04 (o similar)
- Al menos 4 GB de RAM (recomendado 8 GB)
- Docker y Docker Compose instalados
- Nginx y Certbot instalados en el host
- Un dominio o subdominio apuntando a la IP del VPS (en esta guía usamos
erp.tudominio.com)
1. Preparar el entorno
bash
mkdir -p ~/erpnext && cd ~/erpnext
2. Archivo de variables de entorno (.env)
Crea el archivo sin espacios alrededor del =:
bash
cat > .env << 'EOF' MYSQL_ROOT_PASSWORD=ContraseñaSegura123 ADMIN_PASSWORD=OtraContraseña456 SITE=erp.tudominio.com MAIL_FROM=erp@tudominio.com EOF
3. docker-compose.yml con configuración corregida de Redis
Copia este contenido exacto (ya incluye las variables correctas REDIS_CACHE, REDIS_QUEUE, REDIS_SOCKETIO):
yaml
services:
db:
image: mariadb:10.6
container_name: erpnext-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
volumes:
- db-data:/var/lib/mysql
networks:
- erp_network
redis-cache:
image: redis:7-alpine
container_name: erpnext-redis-cache
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- redis-cache-data:/data
networks:
- erp_network
redis-queue:
image: redis:7-alpine
container_name: erpnext-redis-queue
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- redis-queue-data:/data
networks:
- erp_network
erpnext:
image: frappe/erpnext:v15
container_name: erpnext-web
restart: unless-stopped
depends_on:
- db
- redis-cache
- redis-queue
environment:
- FRAPPE_DB_HOST=db
- FRAPPE_DB_PORT=3306
- FRAPPE_DB_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- REDIS_CACHE=redis://redis-cache:6379
- REDIS_QUEUE=redis://redis-queue:6379
- REDIS_SOCKETIO=redis://redis-cache:6379
- FRAPPE_SITE_NAME_HEADER=${SITE}
- FRAPPE_ADMIN_PASSWORD=${ADMIN_PASSWORD}
- FRAPPE_SMTP_SERVER=172.17.0.1 # Gateway del host hacia Docker
- FRAPPE_SMTP_PORT=25
- FRAPPE_SMTP_LOGIN=
- FRAPPE_SMTP_PASSWORD=
- FRAPPE_MAIL_FROM=${MAIL_FROM}
volumes:
- sites-data:/home/frappe/frappe-bench/sites
networks:
- erp_network
ports:
- "127.0.0.1:8000:8000"
# Workers y scheduler (necesarios)
erpnext-queue-short:
image: frappe/erpnext:v15
container_name: erpnext-queue-short
restart: unless-stopped
command: bench worker --queue short
depends_on:
- erpnext
environment:
- FRAPPE_DB_HOST=db
- FRAPPE_DB_PORT=3306
- FRAPPE_DB_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- REDIS_CACHE=redis://redis-cache:6379
- REDIS_QUEUE=redis://redis-queue:6379
- REDIS_SOCKETIO=redis://redis-cache:6379
volumes:
- sites-data:/home/frappe/frappe-bench/sites
networks:
- erp_network
erpnext-queue-long:
image: frappe/erpnext:v15
container_name: erpnext-queue-long
restart: unless-stopped
command: bench worker --queue long
depends_on:
- erpnext
environment:
- FRAPPE_DB_HOST=db
- FRAPPE_DB_PORT=3306
- FRAPPE_DB_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- REDIS_CACHE=redis://redis-cache:6379
- REDIS_QUEUE=redis://redis-queue:6379
- REDIS_SOCKETIO=redis://redis-cache:6379
volumes:
- sites-data:/home/frappe/frappe-bench/sites
networks:
- erp_network
erpnext-queue-default:
image: frappe/erpnext:v15
container_name: erpnext-queue-default
restart: unless-stopped
command: bench worker --queue default
depends_on:
- erpnext
environment:
- FRAPPE_DB_HOST=db
- FRAPPE_DB_PORT=3306
- FRAPPE_DB_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- REDIS_CACHE=redis://redis-cache:6379
- REDIS_QUEUE=redis://redis-queue:6379
- REDIS_SOCKETIO=redis://redis-cache:6379
volumes:
- sites-data:/home/frappe/frappe-bench/sites
networks:
- erp_network
erpnext-schedule:
image: frappe/erpnext:v15
container_name: erpnext-schedule
restart: unless-stopped
command: bench schedule
depends_on:
- erpnext
environment:
- FRAPPE_DB_HOST=db
- FRAPPE_DB_PORT=3306
- FRAPPE_DB_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- REDIS_CACHE=redis://redis-cache:6379
- REDIS_QUEUE=redis://redis-queue:6379
- REDIS_SOCKETIO=redis://redis-cache:6379
volumes:
- sites-data:/home/frappe/frappe-bench/sites
networks:
- erp_network
volumes:
db-data:
redis-cache-data:
redis-queue-data:
sites-data:
networks:
erp_network:
driver: bridge
4. Iniciar los servicios
bash
docker compose up -d
5. Crear el sitio de ERPNext
bash
source .env
docker exec -it erpnext-web bench new-site ${SITE} \
--mariadb-root-password "${MYSQL_ROOT_PASSWORD}" \
--admin-password "${ADMIN_PASSWORD}" \
--db-host db \
--install-app erpnext \
--set-default
6. Configurar el correo saliente
bash
docker exec -it erpnext-web bench set-config --global smtp_server 172.17.0.1
docker exec -it erpnext-web bench set-config --global smtp_port 25
docker exec -it erpnext-web bench set-config --global smtp_mail_from ${MAIL_FROM}
docker exec -it erpnext-web bench clear-cache
7. Forzar la contraseña del administrador
bash
docker exec -it erpnext-web bench set-admin-password 'TuContraseñaFinal'
8. Construir los activos estáticos (CSS/JS)
bash
docker exec -it erpnext-web bench --site ${SITE} build --force
9. Servir los estáticos con Nginx (solución robusta)
Los estáticos se copian del contenedor al host resolviendo enlaces simbólicos con tar -h:
bash
# Copiar archivos reales del contenedor al host sudo rm -rf /var/www/assets sudo docker exec erpnext-web tar -ch -C /home/frappe/frappe-bench/sites assets | sudo tar -x -C /var/www # Permisos para Nginx sudo chown -R www-data:www-data /var/www/assets sudo chmod -R a+rX /var/www/assets
10. Configurar Nginx como proxy inverso con SSL
Crea el archivo /etc/nginx/sites-available/erp:
nginx
server {
listen 80;
listen [::]:80;
server_name erp.tudominio.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name erp.tudominio.com;
ssl_certificate /etc/letsencrypt/live/erp.tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/erp.tudominio.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location /assets {
alias /var/www/assets;
expires max;
add_header Cache-Control "public, immutable";
}
location / {
proxy_pass http://127.0.0.1:8000;
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Habilita el sitio y obtén el certificado SSL:
bash
sudo ln -s /etc/nginx/sites-available/erp /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx sudo certbot --nginx -d erp.tudominio.com
11. Acceder
Abre https://erp.tudominio.com e inicia sesión con:
- Usuario: Administrator
- Contraseña: la que definiste en
ADMIN_PASSWORDo conset-admin-password
🔁 Actualizar los estáticos después de cada bench build
Cada vez que ejecutes bench build, los bundles CSS/JS cambian de nombre y deben copiarse nuevamente al host para que Nginx los sirva. Usa este script de dos pasos:
bash
# Paso 1: Copiar desde el contenedor al host sudo docker exec erpnext-web tar -ch -C /home/frappe/frappe-bench/sites assets | sudo tar -x -C /var/www # Paso 2: Ajustar permisos sudo chown -R www-data:www-data /var/www/assets sudo chmod -R a+rX /var/www/assets sudo systemctl reload nginx
✅ Resumen de puntos clave aprendidos
- Usa siempre
REDIS_CACHE,REDIS_QUEUE,REDIS_SOCKETIOcomo variables de entorno (noFRAPPE_REDIS_*). - El archivo
.envno debe tener espacios alrededor del=. - El backend de ERPNext en producción no sirve estáticos; deben servirse con Nginx (u otro servidor).
- Para copiar los estáticos al host resuelve los enlaces simbólicos con
tar -hodocker cpseguido de un ajuste, pero el métodotar -hes más limpio y directo. - Si al acceder ves la interfaz sin estilos, basta con ejecutar el paso de actualización de estáticos (punto 9 y el script del apartado anterior).
- La integración con n8n (pendiente) se hará mediante la API de ERPNext, usando la URL
http://erpnext-web:8000desde el contenedor de n8n si están en la misma red Docker.
Deja un comentario