Guía de instalación
Ubuntu 24.04 · Apache · PHP 8.3
MariaDB · WordPress · HTTPS

De cero a WordPress en producción, paso a paso.

0%
0 de pasos completados
01

Primer contacto — SSH

Tu primera conexión al servidor. Aprenderás a entrar desde tu terminal y a poner el sistema al día antes de instalar nada.

Conceptos de esta fase
VPS — Virtual Private Server. Un ordenador remoto en un centro de datos que tú alquilas y controlas.
SSH — Secure Shell. Protocolo para conectarte a un servidor remoto de forma segura desde tu terminal.
IP — Dirección numérica que identifica a tu servidor en internet. Algo como 65.21.4.123.
root — El usuario administrador máximo de Linux. Puede hacer cualquier cosa en el sistema.
apt — El gestor de paquetes de Ubuntu. Sirve para instalar, actualizar y eliminar programas.
◈ Pregúntale a Claude Code "¿Qué es SSH y por qué es más seguro que otros métodos de conexión remota? ¿Qué significa que use cifrado asimétrico?"

Desde tu terminal, este comando abre una conexión segura con el servidor. Sustituye TU_IP por la dirección que te dio Puchito.

Reflexiona antes de ejecutar SSH cifra todo lo que envías. ¿Qué pasaría si la conexión no estuviera cifrada? ¿Qué podría ver alguien que interceptara el tráfico?
bash
ssh root@TU_IP

La primera vez te preguntará si confías en el servidor. Escribe yes y pulsa Enter.

¿Por qué?

SSH establece un canal cifrado entre tu ordenador y el servidor. Sin cifrado, cualquier dato que envíes — contraseñas incluidas — podría leerse en texto plano por cualquiera en la red.

La primera vez que te conectas, el servidor te muestra su "huella digital" (fingerprint) para que puedas verificar que es quien dice ser. Al escribir yes la guardas en tu ordenador y futuras conexiones la comprueban automáticamente.

Lo primero en cualquier servidor nuevo: traer todos los paquetes a su versión más reciente.

Reflexiona antes de ejecutar Hay dos comandos encadenados con &&. ¿Qué crees que hace cada uno? ¿Qué diferencia hay entre "actualizar la lista" y "actualizar los paquetes"?
bash
apt update && apt upgrade -y
¿Por qué?

apt update descarga la lista actualizada de paquetes disponibles — no instala nada, solo actualiza el catálogo. apt upgrade instala las versiones más nuevas de todo lo que ya está instalado.

Los paquetes desactualizados pueden contener vulnerabilidades de seguridad conocidas. Un servidor recién creado puede llevar semanas sin actualizarse desde que se preparó su imagen base.

El && significa "ejecuta el segundo comando solo si el primero termina sin errores". El -y responde automáticamente "sí" a todas las confirmaciones.

02

Seguridad básica

Trabajar siempre como root es peligroso. Crearemos un usuario propio con permisos de administrador y configuraremos el firewall.

Conceptos de esta fase
Principio de mínimo privilegio — Cada usuario o proceso debería tener solo los permisos que necesita para funcionar, ni más.
sudo — Comando que permite ejecutar algo con permisos de administrador de forma puntual, sin ser root permanentemente.
Firewall — Sistema que filtra el tráfico de red según reglas definidas. Decide qué conexiones entran y cuáles se bloquean.
Puerto — Canal numérico por el que un servicio escucha conexiones. HTTP usa el 80, HTTPS el 443, SSH el 22.
UFW — Uncomplicated Firewall. La herramienta de firewall estándar en Ubuntu, más sencilla de usar que iptables.
◈ Pregúntale a Claude Code "¿Qué es el principio de mínimo privilegio y por qué es importante en seguridad? ¿Qué diferencia hay entre un firewall de red y un firewall de sistema operativo?"
Reflexiona antes de ejecutar Si root puede hacer cualquier cosa, ¿qué riesgo concreto hay en trabajar siempre como root? Piensa en un error tipográfico en un comando de borrado.

