Skip to content

Hosting compartido con cPanel ​

El hosting compartido con cPanel es, por mucho, lo que más vas a encontrar con clientes pequeños: consultorios, restaurantes, despachos, escuelas. En esta lección aprenderás a moverte en cPanel como un profesional y a publicar dos tipos de proyecto: un sitio estático/VitePress y un proyecto PHP + MySQL.

Concepto ​

cPanel es un panel web que te permite administrar tu parte del servidor sin usar la terminal. Al contratar un plan recibes:

  • Una URL de acceso, normalmente https://tudominio.com/cpanel o https://tudominio.com:2083.
  • Usuario y contraseña de cPanel.
  • Datos FTP (servidor, usuario, puerto).
  • Los nameservers del hosting (ver Dominios y DNS).

hPanel, Plesk, DirectAdmin

Algunos proveedores usan su propio panel (Hostinger usa hPanel) u otros como Plesk o DirectAdmin. Los conceptos son idénticos: administrador de archivos, bases de datos, correos, dominios y SSL. Solo cambian los nombres de los menús.

La carpeta más importante: public_html ​

txt
/home/usuario/
├── public_html/          ← lo que está aquí se ve en https://tudominio.com
│   ├── index.html
│   └── .htaccess
├── tienda.tudominio.com/ ← carpeta de un subdominio (según cómo lo crees)
├── mail/                 ← buzones de correo (no tocar)
├── logs/                 ← registros de acceso
└── privado/              ← archivos fuera de public_html: NO accesibles por web

Todo lo que pongas en public_html es público. Archivos sensibles (configuraciones, respaldos) deben ir fuera de esa carpeta.

Tour por las secciones de cPanel ​

SecciónPara qué la usarás
Administrador de archivosSubir, editar, extraer ZIP, cambiar permisos.
Cuentas FTPCrear accesos FTP (por ejemplo para otro desarrollador).
Bases de datos MySQLCrear base, usuario y asignar privilegios.
phpMyAdminImportar/exportar .sql, ver tablas.
Cuentas de correoCrear hola@dominio.com, ver configuración IMAP/SMTP, Webmail.
DominiosSubdominios, dominios adicionales (addon).
Zone EditorEditar registros DNS (si los nameservers apuntan al hosting).
SSL/TLS StatusActivar AutoSSL (certificado gratis).
MultiPHP ManagerElegir versión de PHP por dominio.
Cron JobsEjecutar tareas programadas.
RespaldosDescargar copia completa o de la base de datos.

Subir archivos ​

Opción 1: Administrador de archivos (rápido) ​

  1. Comprime tu proyecto en un ZIP en tu computadora.
  2. cPanel → Administrador de archivos → entra a public_html.
  3. Cargar → elige el ZIP.
  4. Clic derecho sobre el ZIP → Extraer.
  5. Verifica que index.html o index.php quede directamente dentro de public_html (no en una subcarpeta).
  6. Borra el ZIP.

Opción 2: FTP con FileZilla (cómodo para muchos archivos) ​

  1. Instala FileZilla Client.
  2. Archivo → Gestor de sitios → Nuevo sitio:
txt
Protocolo:  FTP - Protocolo de transferencia de archivos
Servidor:   ftp.tudominio.com   (o la IP que te dio el hosting)
Puerto:     21
Cifrado:    Requiere FTP explícito sobre TLS   ← más seguro que FTP plano
Modo:       Normal
Usuario:    usuario@tudominio.com
Contraseña: ********
  1. Conecta. A la izquierda tus archivos locales; a la derecha el servidor. Arrastra el contenido de tu carpeta al public_html remoto.

Buena práctica

Si el hosting ofrece SFTP (puerto 22) úsalo: todo viaja cifrado. Nunca uses FTP sin TLS en una red pública.

Bases de datos MySQL ​

En cPanel → Bases de datos MySQL:

  1. Crear base de datos: escribe tienda. cPanel le antepone tu usuario: usuario_tienda.
  2. Agregar usuario: usuario_app con una contraseña fuerte (usa el generador).
  3. Agregar usuario a la base de datos → marca TODOS LOS PRIVILEGIOS → Hacer cambios.

