Windows Server + VM + Docker + Odoo = 😚


A veces, muchas veces, quizá la mayoría de las veces, hay que trabajar con lo que se tiene y no con lo que se quiere. Es la eterna batalla entre lo que debería ser y lo que es, esa pizca de realidad, pero también de desafío que le da sentido a la vida, viéndolo de forma optimista, jaja. Generalmente se aplica a pequeñas y medianas empresas, donde su enfoque está en el área de marketing, finanzas o producción, y TI se encuentra en el sótano, en un pequeño escritorio, con una cafetera de los 90 como servidor.
Trabajaremos en un servidor HP Proliant ML110 G3 (del 2005!!!) con un procesador Xeon E31220 y 10gb de RAM, Windows Server 2022, el cual es un servidor de archivos, dominio y una pequeña base de datos MySQL.
Problema: El sistema que usan para las ventas es un programa muy básico que se ha quedado corto para la empresa. Es una aplicación hecha con WinDev que se conecta a la base de datos MySQL para registrar los pedidos, y ya; hoy en día se enfrentan a ordenes hechas a mano, para después pasarlos al sistema, entonces recae en pedidos entregados fuera de fechas, artículos erróneos, ordenes perdidas, no hay conocimiento certero de los márgenes y ni hablar de desiciones basadas en datos. A ver, si, es una pequeña empresa, en una pequeña ciudad, pero no es pretexto para no hacer las cosas bien, y lo resolveremos ;)
Tenemos la planta principal y dos sucursales, una de ellas en otra ciudad, por lo cual la comunicación y planeación es importante.
Material: El servidor viejito y un gran entusiasmo.
Plan: Crearemos una intranet conectado las sucursales mediante una VPN e implementaré el sistema Odoo en su versión Community: CRM, Inventario, Chat, Ordenes de Fabricación, Contabilidad, RRHH, y un largo etcétera. Es la primera vez que lo uso pero parece muy prometedor.
Usaremos Hyper-V, donde tendremos la Maquina Virtual (VM) corriendo Oracle Linux Server; no por algo en especial, gusto personal, me gusta el gestor de paquetes y que es solido como roca. Aquí tendremos la infra, fácil de mover en caso quieran actualizar el hardware pronto y la migración sea rápida, sin pausar el área de producción.
El sistema será usado por una media de 20 usuarios concurrentes aproximadamente.
Orquestaremos los servicios Odoo 18, PostgreSQL 15 y Nginx usando Docker y docker compose. El servidor host tiene dos tarjetas de red. Una tarjeta con su IP se quedará para el uso del servidor de dominio, dns, archivos y, de momento, la base de datos MySQL del programa feo ese. La segunda tarjeta la usaremos para nuestra VM. Usaremos el servidor DNS del dominio para apuntar a la IP de la VM, ex: odoo.dominio.local, para mayor placer gg.
Manos a la obra 💪🏿 ( iré al grano desde el inicio para no hacer este articulo infinito C: )
Instalar Hyper-V
La base de todo esto es nuestra maquina virtual, vamos a nuestro Administrador de Servidor → Administrar → Agregar roles y características. Seleccionamos Hyper-V si no lo tenemos instalado y seleccionamos siguiente siguiente siguiente siguiente… es buena idea reiniciar después si es posible.
Crear conmutador virtual (Hyper-V)
Ahora ya tenemos disponible nuestro Administrador de Hyper-V (virtmgmt.msc). Lo abrimos y, en el panel de la derecha, o en el menú acciones seleccionamos el Administrador de conmutadores virtuales. Aquí crearemos nuestra red WAN usando la segunda tarjeta de red. Seleccionan Nuevo conmutador de red virtual, Externo y seleccionan la tarjeta que quieran usar y el checkbox de abajo, Permitir que el sistema operativo de administración comparta …
Crear la Máquina Virtual
Ahora deben seleccionar el sistema operativo que deseen usar, como mencioné usaré Oracle Linux.
Ya con la imagen ISO descargada, en el Administrador de Hyper-V, en el panel de la derecha, o desde archivo daremos clic en Nuevo para crear nuestra nueva Máquina Virtual. Por eso le dan clic donde dice Maquina Virtual después de pucharle a Nuevo.
Le ponen un nombre bonito y, si quieren poner la VM en otra ubicación, seleccionan ahí donde la quieren, en mi caso en otra unidad ya que C:\ solo lo uso para el guindons.
En especificar la generación yo aun uso la 1, la otra me dio lata y pues, mejor bueno por conocido… jaja.
Asigné 4096 MB (4Gb) de memoria RAM, y seleccioné dinámica por si las dudas, total, quiero que al final toda la infraestructura de servicios corra en la VM, usando contenedores dentro, en su caso dependerá de sus requisitos y hardware disponible.
En Configurar funciones de red, en conexión eligen el conmutador que creamos antes WAN.
En Conectar disco duro virtual, pues solo ponen el Tamaño, que aquí si no importa tanto ya que crece dinámicamente, en mi caso puse 50 Gb y ya de ahí en adelante hasta donde llegue 😏
En opciones de instalación, seleccionan instalar desde CD de arranque, Archivo de imagen ISO y la seleccionan. Dan clic en finalizar.
Como sea todo esto se puede editar después, el tamaño del disco, la memoria asignada, la red, medios de instalación, agregar mas hardware, núcleos de CPU, y más.
Instalación del Sistema Operativo
Instalan el sistema operativo en la VM :v
Instalación y configuración de Docker y Docker Compose
Instalan y configuran Docker y Docker Compose en la VM 🤡
Odoo Time 🤩
Suponiendo que ya tienen su distribución de linux favorita instalada en la maquina virtual e instalaron Docker y Docker Compose iniciaremos con correr los contenedores usando nuestro archivo docker-compose.yml
Si todo ha ido bien hasta ahora deberían tener algo así:
Crearemos un directorio donde colocaremos nuestro proyecto, en mi caso dentro de la carpeta Infra y colocaremos nuestro archivo docker-compose.yml dentro para que haga de las suyas ahí 😈
mkdir -p ~/Infra/docker-compose/dc_odoo
El modo sencillo es instalar git en tu VM y hacer un git clone:
git clone https://github.com/rigelcarbajal/odoo-compose.git
Esto descargará un serie de archivos y directorios, bueno solo tres gg, los revisaremos:
# docker-compose.yml
services:
web:
image: odoo:18 # Puedes poner latest o cualquier otra versión
depends_on:
db:
condition: service_healthy
ports:
- "8069:8069"
- "8072:8072"
volumes:
- odoo-web-data:/var/lib/odoo
- ./config:/etc/odoo
- ./addons:/mnt/extra-addons
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8069"]
interval: 15s
timeout: 10s
retries: 5
restart: unless-stopped
networks:
- odoo-net
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
db:
image: postgres:15 # Es la version más compatible con odoo al momento
environment:
- POSTGRES_DB=postgres
- POSTGRES_PASSWORD=odoo
- POSTGRES_USER=odoo
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- odoo-db-data:/var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD", "pg_isready", "-U", "odoo"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- odoo-net
nginx: # ...
image: nginx:stable
depends_on:
- web
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/certs:/etc/nginx/certs
networks:
- odoo-net
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 15s
timeout: 5s
retries: 3
volumes:
odoo-web-data:
odoo-db-data:
networks:
odoo-net:
# config/odoo.conf
# Este es de la configuración de odoo
[options]
# Cambia el password, es el Master Password de Odoo / Configuración inicial web
admin_passwd = SuperPassword123
db_host = db
db_port = 5432
db_user = odoo
db_password = odoo
addons_path = /mnt/extra-addons
# Dependiendo del hardware de tu servidor modifica estos valores, estos son bajos
db_maxconn = 50
limit_memory_soft = 1536000000
limit_memory_hard = 3072000000
limit_time_cpu = 60
limit_time_real = 120
limit_request = 8192
max_cron_threads = 2
workers = 2
# Para el chat, pero esto es legado, actualmente usa websockets
longpolling_port = 8072
logfile = /var/log/odoo/odoo.log
logrotate = True
log_level = info
xmlrpc_port = 8069
# Por que usamos nginx
proxy_mode = True
# nginx/config.d/odoo.conf
# Esta configuración es del proxy de nginx, aquí esta usando puerto 80 ya que es -
# para una intranet, si lo quieres exponer debes ponerlo usando SSL/TLS usando -
# puerto 443 y tus certificados correspondientes
server {
listen 80;
server_name odoo.local;
access_log /var/log/nginx/odoo.access.log;
error_log /var/log/nginx/odoo.error.log;
location / {
proxy_pass http://web:8069;
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_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
}
# Legado / viejito, pero mejor no moverle
location /longpolling/ {
proxy_pass http://web:8072;
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";
}
# Este si es importante para que no se rompa el chat
location /websocket {
proxy_pass http://web:8072;
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";
}
# Este es para saber su estado usando docker ps
location /health {
return 200 "OK\n";
access_log off;
}
# Para optimizar un poco nomás ...
gzip on;
gzip_min_length 1000;
gzip_types text/plain application/xml application/json application/javascript text/css text/js;
}
Ya revisados los archivos anteriores, y viendo que tenga sentido para su caso especifico usaremos:
docker compose up -d
Para levantar los servicios, podemos corroborar que todo esta corriendo bien usando:
docker ps
Los tres contenedores dicen healthy, si no nos tocará (a ustedes xd) hacer un poco de troubleshooting para arreglarlo, pero en teoría está todo correcto …
… y debería poder ser accesible en la red local desde http://la_ip_del_servidor:8069 y comenzar a utilizarlo, pero esto se ve feito…
Configurando el DNS local
… imaginen que tienen un servidor DNS en su organización, en mi caso Active Directory con el nombre organizacion.local; aprovechemos para ponerlo como odoo.organizacion.local en lugar de la ip:puerto
Ejecutamos dnsmgmt.msc para abrir el Administrador de DNS, también se puede desde el Administrador de Servidor y Herramientas. Aquí ya estamos trabajando en nuestro host, en mi caso con Windows Server 2022 por si hay algún perdido por ahí.
Seleccionan su organización de Active Directory y en Zona de búsqueda directa nuevamente el nombre de su organización. En el panel derecho dan clic secundario y eligen Host nuevo (A o AAAA). En el cuadro gris, en Nombre ponen el que gusten, en mi caso odoo, es el subdominio; en Nombre de dominio completo solo se previsualiza como se verá. En IP la dirección de su servidor donde está corriendo Odoo, la IP de la maquina virtual, dependerá de su configuración, pueden usar en su VM:
ifconfig
# ó
ip a
para conocer su IP, OJO! quizá deban abrir el puerto 80 ó 443 en su Linux.
Con eso configurado ya pueden accesar a http://odoo.organizacion.local en su intranet.
Y ya quedó, dice no seguro por que no usa certificado SSL (http:80 y no https:443), si lo vas a exponer en internet si usa SSL obligatorio sin excusa :) (quizá más adelante, si se portan bien, suba como sería con certificado SSL).
Espero que sea de ayuda, bai 😄
Subscribe to my newsletter
Read articles from Rigel Carbajal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Rigel Carbajal
Rigel Carbajal
¡Hola! Soy Rigel, ingeniero en sistemas, amante de la tecnología, los datos y un buen café. 🚀 Siempre aprendiendo y listo para el próximo reto. 🤓