Crea un usuario con tu nombre. El sistema te pedirá una contraseña — ponle una segura y apúntala.

bash
adduser puchita

Las preguntas sobre nombre completo, teléfono, etc. puedes dejarlas en blanco pulsando Enter.

¿Por qué?

Root no tiene ninguna protección contra errores propios. Un rm -rf /var/www mal escrito ejecutado como root borra todo sin preguntar. Con un usuario normal, los errores graves requieren sudo explícito — un paso extra que da tiempo a pensar.

Además, si alguien obtiene acceso no autorizado a tu sesión, el daño queda limitado a los permisos de ese usuario, no a los de root.

Añade el usuario al grupo sudo para que pueda ejecutar comandos de administrador cuando sea necesario.

bash
usermod -aG sudo puchita
¿Por qué?

usermod modifica un usuario existente. El flag -aG significa "añadir al grupo" (append to Group) sin eliminar los grupos que ya tiene. sudo es el nombre del grupo que otorga permisos de administrador en Ubuntu.

A partir de ahora, cuando el usuario necesite permisos de administrador, solo tiene que anteponer sudo al comando. El sistema le pedirá su contraseña como confirmación explícita.

Reflexiona antes de ejecutar El orden importa aquí. Si activas UFW antes de permitir SSH, ¿qué crees que pasaría con tu conexión actual? ¿Por qué hay que añadir las reglas primero?

Instalamos UFW, definimos las reglas y lo activamos. El orden de los comandos es importante.

bash
apt install ufw -y
ufw allow OpenSSH
ufw allow 'Apache Full'
ufw enable
bash — verificar estado
ufw status
¿Por qué?

Un servidor en internet recibe intentos de conexión continuos desde todo el mundo — bots que prueban contraseñas, escáneres de puertos, intentos de explotar vulnerabilidades. Sin firewall, todos los puertos del servidor son accesibles.

ufw allow OpenSSH permite conexiones al puerto 22 (SSH). ufw allow 'Apache Full' abre los puertos 80 (HTTP) y 443 (HTTPS). Si activaras el firewall sin permitir SSH primero, tu conexión actual se cortaría y no podrías volver a entrar.

A partir de aquí trabajamos con el usuario propio, no con root. Todos los comandos que necesiten permisos llevarán sudo delante.

bash
su - puchita
¿Por qué?

su significa switch user. El guión - carga el entorno completo del nuevo usuario (variables de entorno, directorio home, etc.), como si hubiera iniciado sesión directamente.

03

Apache — el servidor web

Apache es el programa que recibe las peticiones del navegador y devuelve las páginas. Sin él, el servidor no sabe qué hacer cuando alguien intenta visitar tu web.

Conceptos de esta fase
Servidor web — Programa que escucha peticiones HTTP/HTTPS y responde con contenido (HTML, imágenes, datos...).
HTTP — HyperText Transfer Protocol. El protocolo de comunicación de la web. Funciona con un modelo petición-respuesta.
Puerto 80 — Puerto estándar para HTTP. Cuando escribes una URL sin especificar puerto, el navegador usa el 80 por defecto.
systemctl — Herramienta para gestionar servicios en Linux: iniciar, detener, reiniciar, ver estado.
◈ Pregúntale a Claude Code "¿Cómo funciona el protocolo HTTP? ¿Qué ocurre exactamente desde que escribo una URL en el navegador hasta que aparece la página?"
bash
sudo apt install apache2 -y
¿Por qué?

Sin un servidor web, Ubuntu no sabe qué hacer cuando llega una petición HTTP al puerto 80. Apache es el programa que escucha ese puerto y responde con el contenido apropiado.

Una vez instalado, Apache arranca automáticamente y se configura para iniciarse con el sistema. No necesitas ejecutarlo manualmente.

Reflexiona antes de ejecutar El comando te mostrará el estado del servicio. ¿Qué crees que significa "active (running)"? ¿Y qué indicaría "failed" o "inactive"?