Apunta los datos; los usarás en tu código:

env
DB_HOST=localhost
DB_NAME=usuario_tienda
DB_USER=usuario_app
DB_PASS=La-Contraseña-Generada

Error común

Usar 127.0.0.1 o el dominio como host. En hosting compartido casi siempre es localhost. Otro clásico: olvidar el prefijo del usuario en el nombre de la base.

Correos, subdominios y SSL ​

Cuentas de correo ​

Correo electrónico → Cuentas de correo → Crear. Luego "Connect Devices" te muestra los datos IMAP/SMTP (normalmente mail.tudominio.com, IMAP 993, SMTP 465 con SSL). El cliente puede leerlo en Webmail, Outlook, Gmail o el celular.

Subdominios ​

Dominios → Crear un dominio nuevo (o "Subdominios" en versiones antiguas): escribe blog.tudominio.com y define su carpeta raíz (ej. public_html/blog o blog.tudominio.com).

SSL gratis ​

SSL/TLS Status → Run AutoSSL. En minutos tendrás certificado gratuito (Let's Encrypt o Sectigo) que se renueva solo. Requisito: que el dominio ya apunte al hosting.

Después fuerza HTTPS creando o editando public_html/.htaccess:

apache
# Redirigir todo el tráfico HTTP a HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]

Versión de PHP ​

MultiPHP Manager → elige el dominio → PHP 8.2 o superior. En Select PHP Version (si existe) activas extensiones (pdo_mysql, mbstring, intl, gd).

Proyecto 1: subir un sitio estático o VitePress ​

Un sitio estático (HTML/CSS/JS, Vite, Astro, VitePress) se compila en tu computadora y solo subes el resultado.

1. Compila ​

Para VitePress (con el script estándar del package.json):

bash
# instala dependencias si no lo has hecho
npm install

# genera el sitio en docs/.vitepress/dist
npm run docs:build

Para un proyecto Vite/React/Vue: npm run build → carpeta dist/.

La opción base

Si el sitio va en la raíz del dominio (https://tudominio.com/) no necesitas nada. Si va en una subcarpeta (https://tudominio.com/docs/), configura base: '/docs/' en .vitepress/config.mts (o en vite.config.js) antes de compilar.

2. Sube el contenido de dist ​

Sube el contenido de docs/.vitepress/dist (no la carpeta dist en sí) a public_html. Debe quedar public_html/index.html, public_html/assets/, etc.

3. URLs limpias y página 404 ​

Si en VitePress usas cleanUrls: true, las rutas no tienen .html (/guia/inicio). Apache necesita saber que debe servir inicio.html. Crea public_html/.htaccess:

apache
# Forzar HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]

# URLs limpias: /guia/inicio → /guia/inicio.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [L]

# Página de error personalizada que genera VitePress
ErrorDocument 404 /404.html

# Caché larga para archivos con hash en /assets
<IfModule mod_headers.c>
  <FilesMatch "\.(js|css|woff2|svg|png|jpg|webp)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
  </FilesMatch>
</IfModule>

SPA (React/Vue con router)

Para una SPA, todas las rutas deben caer en index.html:

apache
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

Proyecto 2: subir un proyecto PHP + MySQL ​

Supongamos un sistema de contactos con esta estructura:

txt
mi-proyecto/
├── config/
│   └── config.php        ← credenciales (no debe ser público)
├── public/               ← lo único que debe ser público
│   ├── index.php
│   ├── guardar.php
│   └── css/estilos.css
└── database/
    └── esquema.sql

1. Exporta la base de datos local ​

Desde phpMyAdmin local (XAMPP/Laragon): base → Exportar → Rápido → SQL. O por terminal:

bash
mysqldump -u root -p mi_base > respaldo.sql

2. Crea la base en cPanel e importa ​

Crea base y usuario (ver arriba). Luego phpMyAdmin → selecciona usuario_tienda → Importar → elige respaldo.sql → Continuar.

Error común

Si el .sql trae CREATE DATABASE mi_base; y USE mi_base;, bórralos antes de importar: en hosting compartido no tienes permiso para crear bases desde SQL y el nombre real lleva prefijo.

3. Configuración de conexión ​

Coloca config/ fuera de public_html, por ejemplo en /home/usuario/mi-proyecto/config/config.php:

php
<?php
// config/config.php — fuera de public_html
return [
    'db_host' => 'localhost',
    'db_name' => 'usuario_tienda',
    'db_user' => 'usuario_app',
    'db_pass' => 'La-Contraseña-Generada',
    'debug'   => false, // en producción NUNCA mostrar errores
];

Y la conexión con PDO:

php
<?php
// public_html/conexion.php
$config = require __DIR__ . '/../mi-proyecto/config/config.php';

ini_set('display_errors', $config['debug'] ? '1' : '0');

try {
    $pdo = new PDO(
        "mysql:host={$config['db_host']};dbname={$config['db_name']};charset=utf8mb4",
        $config['db_user'],
        $config['db_pass'],
        [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
    );
} catch (PDOException $e) {
    error_log($e->getMessage());     // queda en el log, no en pantalla
    http_response_code(500);
    exit('Error interno. Intenta más tarde.');
}

4. Sube los archivos ​

  • El contenido de public/ → a public_html/.
  • La carpeta config/ → a /home/usuario/mi-proyecto/config/.

5. Permisos ​

  • Carpetas: 755. Archivos: 644. Archivo de configuración: 600 o 640 si el hosting lo permite.
  • Nunca 777.

En el Administrador de archivos: clic derecho → Change Permissions.

6. Protege archivos sensibles con .htaccess ​

apache
# Bloquear acceso a archivos ocultos y de configuración
<FilesMatch "^\.|\.(env|sql|log|ini|sh)$">
  Require all denied
</FilesMatch>

# Desactivar el listado de carpetas
Options -Indexes

Errores típicos al subir PHP ​

SíntomaCausa probable
Página en blanco o error 500Error de PHP: revisa error_log en la carpeta o en Errores de cPanel.
SQLSTATE[HY000] [1045] Access deniedUsuario/contraseña mal o usuario no agregado a la base.
SQLSTATE[HY000] [2002]Host incorrecto: usa localhost.
Acentos raros (é)Falta charset=utf8mb4 en el DSN o las tablas no son utf8mb4.
Call to undefined functionVersión de PHP vieja o extensión desactivada.
Se descarga el .php en vez de ejecutarseEl dominio no tiene PHP asignado; revisa MultiPHP.

Cron jobs ​

Para ejecutar un script cada día a las 3:00 a. m.: cPanel → Cron Jobs:

bash
0 3 * * * /usr/local/bin/php /home/usuario/mi-proyecto/tareas/limpiar.php >/dev/null 2>&1

Ejercicios ​

  1. Crea en un hosting (o simúlalo en papel) la base usuario_blog, el usuario usuario_blogapp y escribe el array de configuración correspondiente.
  2. Escribe un .htaccess que fuerce HTTPS, quite el www y desactive el listado de carpetas.
  3. Tu VitePress se publicará en https://cliente.com/manual/. ¿Qué cambias antes de compilar y dónde subes los archivos?
Ver solución
php
<?php
return [
    'db_host' => 'localhost',
    'db_name' => 'usuario_blog',
    'db_user' => 'usuario_blogapp',
    'db_pass' => 'Contraseña-Fuerte',
    'debug'   => false,
];
apache
Options -Indexes
RewriteEngine On
# Quitar www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [L,R=301]
# Forzar HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]
  1. En .vitepress/config.mts agregas base: '/manual/', compilas con npm run docs:build y subes el contenido de docs/.vitepress/dist a public_html/manual/.

Resumen ​

  • public_html es la carpeta pública; lo sensible va fuera.
  • Sube por Administrador de archivos (ZIP) o FTP/SFTP con FileZilla.
  • Base de datos: crear base + usuario + asignar privilegios; host localhost y nombres con prefijo.
  • AutoSSL da HTTPS gratis; fuérzalo con .htaccess.
  • Estáticos/VitePress: compila y sube el contenido de dist. PHP: sube, importa la base, configura PDO y permisos 755/644.
  • Siguiente: Linux para servidores.

Academia Web — aprende, copia y construye.