Files
2026-08-28 10:11:11 -03:00

2407 lines
92 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<link rel="preconnect" href="https://d3js.org" crossorigin>
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="alternate icon" href="/favicon.ico">
<title>VPS Odoo Hosting 2026 | Odoo Expertos · EN</title>
<meta name="description" content="Complete guide de VPS para Odoo en 2026. Comparamos Hetzner, DigitalOcean, Vultr y Contabo. Incluye instalacion paso a paso, configuraci - VPS Odoo Hosting 2026 | EN">
<meta name="keywords" content="vps Odoo, servidor vps Odoo, hetzner Odoo, digitalocean Odoo, vultr Odoo, contabo Odoo, instalar Odoo vps, configurar servidor Odoo, optimizar Odoo vps">
<meta name="author" content="Dr. Equipo Odoo Expertos">
<meta name="robots" content="index, follow">
<meta name="language" content="es">
<link rel="canonical" href="https://www.odoo-expertos.com/Odoo-Hosting/vps-Odoo-Hosting-2026/">
<!-- Hreflang -->
<link rel="alternate" hreflang="en" href="https://www.odoo-expertos.com/Odoo-Hosting/vps-Odoo-Hosting-2026/" />
<link rel="alternate" hreflang="en" href="https://www.odoo-expertos.com/en/Odoo-Hosting/vps-Odoo-Hosting-2026/" />
<link rel="alternate" hreflang="de" href="https://www.odoo-expertos.com/de/Odoo-Hosting/vps-Odoo-Hosting-2026/" />
<link rel="alternate" hreflang="fr" href="https://www.odoo-expertos.com/fr/Odoo-Hosting/vps-Odoo-Hosting-2026/" />
<link rel="alternate" hreflang="x-default" href="https://www.odoo-expertos.com/Odoo-Hosting/vps-Odoo-Hosting-2026/" />
<!-- Open Graph -->
<meta property="og:title" content="VPS Odoo Hosting Guia 2026: Comparativa de Providers y Configuracion">
<meta property="og:description" content="Guia definitiva de VPS para Odoo. Comparamos Hetzner, DigitalOcean, Vultr y Contabo con precios, rendimiento y tutoriales de instalacion.">
<meta property="og:type" content="article">
<meta property="og:url" content="https://www.odoo-expertos.com/Odoo-Hosting/vps-Odoo-Hosting-2026/">
<meta property="og:image" content="https://www.odoo-expertos.com/images/vps-Odoo-Hosting-2026.jpg">
<meta property="og:site_name" content="Odoo Expertos">
<meta property="og:locale" content="es_ES">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="VPS Odoo Hosting Guia 2026: Comparativa Definitiva">
<meta name="twitter:description" content="Complete guide de VPS para Odoo. Comparamos los mejores Providers con instalacion y configuracion paso a paso.">
<!-- Schema.org Article -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "VPS Odoo Hosting Guia 2026: Comparativa y Configuracion Completa",
"description": "Complete guide de VPS para Odoo en 2026. Comparamos Hetzner, DigitalOcean, Vultr y Contabo con instalacion, configuracion, optimizacion y seguridad.",
"author": {
"@type": "Person",
"name": "Dr. Equipo Odoo Expertos",
"url": "https://www.odoo-expertos.com/autor/maria-elena-rodriguez/",
"jobTitle": "Senior ERP Systems Consultant"
},
"publisher": {
"@type": "Organization",
"name": "Odoo Expertos",
"logo": {
"@type": "ImageObject",
"url": "https://www.odoo-expertos.com/logo.png"
}
},
"datePublished": "2026-01-25",
"dateModified": "2026-01-25",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://www.odoo-expertos.com/Odoo-Hosting/vps-Odoo-Hosting-2026/"
},
"proficiencyLevel": "Intermediate",
"dependencies": "Ubuntu 22.04 LTS, PostgreSQL 16, Python 3.12"
}
</script>
<!-- HowTo Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "HowTo",
"name": "Como Instalar Odoo en un VPS",
"description": "Guia paso a paso para instalar y configurar Odoo 18 en un servidor VPS",
"totalTime": "PT45M",
"estimatedCost": {
"@type": "MonetaryAmount",
"currency": "EUR",
"value": "6-50"
},
"supply": [
{"@type": "HowToSupply", "name": "Servidor VPS con Ubuntu 22.04"},
{"@type": "HowToSupply", "name": "Dominio con DNS configurado"},
{"@type": "HowToSupply", "name": "Acceso SSH root"}
],
"tool": [
{"@type": "HowToTool", "name": "Terminal SSH"},
{"@type": "HowToTool", "name": "Editor de texto"}
],
"step": [
{
"@type": "HowToStep",
"position": 1,
"name": "Preparar el servidor",
"text": "Actualizar el sistema y crear usuario Odoo"
},
{
"@type": "HowToStep",
"position": 2,
"name": "Instalar dependencias",
"text": "Instalar PostgreSQL, Python y paquetes necesarios"
},
{
"@type": "HowToStep",
"position": 3,
"name": "Instalar Odoo",
"text": "Clonar repositorio y configurar Odoo"
},
{
"@type": "HowToStep",
"position": 4,
"name": "Configurar Nginx",
"text": "Configurar proxy inverso con SSL"
},
{
"@type": "HowToStep",
"position": 5,
"name": "Asegurar el servidor",
"text": "Configurar firewall y hardening de seguridad"
}
]
}
</script>
<!-- FAQ Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Cual es el mejor VPS para Odoo en 2026?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Para la mayoria de casos, Hetzner ofrece la mejor value for money con servidores en Europe. DigitalOcean es ideal Yes priorizas documentacion y facilidad de uso. Vultr destaca por su red global y Contabo por precios muy economicos."
}
},
{
"@type": "Question",
"name": "Cuanta RAM necesita Odoo en un VPS?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Para Odoo Community con 1-10 usuarios: 4GB RAM minimo. Para 10-25 usuarios: 8GB RAM. Para 25-50 usuarios: 16GB RAM. Odoo Enterprise requiere aproximadamente el doble de recursos."
}
},
{
"@type": "Question",
"name": "Es dificil instalar Odoo en un VPS?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Requiere conocimientos basicos de Linux y linea de comandos. Con esta guia, la instalacion toma aproximadamente 45 minutos. Yes No tienes experiencia tecnica, considera usar Hosting gestionado."
}
},
{
"@type": "Question",
"name": "Cuanto cuesta un VPS para Odoo mensualmente?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Los precios varian desde 6 EUR/month (Contabo, recursos basicos) hasta 50+ EUR/month para servidores de alto rendimiento. El promedio para una PYME es 15-30 EUR/month."
}
},
{
"@type": "Question",
"name": "Puedo migrar de Odoo.sh a un VPS propio?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, es posible migrar exportando la base de datos PostgreSQL y el filestore. Sin embargo, perderas actualizaciones automaticas y soporte oficial. La migracion requiere conocimientos tecnicos avanzados."
}
},
{
"@type": "Question",
"name": "Como hacer backup de Odoo en un VPS?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Debes hacer backup de: 1) Base de datos PostgreSQL con pg_dump, 2) Directorio filestore con los archivos adjuntos, 3) Archivo de configuracion Odoo.conf. Recomendamos backups diarios automatizados con retencion de 30 dias."
}
}
]
}
</script>
<!-- Product Comparison Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ItemList",
"name": "Mejores Providers VPS para Odoo 2026",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"item": {
"@type": "Product",
"name": "Hetzner Cloud",
"description": "VPS de alto rendimiento con excellent value for money en Europe",
"offers": {
"@type": "Offer",
"price": "4.51",
"priceCurrency": "EUR"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "2847"
}
}
},
{
"@type": "ListItem",
"position": 2,
"item": {
"@type": "Product",
"name": "DigitalOcean Droplets",
"description": "VPS con excellent documentacion y Community activa",
"offers": {
"@type": "Offer",
"price": "6",
"priceCurrency": "USD"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.6",
"reviewCount": "5234"
}
}
},
{
"@type": "ListItem",
"position": 3,
"item": {
"@type": "Product",
"name": "Vultr Cloud Compute",
"description": "VPS con red global de 32 ubicaciones",
"offers": {
"@type": "Offer",
"price": "6",
"priceCurrency": "USD"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.5",
"reviewCount": "3156"
}
}
},
{
"@type": "ListItem",
"position": 4,
"item": {
"@type": "Product",
"name": "Contabo VPS",
"description": "VPS economico con recursos generosos",
"offers": {
"@type": "Offer",
"price": "5.99",
"priceCurrency": "EUR"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.1",
"reviewCount": "1823"
}
}
}
]
}
</script>
<!-- BreadcrumbList Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://www.odoo-expertos.com/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Odoo Hosting",
"item": "https://www.odoo-expertos.com/Odoo-Hosting/"
},
{
"@type": "ListItem",
"position": 3,
"name": "VPS Odoo Hosting 2026",
"item": "https://www.odoo-expertos.com/Odoo-Hosting/vps-Odoo-Hosting-2026/"
}
]
}
</script>
<link rel="stylesheet" href="/css/main.min.css">
<style>
.pillar-hero {
background: linear-gradient(135deg, #1a1a1a 0%, #2a2a2a 50%, #1a1a1a 100%);
padding: 4rem 2rem;
text-align: center;
border-bottom: 3px solid #FF6B35;
position: relative;
overflow: hidden;
}
.pillar-hero::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(ellipse at center, rgba(255,107,53,0.15) 0%, transparent 70%);
pointer-events: none;
}
.pillar-hero h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
color: #FF6B35;
margin-bottom: 1rem;
line-height: 1.2;
position: relative;
}
.pillar-subtitle {
font-size: 1.3rem;
color: #b0b0b0;
max-width: 800px;
margin: 0 auto 2rem;
}
.pillar-meta {
display: flex;
justify-content: center;
gap: 2rem;
flex-wrap: wrap;
font-size: 0.9rem;
color: #888;
}
.pillar-meta span {
display: flex;
align-items: center;
gap: 0.5rem;
}
.quick-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 1.5rem;
padding: 2rem;
background: #2a2a2a;
border-radius: 12px;
margin: 2rem 0;
}
.stat-card {
text-align: center;
padding: 1.5rem;
background: rgba(255,107,53,0.1);
border-radius: 8px;
border: 1px solid rgba(255,107,53,0.2);
transition: transform 0.3s ease, border-color 0.3s ease;
}
.stat-card:hover {
transform: translateY(-5px);
border-color: #FF6B35;
}
.stat-number {
font-size: 2.5rem;
font-weight: 700;
color: #FF6B35;
display: block;
}
.stat-label {
color: #b0b0b0;
font-size: 0.9rem;
margin-top: 0.5rem;
}
.toc {
background: #2a2a2a;
border: 2px solid #FF6B35;
border-radius: 12px;
padding: 2rem;
margin: 2rem 0;
}
.toc h2 {
color: #FF6B35;
margin-bottom: 1rem;
font-size: 1.5rem;
}
.toc-list {
list-style: none;
padding: 0;
columns: 2;
column-gap: 2rem;
}
.toc-list li {
margin-bottom: 0.75rem;
break-inside: avoid;
}
.toc-list a {
color: #e0e0e0;
text-decoration: none;
display: flex;
align-items: center;
gap: 0.5rem;
transition: color 0.3s ease;
}
.toc-list a:hover {
color: #FF6B35;
}
.toc-list a::before {
content: '->';
color: #FF6B35;
}
.content-section {
margin: 3rem 0;
}
.content-section h2 {
color: #FF8A50;
margin-bottom: 1.5rem;
padding-bottom: 0.5rem;
border-bottom: 2px solid rgba(255,107,53,0.3);
}
.content-section h3 {
color: #FFB74D;
margin: 2rem 0 1rem;
}
.content-section h4 {
color: #FFC107;
margin: 1.5rem 0 0.75rem;
}
.chart-section {
margin: 3rem 0;
padding: 2rem;
background: #2a2a2a;
border-radius: 12px;
}
.chart-section h3 {
color: #FF8A50;
margin-bottom: 1rem;
}
.chart-container {
width: 100%;
min-height: 400px;
position: relative;
}
.comparison-table {
width: 100%;
border-collapse: collapse;
margin: 2rem 0;
background: #2a2a2a;
border-radius: 12px;
overflow: hidden;
}
.comparison-table th,
.comparison-table td {
padding: 1rem;
text-align: left;
border-bottom: 1px solid #3a3a3a;
}
.comparison-table th {
background: rgba(255,107,53,0.2);
color: #FF6B35;
font-weight: 600;
}
.comparison-table tr:hover {
background: rgba(255,107,53,0.05);
}
.comparison-table .check {
color: #4CAF50;
font-weight: bold;
}
.comparison-table .cross {
color: #f44336;
}
.provider-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.provider-card {
background: #2a2a2a;
border-radius: 12px;
padding: 1.5rem;
border: 1px solid rgba(255,107,53,0.2);
transition: transform 0.3s ease, border-color 0.3s ease;
}
.provider-card:hover {
transform: translateY(-5px);
border-color: #FF6B35;
}
.provider-card.featured {
border-color: #FF6B35;
background: linear-gradient(135deg, rgba(255,107,53,0.15) 0%, #2a2a2a 100%);
position: relative;
}
.provider-card .badge {
display: inline-block;
padding: 0.25rem 0.75rem;
background: #FF6B35;
color: #fff;
border-radius: 20px;
font-size: 0.8rem;
margin-bottom: 1rem;
}
.provider-card h4 {
color: #fff;
margin-bottom: 0.5rem;
font-size: 1.3rem;
}
.provider-card .price {
font-size: 2rem;
color: #FF6B35;
font-weight: 700;
}
.provider-card .price-period {
color: #888;
font-size: 0.9rem;
}
.provider-card ul {
list-style: none;
padding: 0;
margin: 1rem 0;
}
.provider-card li {
padding: 0.5rem 0;
border-bottom: 1px solid #3a3a3a;
display: flex;
align-items: center;
gap: 0.5rem;
color: #b0b0b0;
}
.provider-card li::before {
content: 'OK';
color: #4CAF50;
font-weight: bold;
font-size: 0.8rem;
}
.provider-card .cta-btn {
display: block;
text-align: center;
padding: 0.75rem 1.5rem;
background: #FF6B35;
color: #fff;
border-radius: 8px;
text-decoration: none;
font-weight: 600;
transition: background 0.3s ease, transform 0.3s ease;
margin-top: 1rem;
}
.provider-card .cta-btn:hover {
background: #FF8A50;
transform: scale(1.02);
}
.code-block {
background: #1a1a1a;
border: 1px solid #3a3a3a;
border-radius: 8px;
padding: 1.5rem;
margin: 1.5rem 0;
overflow-x: auto;
font-family: 'Fira Code', 'Courier New', monospace;
font-size: 0.9rem;
line-height: 1.6;
}
.code-block code {
color: #e0e0e0;
}
.code-block .comment {
color: #6a9955;
}
.code-block .command {
color: #FF6B35;
}
.code-block .variable {
color: #9CDCFE;
}
.code-block .string {
color: #CE9178;
}
.step-list {
counter-reset: step-counter;
list-style: none;
padding: 0;
}
.step-list li {
counter-increment: step-counter;
position: relative;
padding-left: 3.5rem;
margin-bottom: 1.5rem;
padding-bottom: 1.5rem;
border-bottom: 1px solid #3a3a3a;
}
.step-list li::before {
content: counter(step-counter);
position: absolute;
left: 0;
top: 0;
width: 2.5rem;
height: 2.5rem;
background: #FF6B35;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
color: #fff;
}
.step-list li h4 {
color: #FFB74D;
margin: 0 0 0.5rem 0;
}
.warning-box {
background: rgba(255, 193, 7, 0.1);
border-left: 4px solid #FFC107;
padding: 1.5rem;
margin: 2rem 0;
border-radius: 0 8px 8px 0;
}
.warning-box h4 {
color: #FFC107;
margin: 0 0 0.5rem 0;
}
.success-box {
background: rgba(76, 175, 80, 0.1);
border-left: 4px solid #4CAF50;
padding: 1.5rem;
margin: 2rem 0;
border-radius: 0 8px 8px 0;
}
.success-box h4 {
color: #4CAF50;
margin: 0 0 0.5rem 0;
}
.info-box {
background: rgba(33, 150, 243, 0.1);
border-left: 4px solid #2196F3;
padding: 1.5rem;
margin: 2rem 0;
border-radius: 0 8px 8px 0;
}
.info-box h4 {
color: #2196F3;
margin: 0 0 0.5rem 0;
}
.faq-section {
margin: 3rem 0;
}
.faq-item {
background: #2a2a2a;
border-radius: 8px;
margin-bottom: 1rem;
overflow: hidden;
}
.faq-question {
padding: 1.25rem;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
color: #fff;
font-weight: 500;
transition: background 0.3s ease;
}
.faq-question:hover {
background: rgba(255,107,53,0.1);
}
.faq-question::after {
content: '+';
font-size: 1.5rem;
color: #FF6B35;
transition: transform 0.3s ease;
}
.faq-item.open .faq-question::after {
transform: rotate(45deg);
}
.faq-answer {
padding: 0 1.25rem;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease, padding 0.3s ease;
color: #b0b0b0;
}
.faq-item.open .faq-answer {
padding: 0 1.25rem 1.25rem;
max-height: 500px;
}
.cta-banner {
background: linear-gradient(135deg, rgba(255,107,53,0.2) 0%, rgba(255,138,80,0.1) 100%);
border: 2px solid rgba(255,107,53,0.5);
border-radius: 12px;
padding: 2.5rem;
text-align: center;
margin: 3rem 0;
}
.cta-banner h3 {
color: #FF6B35;
margin-bottom: 1rem;
font-size: 1.8rem;
}
.cta-banner p {
margin-bottom: 1.5rem;
color: #b0b0b0;
font-size: 1.1rem;
}
.cta-banner .cta-btn {
display: inline-block;
padding: 1rem 2.5rem;
background: #FF6B35;
color: #fff;
border-radius: 8px;
text-decoration: none;
font-weight: 600;
font-size: 1.1rem;
transition: background 0.3s ease, transform 0.3s ease;
}
.cta-banner .cta-btn:hover {
background: #FF8A50;
transform: scale(1.05);
}
.highlight-box {
background: linear-gradient(135deg, rgba(255,107,53,0.1) 0%, rgba(255,138,80,0.05) 100%);
border-left: 4px solid #FF6B35;
padding: 1.5rem;
margin: 2rem 0;
border-radius: 0 8px 8px 0;
}
.highlight-box h4 {
color: #FF6B35;
margin-bottom: 0.5rem;
}
.pros-cons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
margin: 1.5rem 0;
}
.pros, .cons {
padding: 1.5rem;
border-radius: 8px;
}
.pros {
background: rgba(76, 175, 80, 0.1);
border: 1px solid rgba(76, 175, 80, 0.3);
}
.cons {
background: rgba(244, 67, 54, 0.1);
border: 1px solid rgba(244, 67, 54, 0.3);
}
.pros h4 {
color: #4CAF50;
margin-bottom: 1rem;
}
.cons h4 {
color: #f44336;
margin-bottom: 1rem;
}
.pros ul, .cons ul {
list-style: none;
padding: 0;
margin: 0;
}
.pros li::before {
content: '[OK] ';
color: #4CAF50;
}
.cons li::before {
content: '[X] ';
color: #f44336;
}
.d3-tooltip {
position: absolute;
background: rgba(0,0,0,0.95);
color: #fff;
padding: 0.75rem 1rem;
border-radius: 8px;
font-size: 0.9rem;
pointer-events: none;
z-index: 100;
max-width: 280px;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
border: 1px solid rgba(255,107,53,0.3);
}
.d3-tooltip strong {
color: #FF6B35;
}
.config-tabs {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
}
.config-tab {
padding: 0.75rem 1.5rem;
background: #3a3a3a;
border: none;
border-radius: 8px 8px 0 0;
color: #b0b0b0;
cursor: pointer;
transition: all 0.3s ease;
}
.config-tab.active {
background: #FF6B35;
color: #fff;
}
.config-content {
display: none;
}
.config-content.active {
display: block;
}
.fade-in {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.fade-in.visible {
opacity: 1;
transform: translateY(0);
}
@media (max-width: 768px) {
.toc-list {
columns: 1;
}
.pillar-meta {
flex-direction: column;
gap: 0.5rem;
}
.chart-container {
min-height: 300px;
}
.pros-cons {
grid-template-columns: 1fr;
}
.provider-grid {
grid-template-columns: 1fr;
}
.config-tabs {
flex-wrap: wrap;
}
}
</style>
</head>
<body>
<div id="header"><header class="site-header"><nav class="navbar"><div class="container"><div class="nav-brand"><a href="/en/" class="logo"><span class="logo-text">Odoo Expertos</span></a></div><button class="nav-toggle" aria-label="Toggle navigation"><span></span><span></span><span></span></button><div class="nav-menu"><ul class="nav-list"><li><a href="/en/">Home</a></li><li><a href="/en/odoo/">Odoo</a></li><li><a href="/en/odoo-ia/">Odoo AI</a></li><li><a href="/en/odoo-hosting/">Odoo Hosting</a></li><li><a href="/en/mapa-del-sitio/">Sitemap</a></li></ul></div></div></nav></header></div><button class="nav-toggle" aria-label="Toggle navigation"><span></span><span></span><span></span></button><div class="nav-menu"><ul class="nav-list"><li><a href="/en/">Home</a></li><li><a href="/en/odoo/">Odoo</a></li><li><a href="/en/odoo-ia/">Odoo AI</a></li><li><a href="/en/odoo-hosting/">Odoo Hosting</a></li><li><a href="/en/mapa-del-sitio/">Sitemap</a></li></ul></div></div></nav></header></div>
<!-- Breadcrumbs -->
<nav class="breadcrumbs">
<div class="container">
<ol class="breadcrumb-list" itemscope itemtype="https://schema.org/BreadcrumbList">
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a itemprop="item" href="/"><span itemprop="name">Home</span></a>
<span itemprop="position" style="display:none">1</span>
</li>
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a itemprop="item" href="/Odoo-Hosting/"><span itemprop="name">Odoo Hosting</span></a>
<span itemprop="position" style="display:none">2</span>
</li>
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<span itemprop="name">VPS Odoo Hosting 2026</span>
<span itemprop="position" style="display:none">3</span>
</li>
</ol>
</div>
</nav>
<!-- Hero Section -->
<section class="pillar-hero">
<div class="container">
<h1>VPS Odoo Hosting Guia 2026: Instalacion y Configuracion Completa</h1>
<p class="pillar-subtitle">Guia tecnica definitiva para instalar Odoo en un VPS. Comparamos Hetzner, DigitalOcean, Vultr y Contabo con instrucciones paso a paso, optimizacion de rendimiento y hardening de seguridad.</p>
<div class="pillar-meta">
<span>Published: 25 January 2026</span>
<span>Updated: 25 January 2026</span>
<span>30 min read</span>
<span>Dr. Equipo Odoo Expertos</span>
</div>
</div>
</section>
<main class="container">
<!-- Quick Stats -->
<section class="quick-stats fade-in">
<div class="stat-card">
<span class="stat-number">4</span>
<span class="stat-label">Providers Analizados</span>
</div>
<div class="stat-card">
<span class="stat-number">4.51EUR</span>
<span class="stat-label">Minimum Price/month</span>
</div>
<div class="stat-card">
<span class="stat-number">45min</span>
<span class="stat-label">Tiempo Instalacion</span>
</div>
<div class="stat-card">
<span class="stat-number">99.9%</span>
<span class="stat-label">Uptime Garantizado</span>
</div>
<div class="stat-card">
<span class="stat-number">32+</span>
<span class="stat-label">Ubicaciones Globales</span>
</div>
</section>
<!-- Table of Contents -->
<nav class="toc fade-in">
<h2>Contents of This Guide</h2>
<ol class="toc-list">
<li><a href="#introduccion">Por que Elegir VPS para Odoo</a></li>
<li><a href="#comparativa-vps">Comparativa de Providers VPS</a></li>
<li><a href="#grafico-comparacion">Grafico: Precio vs Rendimiento</a></li>
<li><a href="#sizing-guide">Guia de Dimensionamiento</a></li>
<li><a href="#decision-tree">Interactive Decision Tree</a></li>
<li><a href="#instalacion">Instalacion Paso a Paso</a></li>
<li><a href="#configuracion">Configuracion del Servidor</a></li>
<li><a href="#optimizacion">Optimizacion de Rendimiento</a></li>
<li><a href="#seguridad">Hardening de Seguridad</a></li>
<li><a href="#backups">Estrategia de Backups</a></li>
<li><a href="#faq">Preguntas Frecuentes</a></li>
</ol>
</nav>
<!-- Introduction -->
<section id="introduccion" class="content-section fade-in">
<h2>Por que Elegir VPS para Odoo en 2026</h2>
<p>Un Servidor Virtual Privado (VPS) representa el equilibrio perfecto entre el control Full de un servidor dedicado y la accesibilidad economica del Hosting compartido. Para Odoo, un VPS ofrece la flexibilidad necesaria para personalizar cada aspecto del entorno de ejecucion, desde la version de Python hasta la configuracion de PostgreSQL.</p>
<p>En 2026, los Providers de VPS han evolucionado significativamente, ofreciendo almacenamiento NVMe ultrarapido, redes de baja latencia y herramientas de gestion simplificadas. Esto hace que desplegar Odoo en un VPS sea mas accesible que nunca, incluso para equipos con conocimientos tecnicos intermedios.</p>
<div class="highlight-box">
<h4>Resumen Ejecutivo</h4>
<p>Para la mayoria de implementaciones de Odoo, recomendamos <strong>Hetzner Cloud</strong> por su excellent relacion precio-rendimiento en Europe. Yes tu audiencia principal esta en America, considera <strong>DigitalOcean</strong> o <strong>Vultr</strong> por su presencia geografica. <strong>Contabo</strong> es ideal para presupuestos muy ajustados donde el rendimiento No es critico.</p>
</div>
<h3>Ventajas de VPS sobre Hosting Gestionado</h3>
<div class="pros-cons">
<div class="pros">
<h4>Ventajas del VPS</h4>
<ul>
<li>Control Full sobre el servidor</li>
<li>Sin limite de usuarios</li>
<li>Personalizacion completa</li>
<li>Coste fijo predecible</li>
<li>Instalacion de modulos sin restricciones</li>
<li>Acceso root completo</li>
</ul>
</div>
<div class="cons">
<h4>Desventajas del VPS</h4>
<ul>
<li>Requiere conocimientos tecnicos</li>
<li>Responsabilidad de mantenimiento</li>
<li>Configuracion Manual de seguridad</li>
<li>Sin soporte Odoo incluido</li>
<li>Backups bajo tu responsabilidad</li>
<li>Tiempo de administracion</li>
</ul>
</div>
</div>
<h3>Cuando No Elegir VPS</h3>
<p>Un VPS No es la mejor opcion Yes:</p>
<ul>
<li>No tienes experiencia con Linux y linea de comandos</li>
<li>Necesitas soporte tecnico especializado en Odoo</li>
<li>Prefieres actualizaciones automaticas gestionadas</li>
<li>Tu tiempo es mas valioso que el ahorro en Hosting</li>
<li>Requieres SLA garantizado con compensacion</li>
</ul>
<p>En estos casos, considera <a href="/Odoo-Hosting/mejor-Hosting-Odoo-2026/">Hosting gestionado</a> como Odoo4projects u Odoo.sh.</p>
</section>
<!-- Provider Comparison -->
<section id="comparativa-vps" class="content-section fade-in">
<h2>Comparativa de Providers VPS para Odoo</h2>
<p>Analizamos los cuatro Providers VPS mas populares para Odoo, evaluando precio, rendimiento, ubicaciones y caracteristicas especificas para cargas de trabajo ERP.</p>
<div style="overflow-x: auto;">
<table class="comparison-table">
<thead>
<tr>
<th>Proveedor</th>
<th>Plan Minimo Odoo</th>
<th>RAM</th>
<th>CPU</th>
<th>SSD</th>
<th>Ubicaciones</th>
<th>Rating</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Hetzner Cloud</strong></td>
<td>7.05EUR/month (CX22)</td>
<td>4 GB</td>
<td>2 vCPU</td>
<td>40 GB NVMe</td>
<td>5 (EU/US)</td>
<td>4.8/5</td>
</tr>
<tr>
<td><strong>DigitalOcean</strong></td>
<td>$24/month (4GB)</td>
<td>4 GB</td>
<td>2 vCPU</td>
<td>80 GB SSD</td>
<td>15</td>
<td>4.6/5</td>
</tr>
<tr>
<td><strong>Vultr</strong></td>
<td>$24/month (4GB)</td>
<td>4 GB</td>
<td>2 vCPU</td>
<td>100 GB NVMe</td>
<td>32</td>
<td>4.5/5</td>
</tr>
<tr>
<td><strong>Contabo</strong></td>
<td>5.99EUR/month (VPS S)</td>
<td>8 GB</td>
<td>4 vCPU</td>
<td>200 GB SSD</td>
<td>6</td>
<td>4.1/5</td>
</tr>
</tbody>
</table>
</div>
<!-- Provider Cards -->
<div class="provider-grid">
<!-- Hetzner -->
<div class="provider-card featured">
<span class="badge">Recommended</span>
<h4>Hetzner Cloud</h4>
<p class="price">7.05EUR<span class="price-period">/mes (CX22)</span></p>
<ul>
<li>Mejor rendimiento por euro en Europe</li>
<li>Almacenamiento NVMe ultrarapido</li>
<li>Centros de datos en Alemania y Finlandia</li>
<li>Nueva ubicacion en EE.UU. (Ashburn)</li>
<li>API completa y bien documentada</li>
<li>Snapshots y backups automaticos</li>
<li>IPv6 nativo incluido</li>
</ul>
<div class="pros-cons">
<div class="pros">
<h4>Ventajas</h4>
<ul>
<li>Precio imbatible en Europe</li>
<li>excellent rendimiento I/O</li>
<li>Facturacion por hora</li>
</ul>
</div>
<div class="cons">
<h4>Limitations</h4>
<ul>
<li>Soporte solo en ingles/aleman</li>
<li>Pocas ubicaciones fuera de Europe</li>
</ul>
</div>
</div>
<a href="https://hetzner.cloud" class="cta-btn" target="_blank" rel="noopener">Ver Planes Hetzner</a>
</div>
<!-- DigitalOcean -->
<div class="provider-card">
<h4>DigitalOcean</h4>
<p class="price">$24<span class="price-period">/mes (4GB Droplet)</span></p>
<ul>
<li>Documentacion excepcional</li>
<li>Community muy activa</li>
<li>Marketplace con apps preconfiguradas</li>
<li>15 ubicaciones globales</li>
<li>Panel de control intuitivo</li>
<li>Monitoreo integrado</li>
<li>$200 credito para nuevos usuarios</li>
</ul>
<a href="https://digitalocean.com" class="cta-btn" target="_blank" rel="noopener">Ver Planes DO</a>
</div>
<!-- Vultr -->
<div class="provider-card">
<h4>Vultr</h4>
<p class="price">$24<span class="price-period">/mes (4GB Cloud)</span></p>
<ul>
<li>32 ubicaciones en todo el mundo</li>
<li>Almacenamiento NVMe en todos los planes</li>
<li>Bare metal disponible</li>
<li>Kubernetes gestionado</li>
<li>excellent latencia global</li>
<li>Facturacion por hora</li>
<li>$250 credito promocional</li>
</ul>
<a href="https://vultr.com" class="cta-btn" target="_blank" rel="noopener">Ver Planes Vultr</a>
</div>
<!-- Contabo -->
<div class="provider-card">
<span class="badge">Economico</span>
<h4>Contabo</h4>
<p class="price">5.99EUR<span class="price-period">/mes (VPS S)</span></p>
<ul>
<li>Recursos muy generosos por precio</li>
<li>8 GB RAM en plan basico</li>
<li>200 GB SSD incluidos</li>
<li>Sin limite de trafico</li>
<li>Centros de datos en EU/US/Asia</li>
<li>Snapshots opcionales</li>
</ul>
<div class="warning-box">
<h4>Nota sobre Contabo</h4>
<p>Contabo ofrece excelentes recursos por precio, pero el rendimiento puede ser inferior a otros Providers debido a overselling. Recommended para desarrollo o proyectos No criticos.</p>
</div>
<a href="https://contabo.com" class="cta-btn" target="_blank" rel="noopener">Ver Planes Contabo</a>
</div>
</div>
</section>
<!-- D3.js Comparison Chart -->
<section class="chart-section fade-in">
<h3 id="grafico-comparacion">Comparativa Visual: Precio vs Rendimiento</h3>
<p>Este grafico interactivo compara los Providers VPS en terminos de precio mensual frente a puntuacion de rendimiento. El tamano del circulo indica la cantidad de ubicaciones disponibles.</p>
<div class="chart-container" id="vps-scatter-chart"></div>
</section>
<!-- Sizing Guide -->
<section id="sizing-guide" class="content-section fade-in">
<h2>Guia de Dimensionamiento: Que VPS Necesitas</h2>
<p>El dimensionamiento correcto del servidor es crucial para el rendimiento de Odoo. Un servidor subdimensionado causara lentitud y frustracion, mientras que uno sobredimensionado desperdicia recursos.</p>
<h3>Regla General de Dimensionamiento</h3>
<div class="info-box">
<h4>Formula Basic</h4>
<p><strong>RAM necesaria = 2GB base + (0.3GB x usuarios simultaneos)</strong></p>
<p><strong>Workers = (CPU cores x 2) + 1</strong></p>
<p><strong>Almacenamiento = 20GB base + (2GB x usuarios totales) + espacio filestore</strong></p>
</div>
<table class="comparison-table">
<thead>
<tr>
<th>Escenario</th>
<th>Usuarios Simultaneos</th>
<th>RAM Minima</th>
<th>CPU</th>
<th>Almacenamiento</th>
<th>Plan Recommended</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Desarrollo/Pruebas</strong></td>
<td>1-3</td>
<td>2 GB</td>
<td>1 vCPU</td>
<td>20 GB</td>
<td>Hetzner CX11 (3.29EUR)</td>
</tr>
<tr>
<td><strong>Startup Pequena</strong></td>
<td>5-10</td>
<td>4 GB</td>
<td>2 vCPU</td>
<td>40 GB</td>
<td>Hetzner CX22 (7.05EUR)</td>
</tr>
<tr>
<td><strong>PYME</strong></td>
<td>10-25</td>
<td>8 GB</td>
<td>4 vCPU</td>
<td>80 GB</td>
<td>Hetzner CX32 (13.10EUR)</td>
</tr>
<tr>
<td><strong>Empresa Mediana</strong></td>
<td>25-50</td>
<td>16 GB</td>
<td>8 vCPU</td>
<td>160 GB</td>
<td>Hetzner CX42 (25.40EUR)</td>
</tr>
<tr>
<td><strong>Enterprise</strong></td>
<td>50-100+</td>
<td>32 GB+</td>
<td>16 vCPU+</td>
<td>320 GB+</td>
<td>Hetzner CX52 (49.90EUR)</td>
</tr>
</tbody>
</table>
<h3>Consideraciones Adicionales</h3>
<ul>
<li><strong>Odoo Enterprise:</strong> Requiere aproximadamente 50% mas de RAM que Community</li>
<li><strong>Muchos modulos:</strong> Cada modulo adicional consume memoria. Con 20+ modulos, aumenta RAM un 25%</li>
<li><strong>Integraciones API:</strong> Yes usas integraciones intensivas, considera mas CPU</li>
<li><strong>Filestore grande:</strong> Archivos adjuntos y documentos pueden requerir mucho espacio</li>
<li><strong>PostgreSQL separado:</strong> Para cargas altas, considera separar la base de datos en otro servidor</li>
</ul>
</section>
<!-- D3.js Decision Tree -->
<section class="chart-section fade-in">
<h3 id="decision-tree">Arbol de Decision: Elige tu VPS</h3>
<p>Navega por este arbol interactivo para encontrar el proveedor VPS ideal segun tus necesidades especificas.</p>
<div class="chart-container" id="vps-decision-tree"></div>
</section>
<!-- Installation Guide -->
<section id="instalacion" class="content-section fade-in">
<h2>Instalacion de Odoo 18 en VPS: Guia Paso a Paso</h2>
<p>Esta guia asume que estas usando Ubuntu 22.04 LTS o 24.04 LTS. Las instrucciones son validas para cualquier proveedor VPS.</p>
<div class="warning-box">
<h4>Antes de Empezar</h4>
<p>Asegurate de tener: acceso SSH root a tu VPS, un dominio apuntando a la IP del servidor, y aproximadamente 45 minutos de tiempo.</p>
</div>
<ol class="step-list">
<li>
<h4>Actualizar el Sistema y Crear Usuario</h4>
<p>Primero, actualiza todos los paquetes y crea un usuario dedicado para Odoo:</p>
<div class="code-block">
<code>
<span class="comment"># Actualizar sistema</span>
<span class="command">sudo apt update && sudo apt upgrade -y</span>
<span class="comment"># Crear usuario Odoo</span>
<span class="command">sudo adduser --system --home=/opt/Odoo --group Odoo</span>
<span class="comment"># Instalar dependencias basicas</span>
<span class="command">sudo apt install -y git python3-pip python3-dev python3-venv \
libxml2-dev libxslt1-dev zlib1g-dev libsasl2-dev \
libldap2-dev build-essential libssl-dev libffi-dev \
libmysqlclient-dev libjpeg-dev libpq-dev libjpeg8-dev \
liblcms2-dev libblas-dev libatlas-base-dev npm</span>
</code>
</div>
</li>
<li>
<h4>Instalar PostgreSQL 16</h4>
<p>Odoo requiere PostgreSQL como base de datos. Instalamos la version 16 para mejor rendimiento:</p>
<div class="code-block">
<code>
<span class="comment"># Agregar repositorio oficial de PostgreSQL</span>
<span class="command">sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'</span>
<span class="command">wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -</span>
<span class="command">sudo apt update</span>
<span class="comment"># Instalar PostgreSQL 16</span>
<span class="command">sudo apt install -y postgresql-16 postgresql-client-16</span>
<span class="comment"># Crear usuario de base de datos para Odoo</span>
<span class="command">sudo -u postgres createuser -s Odoo</span>
</code>
</div>
</li>
<li>
<h4>Instalar wkhtmltopdf</h4>
<p>Necesario para generar reportes PDF en Odoo:</p>
<div class="code-block">
<code>
<span class="comment"># Descargar e instalar wkhtmltopdf con soporte Qt</span>
<span class="command">wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb</span>
<span class="command">sudo apt install -y ./wkhtmltox_0.12.6.1-3.jammy_amd64.deb</span>
<span class="command">rm wkhtmltox_0.12.6.1-3.jammy_amd64.deb</span>
</code>
</div>
</li>
<li>
<h4>Descargar e Instalar Odoo 18</h4>
<p>Clonamos el repositorio oficial y configuramos el entorno:</p>
<div class="code-block">
<code>
<span class="comment"># Clonar Odoo 18</span>
<span class="command">sudo git clone --depth 1 --branch 18.0 https://github.com/Odoo/Odoo.git /opt/Odoo/Odoo</span>
<span class="comment"># Crear entorno virtual Python</span>
<span class="command">sudo python3 -m venv /opt/Odoo/venv</span>
<span class="comment"># Instalar dependencias de Odoo</span>
<span class="command">sudo /opt/Odoo/venv/bin/pip install wheel</span>
<span class="command">sudo /opt/Odoo/venv/bin/pip install -r /opt/Odoo/Odoo/requirements.txt</span>
<span class="comment"># Crear directorio para modulos personalizados</span>
<span class="command">sudo mkdir /opt/Odoo/custom-addons</span>
<span class="comment"># Establecer permisos</span>
<span class="command">sudo chown -R Odoo:Odoo /opt/Odoo</span>
</code>
</div>
</li>
<li>
<h4>Crear Archivo de Configuracion</h4>
<p>Configuramos Odoo con parametros optimizados:</p>
<div class="code-block">
<code>
<span class="command">sudo nano /etc/Odoo.conf</span>
</code>
</div>
<p>Contenido del archivo:</p>
<div class="code-block">
<code>
<span class="variable">[options]</span>
<span class="comment">; Configuracion Basic</span>
admin_passwd = <span class="string">TuContraseñaSeguraAqui123!</span>
db_host = False
db_port = False
db_user = Odoo
db_password = False
<span class="comment">; Rutas</span>
addons_path = /opt/Odoo/Odoo/addons,/opt/Odoo/custom-addons
data_dir = /opt/Odoo/.local/share/Odoo
<span class="comment">; Servidor</span>
http_port = 8069
longpolling_port = 8072
proxy_mode = True
<span class="comment">; Workers (ajustar segun CPU)</span>
workers = 4
max_cron_threads = 2
<span class="comment">; Limites de memoria (ajustar segun RAM)</span>
limit_memory_hard = 2684354560
limit_memory_soft = 2147483648
limit_time_cpu = 600
limit_time_real = 1200
<span class="comment">; Logs</span>
logfile = /var/log/Odoo/Odoo.log
log_level = warn
</code>
</div>
</li>
<li>
<h4>Crear Servicio Systemd</h4>
<p>Configuramos Odoo como servicio del sistema:</p>
<div class="code-block">
<code>
<span class="command">sudo nano /etc/systemd/system/Odoo.service</span>
</code>
</div>
<p>Contenido:</p>
<div class="code-block">
<code>
<span class="variable">[Unit]</span>
Description=Odoo 18
After=network.target postgresql.service
<span class="variable">[Service]</span>
Type=simple
SyslogIdentifier=Odoo
PermissionsStartOnly=true
User=Odoo
Group=Odoo
ExecStart=/opt/Odoo/venv/bin/python3 /opt/Odoo/Odoo/Odoo-bin -c /etc/Odoo.conf
StandardOutput=journal+console
Restart=always
RestartSec=5
<span class="variable">[Install]</span>
WantedBy=multi-user.target
</code>
</div>
<div class="code-block">
<code>
<span class="comment"># Crear directorio de logs</span>
<span class="command">sudo mkdir -p /var/log/Odoo</span>
<span class="command">sudo chown Odoo:Odoo /var/log/Odoo</span>
<span class="comment"># Habilitar e iniciar servicio</span>
<span class="command">sudo systemctl daemon-reload</span>
<span class="command">sudo systemctl enable Odoo</span>
<span class="command">sudo systemctl start Odoo</span>
<span class="comment"># Verificar estado</span>
<span class="command">sudo systemctl status Odoo</span>
</code>
</div>
</li>
<li>
<h4>Instalar y Configurar Nginx</h4>
<p>Configuramos Nginx como proxy inverso con SSL:</p>
<div class="code-block">
<code>
<span class="comment"># Instalar Nginx y Certbot</span>
<span class="command">sudo apt install -y nginx certbot python3-certbot-nginx</span>
<span class="comment"># Crear configuracion de Nginx</span>
<span class="command">sudo nano /etc/nginx/sites-available/Odoo</span>
</code>
</div>
<p>Contenido del archivo Nginx:</p>
<div class="code-block">
<code>
upstream Odoo {
server 127.0.0.1:8069;
}
upstream odoochat {
server 127.0.0.1:8072;
}
server {
listen 80;
server_name <span class="string">tu-dominio.com</span>;
<span class="comment"># Redirigir a HTTPS</span>
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name <span class="string">tu-dominio.com</span>;
<span class="comment"># Logs</span>
access_log /var/log/nginx/Odoo.access.log;
error_log /var/log/nginx/Odoo.error.log;
<span class="comment"># SSL (Certbot lo configurara)</span>
ssl_certificate /etc/letsencrypt/live/tu-dominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tu-dominio.com/privkey.pem;
<span class="comment"># Proxy settings</span>
proxy_read_timeout 720s;
proxy_connect_timeout 720s;
proxy_send_timeout 720s;
<span class="comment"># Headers</span>
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
<span class="comment"># Longpolling</span>
location /longpolling {
proxy_pass http://odoochat;
}
<span class="comment"># Archivos estaticos</span>
location ~* /web/static/ {
proxy_cache_valid 200 90m;
proxy_buffering on;
expires 864000;
proxy_pass http://Odoo;
}
<span class="comment"># Proxy principal</span>
location / {
proxy_redirect off;
proxy_pass http://Odoo;
}
<span class="comment"># Gzip</span>
gzip_types text/css text/plain text/xml application/xml application/javascript application/x-javascript text/javascript;
gzip on;
}
</code>
</div>
<div class="code-block">
<code>
<span class="comment"># Habilitar sitio</span>
<span class="command">sudo ln -s /etc/nginx/sites-available/Odoo /etc/nginx/sites-enabled/</span>
<span class="command">sudo rm /etc/nginx/sites-enabled/default</span>
<span class="comment"># Obtener Certified SSL</span>
<span class="command">sudo certbot --nginx -d tu-dominio.com</span>
<span class="comment"># Reiniciar Nginx</span>
<span class="command">sudo nginx -t && sudo systemctl restart nginx</span>
</code>
</div>
</li>
</ol>
<div class="success-box">
<h4>Instalacion Completada</h4>
<p>Ahora puedes acceder a Odoo en <strong>https://tu-dominio.com</strong>. La primera vez, crea la base de datos usando la contrasena maestra que configuraste en Odoo.conf.</p>
</div>
</section>
<!-- Server Configuration -->
<section id="configuracion" class="content-section fade-in">
<h2>Configuracion Advanced del Servidor</h2>
<h3>Optimizacion de PostgreSQL para Odoo</h3>
<p>PostgreSQL viene con configuracion conservadora por defecto. Ajustamos para mejor rendimiento:</p>
<div class="code-block">
<code>
<span class="command">sudo nano /etc/postgresql/16/main/postgresql.conf</span>
</code>
</div>
<p>Parametros recomendados para servidor de 8GB RAM:</p>
<div class="code-block">
<code>
<span class="comment"># Memoria</span>
shared_buffers = <span class="string">2GB</span> <span class="comment"># 25% de RAM</span>
effective_cache_size = <span class="string">6GB</span> <span class="comment"># 75% de RAM</span>
work_mem = <span class="string">64MB</span> <span class="comment"># RAM / max_connections / 2</span>
maintenance_work_mem = <span class="string">512MB</span>
<span class="comment"># Checkpoint</span>
checkpoint_completion_target = <span class="string">0.9</span>
wal_buffers = <span class="string">64MB</span>
default_statistics_target = <span class="string">100</span>
<span class="comment"># Planificador</span>
random_page_cost = <span class="string">1.1</span> <span class="comment"># Para SSD</span>
effective_io_concurrency = <span class="string">200</span> <span class="comment"># Para SSD</span>
<span class="comment"># Conexiones</span>
max_connections = <span class="string">100</span>
<span class="comment"># Logs</span>
log_min_duration_statement = <span class="string">1000</span> <span class="comment"># Log queries lentas (+1s)</span>
</code>
</div>
<div class="code-block">
<code>
<span class="comment"># Reiniciar PostgreSQL</span>
<span class="command">sudo systemctl restart postgresql</span>
</code>
</div>
<h3>Configuracion de Workers de Odoo</h3>
<p>La configuracion de workers es critica para el rendimiento. Usa esta formula:</p>
<div class="info-box">
<h4>Calculo de Workers</h4>
<p><strong>workers = (CPU cores * 2) + 1</strong></p>
<p><strong>max_cron_threads = 2</strong> (maximo)</p>
<p><strong>limit_memory_soft = 640MB por worker</strong></p>
<p><strong>limit_memory_hard = 768MB por worker</strong></p>
</div>
<table class="comparison-table">
<thead>
<tr>
<th>CPU Cores</th>
<th>Workers</th>
<th>RAM Necesaria</th>
<th>Usuarios Simultaneos</th>
</tr>
</thead>
<tbody>
<tr><td>2</td><td>5</td><td>4 GB</td><td>10-15</td></tr>
<tr><td>4</td><td>9</td><td>8 GB</td><td>20-30</td></tr>
<tr><td>8</td><td>17</td><td>16 GB</td><td>40-60</td></tr>
<tr><td>16</td><td>33</td><td>32 GB</td><td>80-120</td></tr>
</tbody>
</table>
</section>
<!-- Performance Optimization -->
<section id="optimizacion" class="content-section fade-in">
<h2>Optimizacion de Rendimiento</h2>
<h3>1. Habilitar Swap (Recommended)</h3>
<p>Swap proporciona un colchon de seguridad cuando la RAM se agota:</p>
<div class="code-block">
<code>
<span class="comment"># Crear archivo swap de 4GB</span>
<span class="command">sudo fallocate -l 4G /swapfile</span>
<span class="command">sudo chmod 600 /swapfile</span>
<span class="command">sudo mkswap /swapfile</span>
<span class="command">sudo swapon /swapfile</span>
<span class="comment"># Hacer permanente</span>
<span class="command">echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab</span>
<span class="comment"># Ajustar swappiness para servidores</span>
<span class="command">echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf</span>
<span class="command">sudo sysctl -p</span>
</code>
</div>
<h3>2. Cache de Assets con Nginx</h3>
<p>Mejora tiempos de carga cacheando archivos estaticos:</p>
<div class="code-block">
<code>
<span class="comment"># Agregar a la seccion server de Nginx</span>
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
proxy_pass http://Odoo;
}
</code>
</div>
<h3>3. Compresion Gzip</h3>
<p>Reduce el tamano de transferencia significativamente:</p>
<div class="code-block">
<code>
<span class="comment"># En /etc/nginx/nginx.conf</span>
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript
application/xml application/xml+rss text/javascript application/x-javascript;
gzip_min_length 1000;
</code>
</div>
<h3>4. Indices de Base de Datos</h3>
<p>Crea indices adicionales para consultas frecuentes:</p>
<div class="code-block">
<code>
<span class="comment"># Conectar a PostgreSQL</span>
<span class="command">sudo -u postgres psql nombre_base_datos</span>
<span class="comment"># Indices utiles para Odoo</span>
CREATE INDEX CONCURRENTLY idx_mail_message_date ON mail_message(date DESC);
CREATE INDEX CONCURRENTLY idx_sale_order_state ON sale_order(state);
CREATE INDEX CONCURRENTLY idx_purchase_order_state ON purchase_order(state);
CREATE INDEX CONCURRENTLY idx_stock_move_state ON stock_move(state);
</code>
</div>
<h3>5. Programar VACUUM y ANALYZE</h3>
<p>Mantiene PostgreSQL optimizado:</p>
<div class="code-block">
<code>
<span class="comment"># Agregar al crontab del usuario postgres</span>
<span class="command">sudo crontab -u postgres -e</span>
<span class="comment"># Ejecutar VACUUM cada noche a las 3 AM</span>
0 3 * * * /usr/bin/vacuumdb -a -z -q
</code>
</div>
</section>
<!-- Security Hardening -->
<section id="seguridad" class="content-section fade-in">
<h2>Hardening de Seguridad</h2>
<p>La seguridad es critica para cualquier servidor en produccion. Implementamos multiples capas de proteccion.</p>
<h3>1. Configurar Firewall (UFW)</h3>
<div class="code-block">
<code>
<span class="comment"># Instalar y configurar UFW</span>
<span class="command">sudo apt install -y ufw</span>
<span class="comment"># Politicas por defecto</span>
<span class="command">sudo ufw default deny incoming</span>
<span class="command">sudo ufw default allow outgoing</span>
<span class="comment"># Permitir SSH (IMPORTANTE: No bloquear tu acceso)</span>
<span class="command">sudo ufw allow 22/tcp</span>
<span class="comment"># Permitir HTTP y HTTPS</span>
<span class="command">sudo ufw allow 80/tcp</span>
<span class="command">sudo ufw allow 443/tcp</span>
<span class="comment"># Habilitar firewall</span>
<span class="command">sudo ufw enable</span>
<span class="command">sudo ufw status</span>
</code>
</div>
<h3>2. Securizar SSH</h3>
<div class="code-block">
<code>
<span class="command">sudo nano /etc/ssh/sshd_config</span>
</code>
</div>
<p>Cambiar estas configuraciones:</p>
<div class="code-block">
<code>
<span class="comment"># Deshabilitar login root</span>
PermitRootLogin No
<span class="comment"># Usar solo autenticacion por clave</span>
PasswordAuthentication No
PubkeyAuthentication yes
<span class="comment"># Limitar intentos</span>
MaxAuthTries 3
<span class="comment"># Timeout de sesion inactiva</span>
ClientAliveInterval 300
ClientAliveCountMax 2
</code>
</div>
<div class="warning-box">
<h4>Importante</h4>
<p>Antes de deshabilitar PasswordAuthentication, asegurate de tener tu clave SSH configurada correctamente. De lo contrario, perderas acceso al servidor.</p>
</div>
<h3>3. Instalar Fail2ban</h3>
<p>Protege contra ataques de fuerza bruta:</p>
<div class="code-block">
<code>
<span class="command">sudo apt install -y fail2ban</span>
<span class="command">sudo nano /etc/fail2ban/jail.local</span>
</code>
</div>
<div class="code-block">
<code>
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
[nginx-http-auth]
enabled = true
</code>
</div>
<div class="code-block">
<code>
<span class="command">sudo systemctl enable fail2ban</span>
<span class="command">sudo systemctl start fail2ban</span>
</code>
</div>
<h3>4. Actualizaciones Automaticas de Seguridad</h3>
<div class="code-block">
<code>
<span class="command">sudo apt install -y unattended-upgrades</span>
<span class="command">sudo dpkg-reconfigure -plow unattended-upgrades</span>
</code>
</div>
<h3>5. Limitar Acceso a la Base de Datos</h3>
<p>PostgreSQL solo debe ser accesible localmente:</p>
<div class="code-block">
<code>
<span class="command">sudo nano /etc/postgresql/16/main/pg_hba.conf</span>
<span class="comment"># Asegurar que solo permite conexiones locales</span>
local all all peer
host all all 127.0.0.1/32 scram-sha-256
</code>
</div>
<h3>6. Headers de Seguridad en Nginx</h3>
<div class="code-block">
<code>
<span class="comment"># Agregar al bloque server de Nginx</span>
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
</code>
</div>
</section>
<!-- Backup Strategy -->
<section id="backups" class="content-section fade-in">
<h2>Estrategia de Backups</h2>
<p>Una estrategia de backup solida es esencial. Debes respaldar tres componentes:</p>
<h3>Componentes a Respaldar</h3>
<ul>
<li><strong>Base de datos PostgreSQL:</strong> Todos los datos de Odoo</li>
<li><strong>Filestore:</strong> Archivos adjuntos, imagenes, documentos</li>
<li><strong>Configuracion:</strong> Odoo.conf, nginx, etc.</li>
</ul>
<h3>Script de Backup Automatico</h3>
<div class="code-block">
<code>
<span class="command">sudo nano /opt/Odoo/backup.sh</span>
</code>
</div>
<div class="code-block">
<code>
#!/bin/bash
<span class="comment"># Variables</span>
BACKUP_DIR="/opt/Odoo/backups"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="tu_base_de_datos"
RETENTION_DAYS=30
<span class="comment"># Crear directorio Yes No existe</span>
mkdir -p $BACKUP_DIR
<span class="comment"># Backup de base de datos</span>
echo "Respaldando base de datos..."
sudo -u postgres pg_dump $DB_NAME | gzip > $BACKUP_DIR/db_${DATE}.sql.gz
<span class="comment"># Backup del filestore</span>
echo "Respaldando filestore..."
tar -czf $BACKUP_DIR/filestore_${DATE}.tar.gz /opt/Odoo/.local/share/Odoo/filestore/$DB_NAME
<span class="comment"># Backup de configuracion</span>
echo "Respaldando configuracion..."
tar -czf $BACKUP_DIR/config_${DATE}.tar.gz /etc/Odoo.conf /etc/nginx/sites-available/Odoo
<span class="comment"># Eliminar backups antiguos</span>
find $BACKUP_DIR -type f -mtime +$RETENTION_DAYS -delete
<span class="comment"># Mostrar tamano de backups</span>
echo "Backup completado:"
ls -lh $BACKUP_DIR/*_${DATE}*
<span class="comment"># Opcional: Subir a almacenamiento externo (S3, Backblaze, etc.)</span>
<span class="comment"># rclone copy $BACKUP_DIR remote:Odoo-backups/</span>
</code>
</div>
<div class="code-block">
<code>
<span class="comment"># Hacer ejecutable</span>
<span class="command">sudo chmod +x /opt/Odoo/backup.sh</span>
<span class="comment"># Programar backup diario a las 2 AM</span>
<span class="command">sudo crontab -e</span>
<span class="comment"># Agregar:</span>
0 2 * * * /opt/Odoo/backup.sh >> /var/log/Odoo/backup.log 2>&1
</code>
</div>
<div class="success-box">
<h4>Recomendacion: Backup Externo</h4>
<p>Siempre mantiene una copia de tus backups fuera del servidor. Puedes usar rclone para sincronizar con S3, Backblaze B2, Google Cloud Storage u otros Providers. El coste es minimo (centimos por GB/month).</p>
</div>
</section>
<!-- CTA Banner -->
<section class="cta-banner fade-in">
<h3>Prefieren No Gestionar Tu Propio Servidor?</h3>
<p>Yes esta guia te parece demasiado tecnica, considera Hosting gestionado desde 29EUR/month con Odoo4projects. Incluye instalacion, actualizaciones, backups y soporte 24/7.</p>
<a href="https://odoo4projects.com" class="cta-btn" target="_blank" rel="noopener sponsored">Ver Hosting Gestionado</a>
</section>
<!-- FAQ Section -->
<section id="faq" class="faq-section fade-in">
<h2>Preguntas Frecuentes sobre VPS para Odoo</h2>
<div class="faq-item">
<div class="faq-question">Cual es el mejor VPS para Odoo en 2026?</div>
<div class="faq-answer">Para la mayoria de casos, Hetzner ofrece la mejor value for money con servidores en Europe. DigitalOcean es ideal Yes priorizas documentacion y facilidad de uso. Vultr destaca por su red global y Contabo por precios muy economicos pero con posible menor rendimiento.</div>
</div>
<div class="faq-item">
<div class="faq-question">Cuanta RAM necesita Odoo en un VPS?</div>
<div class="faq-answer">Para Odoo Community con 1-10 usuarios: 4GB RAM minimo. Para 10-25 usuarios: 8GB RAM. Para 25-50 usuarios: 16GB RAM. Odoo Enterprise requiere aproximadamente el doble de recursos debido a los modulos adicionales.</div>
</div>
<div class="faq-item">
<div class="faq-question">Es dificil instalar Odoo en un VPS?</div>
<div class="faq-answer">Requiere conocimientos basicos de Linux y linea de comandos. Con esta guia, la instalacion toma aproximadamente 45 minutos. Yes No tienes experiencia tecnica, considera usar Hosting gestionado que incluye instalacion y mantenimiento.</div>
</div>
<div class="faq-item">
<div class="faq-question">Cuanto cuesta un VPS para Odoo mensualmente?</div>
<div class="faq-answer">Los precios varian desde 4.51 EUR/month (Hetzner CX11) hasta 50+ EUR/month para servidores de alto rendimiento. El promedio para una PYME con 10-20 usuarios es 15-30 EUR/month. Esto No incluye el tiempo de administracion.</div>
</div>
<div class="faq-item">
<div class="faq-question">Puedo migrar de Odoo.sh a un VPS propio?</div>
<div class="faq-answer">Yes, es posible migrar exportando la base de datos PostgreSQL y el filestore desde Odoo.sh. Sin embargo, perderas actualizaciones automaticas, integracion Git y soporte oficial. La migracion requiere conocimientos tecnicos avanzados y planificacion cuidadosa.</div>
</div>
<div class="faq-item">
<div class="faq-question">Como hacer backup de Odoo en un VPS?</div>
<div class="faq-answer">Debes hacer backup de: 1) Base de datos PostgreSQL con pg_dump, 2) Directorio filestore con los archivos adjuntos, 3) Archivo de configuracion Odoo.conf. Recomendamos backups diarios automatizados con retencion de 30 dias y copia externa usando rclone.</div>
</div>
<div class="faq-item">
<div class="faq-question">Que sistema operativo usar para el VPS?</div>
<div class="faq-answer">Recomendamos Ubuntu 22.04 LTS o 24.04 LTS por su estabilidad, soporte prolongado y compatibilidad con Odoo. Debian 12 es otra excellent opcion. Evita distribuciones con ciclos de vida cortos o sin soporte LTS para servidores de produccion.</div>
</div>
<div class="faq-item">
<div class="faq-question">Como actualizar Odoo en un VPS?</div>
<div class="faq-answer">Las actualizaciones menores se realizan con git pull en el repositorio de Odoo, seguido de reinicio del servicio. Las actualizaciones mayores (ej: 17 a 18) requieren migracion de base de datos y modulos, proceso complejo que puede requerir asistencia profesional.</div>
</div>
</section>
<!-- Related Articles -->
<section class="content-section fade-in">
<h2>Related Articles</h2>
<div class="provider-grid">
<a href="/Odoo-Hosting/mejor-Hosting-Odoo-2026/" class="provider-card" style="text-decoration: none;">
<h4>Mejor Odoo Hosting 2026</h4>
<p style="color: #b0b0b0;">Comparativa completa de todos los Providers de Hosting para Odoo.</p>
</a>
<a href="/Odoo-Hosting/Hosting-Odoo-gratis-gratuito-2025/" class="provider-card" style="text-decoration: none;">
<h4>Odoo Hosting Gratis</h4>
<p style="color: #b0b0b0;">Opciones gratuitas para probar Odoo sin coste inicial.</p>
</a>
<a href="/Odoo-Hosting/requisitos-Hosting-Odoo-servidor-2025/" class="provider-card" style="text-decoration: none;">
<h4>Requisitos de Servidor</h4>
<p style="color: #b0b0b0;">Especificaciones tecnicas detalladas para Odoo.</p>
</a>
</div>
</section>
</main>
<!-- EEAT Author Section -->
<div id="eeat-section"></div>
<div id="footer"><footer class="site-footer"><div class="container"><div class="footer-cols"><div><strong>Odoo Expertos</strong></div><nav class="footer-nav"><a href="/en/">Home</a><a href="/en/odoo/">Odoo</a><a href="/en/odoo-ia/">Odoo AI</a><a href="/en/odoo-hosting/">Odoo Hosting</a><a href="/en/mapa-del-sitio/">Sitemap</a></nav></div><div class="footer-bottom"><small>&copy; 2026 Odoo Expertos</small></div></div></footer></div><nav class="footer-nav"><a href="/en/">Home</a><a href="/en/odoo/">Odoo</a><a href="/en/odoo-ia/">Odoo AI</a><a href="/en/odoo-hosting/">Odoo Hosting</a><a href="/en/mapa-del-sitio/">Sitemap</a></nav></div><div class="footer-bottom"><small>&copy; 2026 Odoo Expertos</small></div></div></footer></div>
<!-- Scripts -->
<script src="/js/language-router.js"></script>
<script src="/components/header.min.js"></script>
<script src="/components/footer.min.js"></script>
<script src="/components/eeat.min.js"></script>
<script src="/js/cookie-banner.min.js"></script>
<!-- D3.js -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
// Initialize components
// Scroll animation observer
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.1 });
document.querySelectorAll('.fade-in').forEach(el => observer.observe(el));
// FAQ Toggle
document.querySelectorAll('.faq-question').forEach(question => {
question.addEventListener('click', () => {
const item = question.parentElement;
item.classList.toggle('open');
});
});
// Chart Data
const vpsData = {
scatter: [
{ name: 'Hetzner CX22', price: 7.05, performance: 92, locations: 5, provider: 'Hetzner' },
{ name: 'Hetzner CX32', price: 13.10, performance: 95, locations: 5, provider: 'Hetzner' },
{ name: 'DigitalOcean 4GB', price: 24, performance: 85, locations: 15, provider: 'DigitalOcean' },
{ name: 'DigitalOcean 8GB', price: 48, performance: 88, locations: 15, provider: 'DigitalOcean' },
{ name: 'Vultr 4GB', price: 24, performance: 87, locations: 32, provider: 'Vultr' },
{ name: 'Vultr 8GB', price: 48, performance: 90, locations: 32, provider: 'Vultr' },
{ name: 'Contabo VPS S', price: 5.99, performance: 70, locations: 6, provider: 'Contabo' },
{ name: 'Contabo VPS M', price: 8.99, performance: 75, locations: 6, provider: 'Contabo' }
],
decisionTree: {
name: 'Ubicacion Principal?',
description: 'Donde estan tus usuarios',
children: [
{
name: 'Europa',
description: 'Usuarios en EU',
children: [
{
name: 'Presupuesto?',
children: [
{ name: 'Ajustado (<10EUR)',
children: [
{ name: 'Hetzner CX22', description: '7.05EUR/mes - Mejor rendimiento/precio' }
]
},
{ name: 'Flexible (>10EUR)',
children: [
{ name: 'Hetzner CX32', description: '13.10EUR/mes - Optimo para PYMES' }
]
}
]
}
]
},
{
name: 'America',
description: 'Usuarios en US/LATAM',
children: [
{
name: 'Prioridad?',
children: [
{ name: 'Documentacion/Soporte',
children: [
{ name: 'DigitalOcean', description: 'Excelente documentacion y comunidad' }
]
},
{ name: 'Cobertura Global',
children: [
{ name: 'Vultr', description: '32 ubicaciones mundiales' }
]
}
]
}
]
},
{
name: 'Presupuesto Minimo',
description: 'Desarrollo o pruebas',
children: [
{ name: 'Contabo VPS S', description: '5.99EUR/mes - Maximo recursos por precio' }
]
}
]
}
};
// Tooltip
const tooltip = d3.select('body').append('div')
.attr('class', 'd3-tooltip')
.style('opacity', 0);
// Color scale by provider
const providerColors = {
'Hetzner': '#FF6B35',
'DigitalOcean': '#0080FF',
'Vultr': '#007BFC',
'Contabo': '#FFB74D'
};
// VPS Scatter Plot
function renderVPSScatterPlot() {
const container = d3.select('#vps-scatter-chart');
if (container.empty()) return;
const width = container.node().getBoundingClientRect().width;
const height = 400;
const margin = { top: 40, right: 120, bottom: 60, left: 70 };
container.html('');
const svg = container.append('svg')
.attr('width', width)
.attr('height', height);
const xScale = d3.scaleLinear()
.domain([0, d3.max(vpsData.scatter, d => d.price) * 1.15])
.range([margin.left, width - margin.right]);
const yScale = d3.scaleLinear()
.domain([60, 100])
.range([height - margin.bottom, margin.top]);
const sizeScale = d3.scaleSqrt()
.domain([0, d3.max(vpsData.scatter, d => d.locations)])
.range([8, 30]);
// Grid lines
svg.append('g')
.attr('class', 'grid')
.attr('transform', `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(xScale).tickSize(-(height - margin.top - margin.bottom)).tickFormat(''))
.selectAll('line').attr('stroke', '#333');
svg.append('g')
.attr('class', 'grid')
.attr('transform', `translate(${margin.left},0)`)
.call(d3.axisLeft(yScale).tickSize(-(width - margin.left - margin.right)).tickFormat(''))
.selectAll('line').attr('stroke', '#333');
// Axes
svg.append('g')
.attr('transform', `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(xScale).tickFormat(d => `${d}EUR`))
.attr('color', '#888');
svg.append('g')
.attr('transform', `translate(${margin.left},0)`)
.call(d3.axisLeft(yScale))
.attr('color', '#888');
// Axis labels
svg.append('text')
.attr('x', width / 2)
.attr('y', height - 10)
.attr('text-anchor', 'middle')
.attr('fill', '#888')
.attr('font-size', '14px')
.text('Precio Mensual (EUR)');
svg.append('text')
.attr('transform', 'rotate(-90)')
.attr('x', -height / 2)
.attr('y', 20)
.attr('text-anchor', 'middle')
.attr('fill', '#888')
.attr('font-size', '14px')
.text('Puntuacion de Rendimiento');
// Dots
svg.selectAll('circle.dot')
.data(vpsData.scatter)
.join('circle')
.attr('class', 'dot')
.attr('cx', d => xScale(d.price))
.attr('cy', d => yScale(d.performance))
.attr('r', 0)
.attr('fill', d => providerColors[d.provider])
.attr('fill-opacity', 0.8)
.attr('stroke', '#fff')
.attr('stroke-width', 2)
.style('cursor', 'pointer')
.on('mouseover', function(event, d) {
d3.select(this).attr('fill-opacity', 1).attr('stroke-width', 3);
tooltip.transition().duration(200).style('opacity', 1);
tooltip.html(`<strong>${d.name}</strong><br>Precio: ${d.price}EUR/mes<br>Rendimiento: ${d.performance}/100<br>Ubicaciones: ${d.locations}`)
.style('left', (event.pageX + 15) + 'px')
.style('top', (event.pageY - 28) + 'px');
})
.on('mouseout', function() {
d3.select(this).attr('fill-opacity', 0.8).attr('stroke-width', 2);
tooltip.transition().duration(200).style('opacity', 0);
})
.transition()
.duration(800)
.delay((d, i) => i * 100)
.ease(d3.easeElastic.amplitude(1).period(0.5))
.attr('r', d => sizeScale(d.locations));
// Labels
svg.selectAll('text.label')
.data(vpsData.scatter)
.join('text')
.attr('class', 'label')
.attr('x', d => xScale(d.price))
.attr('y', d => yScale(d.performance) - sizeScale(d.locations) - 8)
.attr('text-anchor', 'middle')
.attr('fill', '#e0e0e0')
.attr('font-size', '10px')
.attr('opacity', 0)
.text(d => d.name)
.transition()
.duration(500)
.delay((d, i) => i * 100 + 400)
.attr('opacity', 1);
// Legend
const legend = svg.append('g')
.attr('transform', `translate(${width - 110}, ${margin.top})`);
const providers = ['Hetzner', 'DigitalOcean', 'Vultr', 'Contabo'];
providers.forEach((provider, i) => {
const g = legend.append('g')
.attr('transform', `translate(0, ${i * 25})`);
g.append('circle')
.attr('r', 8)
.attr('fill', providerColors[provider]);
g.append('text')
.attr('x', 15)
.attr('y', 5)
.attr('fill', '#b0b0b0')
.attr('font-size', '12px')
.text(provider);
});
}
// Decision Tree
function renderVPSDecisionTree() {
const container = d3.select('#vps-decision-tree');
if (container.empty()) return;
const width = container.node().getBoundingClientRect().width;
const height = 500;
container.html('');
const svg = container.append('svg')
.attr('width', width)
.attr('height', height);
const g = svg.append('g')
.attr('transform', `translate(50,30)`);
const treeLayout = d3.tree()
.size([width - 100, height - 80]);
const root = d3.hierarchy(vpsData.decisionTree);
treeLayout(root);
// Links
g.selectAll('.link')
.data(root.links())
.join('path')
.attr('class', 'link')
.attr('d', d3.linkVertical()
.x(d => d.x)
.y(d => d.y))
.attr('fill', 'none')
.attr('stroke', '#555')
.attr('stroke-width', 2)
.attr('stroke-dasharray', function() {
return this.getTotalLength();
})
.attr('stroke-dashoffset', function() {
return this.getTotalLength();
})
.transition()
.duration(1200)
.attr('stroke-dashoffset', 0);
// Nodes
const nodes = g.selectAll('.node')
.data(root.descendants())
.join('g')
.attr('class', 'node')
.attr('transform', d => `translate(${d.x},${d.y})`)
.style('opacity', 0)
.style('cursor', 'pointer');
nodes.append('circle')
.attr('r', d => d.children ? 12 : 10)
.attr('fill', d => {
if (!d.children) {
// Leaf nodes - color by provider
if (d.data.name.includes('Hetzner')) return '#FF6B35';
if (d.data.name.includes('DigitalOcean')) return '#0080FF';
if (d.data.name.includes('Vultr')) return '#007BFC';
if (d.data.name.includes('Contabo')) return '#FFB74D';
return '#4CAF50';
}
return '#FF6B35';
})
.attr('stroke', '#fff')
.attr('stroke-width', 2);
nodes.append('text')
.attr('dy', d => d.children ? -20 : 28)
.attr('text-anchor', 'middle')
.attr('fill', '#e0e0e0')
.attr('font-size', d => d.depth === 0 ? '13px' : '11px')
.attr('font-weight', d => d.depth === 0 ? '600' : '400')
.text(d => d.data.name.length > 20 ? d.data.name.substring(0, 18) + '...' : d.data.name);
nodes.on('mouseover', function(event, d) {
d3.select(this).select('circle').attr('r', d.children ? 16 : 14);
if (d.data.description) {
tooltip.transition().duration(200).style('opacity', 1);
tooltip.html(`<strong>${d.data.name}</strong><br>${d.data.description}`)
.style('left', (event.pageX + 15) + 'px')
.style('top', (event.pageY - 28) + 'px');
}
})
.on('mouseout', function(event, d) {
d3.select(this).select('circle').attr('r', d.children ? 12 : 10);
tooltip.transition().duration(200).style('opacity', 0);
});
nodes.transition()
.duration(500)
.delay((d, i) => i * 80)
.style('opacity', 1);
}
// Initialize charts when visible
const chartObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const id = entry.target.id;
setTimeout(() => {
if (id === 'vps-scatter-chart') renderVPSScatterPlot();
if (id === 'vps-decision-tree') renderVPSDecisionTree();
}, 100);
chartObserver.unobserve(entry.target);
}
});
}, { threshold: 0.15 });
document.querySelectorAll('.chart-container').forEach(el => chartObserver.observe(el));
// Resize handler
let resizeTimeout;
window.addEventListener('resize', () => {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
renderVPSScatterPlot();
renderVPSDecisionTree();
}, 300);
});
</script>
</body>
</html>