Comprueba que Apache está en marcha y pruébalo en el navegador.

bash
sudo systemctl status apache2

Abre también tu navegador y ve a http://TU_IP. Deberías ver la página de bienvenida de Apache. Si la ves, el servidor web está funcionando.

¿Por qué?

Verificar siempre después de instalar es una buena práctica. systemctl status muestra si el servicio está corriendo, cuándo arrancó y las últimas líneas de su log — muy útil para detectar errores de configuración.

La comprobación en el navegador confirma además que el firewall permite el tráfico HTTP y que Apache responde correctamente a peticiones reales.

04

PHP 8.3

WordPress está escrito en PHP. Sin PHP, Apache sirve archivos estáticos pero no puede ejecutar código. Necesitamos instalarlo junto con las extensiones que WordPress requiere.

Conceptos de esta fase
Lenguaje de servidor — Código que se ejecuta en el servidor (no en el navegador) antes de enviar la respuesta. PHP genera HTML dinámicamente.
Extensión PHP — Módulo adicional que añade capacidades a PHP: conectar con bases de datos, manipular imágenes, comprimir archivos...
Módulo Apache — Plugin que amplía las capacidades de Apache. libapache2-mod-php es el que le dice a Apache cómo procesar archivos PHP.
◈ Pregúntale a Claude Code "¿Qué diferencia hay entre un lenguaje de servidor como PHP y JavaScript en el navegador? ¿Qué ventajas tiene que el código se ejecute en el servidor?"
Reflexiona antes de ejecutar El comando instala libapache2-mod-php8.3 además de PHP. ¿Por qué crees que Apache necesita un módulo específico para saber que tiene que procesar los archivos .php?

WordPress necesita varias extensiones para funcionar: gestión de imágenes, caracteres internacionales, conexión a base de datos y más. Este comando las instala todas.

bash
sudo apt install php8.3 libapache2-mod-php8.3 php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip php8.3-intl -y
¿Por qué?

Sin libapache2-mod-php8.3, Apache trataría los archivos .php como texto plano y los enviaría al navegador tal cual — exponiendo el código fuente de WordPress.

Cada extensión cubre una necesidad: php8.3-mysql para conectar con MariaDB, php8.3-gd para procesar imágenes (miniaturas, recortes), php8.3-mbstring para texto en múltiples idiomas, php8.3-zip para instalar plugins desde el panel de WordPress.

bash
php -v

Deberías ver PHP 8.3.x .... Si aparece esa línea, PHP está instalado correctamente.

05

MariaDB — la base de datos

WordPress guarda todo su contenido en una base de datos: páginas, artículos, usuarios, ajustes. MariaDB es el motor que gestiona esa información.

Conceptos de esta fase
Base de datos relacional — Sistema que organiza la información en tablas con filas y columnas, y permite relacionarlas entre sí.
SQL — Structured Query Language. El lenguaje para interactuar con bases de datos: crear tablas, insertar datos, hacer consultas.
Usuario de BD — Cuenta con permisos específicos dentro de la base de datos, independiente del usuario del sistema operativo.
Privilegios — Permisos concretos de un usuario de BD: leer, escribir, crear tablas, borrar bases de datos...
◈ Pregúntale a Claude Code "¿Qué es una base de datos relacional y cómo organiza WordPress su contenido en tablas? ¿Qué diferencia hay entre una base de datos y un sistema de archivos?"
bash
sudo apt install mariadb-server -y
¿Por qué?

MariaDB es un fork de MySQL — fue creado por los mismos desarrolladores originales y es totalmente compatible con él. WordPress pide MySQL pero funciona perfectamente con MariaDB.

Es el motor de base de datos estándar en el stack LAMP (Linux, Apache, MySQL/MariaDB, PHP) que es la base de la mayoría de sitios WordPress en producción.

Reflexiona antes de ejecutar ¿Por qué crees que MariaDB viene con usuarios anónimos y bases de datos de prueba por defecto? ¿Qué riesgo de seguridad representan en un servidor en producción?

Este asistente interactivo te guía para eliminar configuraciones inseguras que vienen por defecto.

bash
sudo mysql_secure_installation

Responde Y a todas las preguntas. Cuando pida contraseña para root de MariaDB, ponle una segura y apúntala — es diferente a la del sistema operativo.

¿Por qué?

MariaDB se instala con configuraciones pensadas para desarrollo local, no para producción: permite conexiones anónimas sin contraseña, incluye una base de datos de prueba accesible por cualquiera y permite login de root desde cualquier host.

En un servidor en internet, dejar estas configuraciones abiertas es un riesgo real. mysql_secure_installation las elimina con un solo proceso guiado.

Reflexiona antes de ejecutar Podrías darle a WordPress acceso directo con el usuario root de MariaDB. ¿Por qué crees que es mejor crear un usuario específico con permisos solo sobre su propia base de datos?

Entramos a MariaDB y creamos todo lo que WordPress necesita para conectarse.

bash
sudo mysql -u root -p

Una vez dentro, ejecuta estos comandos. Cambia TU_CONTRASEÑA por una contraseña segura y apúntala.

sql
CREATE DATABASE wordpress_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'TU_CONTRASEÑA';
GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Apunta estos tres datos: base de datos (wordpress_db), usuario (wp_user) y contraseña. Los necesitarás en la fase 6.

¿Por qué?

Si WordPress usa root de MariaDB y la aplicación sufre una vulnerabilidad, un atacante tendría acceso total a todas las bases de datos del servidor, no solo a la de WordPress. Con un usuario limitado (wp_user), el daño queda contenido.

utf8mb4 es el conjunto de caracteres que soporta emojis y caracteres especiales de todos los idiomas. FLUSH PRIVILEGES obliga a MariaDB a recargar los permisos inmediatamente — sin él, los cambios pueden no aplicarse hasta el siguiente reinicio.

06

WordPress

Descargamos WordPress desde su web oficial, lo colocamos en el servidor, ajustamos los permisos y lo conectamos a la base de datos.

Conceptos de esta fase
CMS — Content Management System. Sistema que permite gestionar contenido web sin escribir código. WordPress es el más usado del mundo.
DocumentRoot — La carpeta del servidor que Apache sirve como raíz del sitio web. Todo lo que está ahí puede ser accedido desde el navegador.
www-data — El usuario con el que corre Apache en Ubuntu. Necesita ser propietario de los archivos de WordPress para leerlos y escribirlos.
Permisos Unix — Sistema que define quién puede leer, escribir o ejecutar cada archivo: el propietario, su grupo, o cualquier usuario.
◈ Pregúntale a Claude Code "¿Qué son los permisos de archivos en Linux? ¿Qué significa el número 755 y por qué es el adecuado para los archivos de un servidor web?"

Descargamos la última versión desde wordpress.org y la colocamos en la carpeta web.

bash
cd /tmp
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
sudo mv wordpress /var/www/html/miweb

Puedes cambiar miweb por el nombre que quieras para la carpeta del sitio.

¿Por qué?

Descargamos en /tmp porque es una carpeta temporal — si algo falla no ensucia el sistema. tar -xzf descomprime el archivo: x extrae, z indica que está comprimido con gzip, f especifica el archivo.

/var/www/html/ es la raíz web por defecto de Apache. Todo lo que colocamos ahí puede ser servido por el servidor web.

Reflexiona antes de ejecutar Apache corre como el usuario www-data. Si los archivos pertenecen a otro usuario, ¿qué crees que pasará cuando WordPress intente crear una carpeta para subir imágenes?

www-data necesita ser propietario de los archivos para que WordPress pueda subir imágenes e instalar plugins desde el panel.

bash
sudo chown -R www-data:www-data /var/www/html/miweb
sudo chmod -R 755 /var/www/html/miweb
¿Por qué?

chown cambia el propietario. -R lo aplica recursivamente a todos los archivos y subcarpetas. El formato usuario:grupo asigna propietario y grupo a la vez.

chmod 755 significa: el propietario puede leer, escribir y ejecutar (7); el grupo y otros solo pueden leer y ejecutar (5). Es el permiso estándar para archivos web: Apache puede leerlos pero usuarios externos no pueden modificarlos.

Reflexiona antes de ejecutar El archivo wp-config.php contiene la contraseña de la base de datos en texto plano. ¿Por qué nunca deberías subir este archivo a un repositorio público de GitHub?

Copiamos el archivo de configuración de ejemplo y editamos los datos de la base de datos que creaste en la fase 5.

bash
sudo cp /var/www/html/miweb/wp-config-sample.php /var/www/html/miweb/wp-config.php
sudo nano /var/www/html/miweb/wp-config.php

Busca estas líneas y cámbia los valores por los de tu base de datos:

php — wp-config.php
define( 'DB_NAME',     'wordpress_db' );
define( 'DB_USER',     'wp_user' );
define( 'DB_PASSWORD', 'TU_CONTRASEÑA' );
define( 'DB_HOST',     'localhost' );

Para guardar en nano: Ctrl+O → Enter → Ctrl+X.

¿Por qué?

WordPress no sabe por arte de magia a qué base de datos conectarse — necesita que se lo digas explícitamente. wp-config.php es el archivo central de configuración: credenciales de BD, claves de seguridad, prefijo de tablas...

Trabajamos con una copia del archivo de ejemplo (no el original) para mantener el original como referencia limpia. DB_HOST es localhost porque la base de datos está en el mismo servidor que WordPress.

07

VirtualHost de Apache

Un VirtualHost le dice a Apache cómo servir tu sitio: qué dominio escuchar y dónde están los archivos. Es el archivo que conecta el dominio con WordPress.

Conceptos de esta fase
VirtualHost — Configuración de Apache que define cómo servir un sitio concreto. Un mismo servidor puede tener múltiples VirtualHosts para múltiples dominios.
DNS — Domain Name System. El sistema que traduce nombres de dominio (wp.puchilabs.jesusmagamu.dev) a direcciones IP.
Módulo rewrite — Extensión de Apache que permite reescribir URLs. WordPress lo necesita para las URLs amigables (en lugar de ?p=123, usa /mi-articulo/).
.htaccess — Archivo de configuración de Apache a nivel de carpeta. WordPress lo usa para gestionar sus URLs.
◈ Pregúntale a Claude Code "¿Cómo funciona el DNS? ¿Qué ocurre exactamente cuando un navegador resuelve un nombre de dominio antes de conectarse al servidor?"
Reflexiona antes de ejecutar Apache puede servir múltiples sitios desde un mismo servidor. ¿Cómo crees que sabe a cuál de ellos debe responder cuando llega una petición a un dominio concreto?

Crea el archivo de configuración para tu sitio.

bash
sudo nano /etc/apache2/sites-available/miweb.conf

Escribe este contenido en el archivo:

apache — miweb.conf
<VirtualHost *:80>
    ServerName wp.puchilabs.jesusmagamu.dev
    DocumentRoot /var/www/html/miweb

    <Directory /var/www/html/miweb>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/miweb-error.log
    CustomLog ${APACHE_LOG_DIR}/miweb-access.log combined
</VirtualHost>

Para guardar en nano: Ctrl+O → Enter → Ctrl+X.

¿Por qué?

Apache distingue entre sitios por el ServerName: cuando llega una petición para wp.puchilabs.jesusmagamu.dev, busca el VirtualHost que tiene ese nombre y sirve el contenido de su DocumentRoot.

AllowOverride All es clave para WordPress: le permite usar su archivo .htaccess para reescribir URLs. Sin esto, solo funcionaría la portada del sitio — cualquier otra URL daría 404.

Los logs separados por sitio (ErrorLog, CustomLog) permiten depurar problemas de un sitio sin mezclar los mensajes de otros.

a2ensite activa el sitio. a2enmod rewrite activa las URLs amigables. a2dissite desactiva la página de bienvenida por defecto.

bash
sudo a2ensite miweb.conf
sudo a2enmod rewrite
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
¿Por qué?

a2ensite y a2dissite crean y eliminan enlaces simbólicos en /etc/apache2/sites-enabled/. Apache solo carga los sitios de esa carpeta — los de sites-available son plantillas disponibles pero no activas.

Desactivar el sitio por defecto (000-default.conf) evita que Apache sirva la página de bienvenida genérica cuando el dominio no coincide con ningún VirtualHost configurado.

reload recarga la configuración sin detener el servidor — las conexiones activas no se interrumpen.

08

HTTPS con Certbot

Certbot obtiene e instala un certificado SSL gratuito de Let's Encrypt. Con esto tu web pasa a HTTPS: conexión cifrada y el candado verde en el navegador.

Conceptos de esta fase
SSL/TLS — Protocolo de cifrado que protege la comunicación entre el navegador y el servidor. HTTPS es HTTP sobre TLS.
Certificado digital — Documento electrónico que verifica que un dominio pertenece a quien dice. Lo firma una autoridad de certificación.
Let's Encrypt — Autoridad de certificación gratuita y automática, respaldada por Mozilla, EFF y otras organizaciones.
Certbot — Herramienta oficial de Let's Encrypt que automatiza la obtención, instalación y renovación de certificados.
◈ Pregúntale a Claude Code "¿Cómo funciona el cifrado TLS? ¿Qué es un certificado digital y cómo verifica el navegador que es auténtico?"
bash
sudo apt install certbot python3-certbot-apache -y
¿Por qué?

certbot es la herramienta principal. python3-certbot-apache es el plugin específico para Apache: sabe cómo modificar la configuración de Apache automáticamente para activar HTTPS y redirigir el tráfico HTTP.

Reflexiona antes de ejecutar Para emitir un certificado, Let's Encrypt necesita verificar que tú controlas el dominio. ¿Cómo crees que puede comprobarlo? ¿Por qué el dominio debe estar apuntando al servidor antes de ejecutar este comando?

Certbot se conecta a Let's Encrypt, verifica el dominio y configura Apache automáticamente para usar HTTPS.

bash
sudo certbot --apache -d wp.puchilabs.jesusmagamu.dev

Te pedirá un email para avisos de renovación y que aceptes los términos. La renovación del certificado es automática — Certbot instala un timer que la gestiona solo.

¿Por qué?

Let's Encrypt verifica que controlas el dominio con un "challenge": coloca un archivo en tu servidor y comprueba que puede acceder a él desde internet a través del dominio. Por eso el dominio tiene que apuntar ya a la IP del servidor.

Una vez obtenido el certificado, Certbot modifica el VirtualHost de Apache para escuchar también en el puerto 443 (HTTPS) y añade una regla de redirección para que todo el tráfico HTTP vaya a HTTPS automáticamente.

Los certificados de Let's Encrypt caducan cada 90 días. Certbot instala un temporizador del sistema que los renueva automáticamente antes de que expiren.

09

Instalación final

Todo está listo en el servidor. El último paso es el asistente de WordPress en el navegador.

Abre el dominio en el navegador. WordPress detecta que es una instalación nueva y muestra el asistente de configuración.

url
https://wp.puchilabs.jesusmagamu.dev

El asistente te pedirá: idioma, nombre del sitio, usuario administrador y contraseña. Apunta bien las credenciales de administrador.

Una vez completada la instalación, entra al panel con el usuario que acabas de crear.

url
https://wp.puchilabs.jesusmagamu.dev/wp-admin

Si ves el dashboard de WordPress, lo has conseguido. Has instalado WordPress en un servidor real desde cero.