De cero a WordPress en producción, paso a paso.
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.
65.21.4.123.Desde tu terminal, este comando abre una conexión segura con el servidor. Sustituye TU_IP por la dirección que te dio Puchito.
ssh root@TU_IP
La primera vez te preguntará si confías en el servidor. Escribe yes y pulsa Enter.
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.
&&. ¿Qué crees que hace cada uno? ¿Qué diferencia hay entre "actualizar la lista" y "actualizar los paquetes"?
apt update && apt upgrade -y
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.
Trabajar siempre como root es peligroso. Crearemos un usuario propio con permisos de administrador y configuraremos el firewall.
Crea un usuario con tu nombre. El sistema te pedirá una contraseña — ponle una segura y apúntala.
adduser puchita
Las preguntas sobre nombre completo, teléfono, etc. puedes dejarlas en blanco pulsando Enter.
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.
usermod -aG sudo puchita
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.
Instalamos UFW, definimos las reglas y lo activamos. El orden de los comandos es importante.
apt install ufw -y ufw allow OpenSSH ufw allow 'Apache Full' ufw enable
ufw status
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.
su - puchita
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.
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.
sudo apt install apache2 -y
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.
Comprueba que Apache está en marcha y pruébalo en el navegador.
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.
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.
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.
libapache2-mod-php es el que le dice a Apache cómo procesar archivos PHP.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.
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
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.
php -v
Deberías ver PHP 8.3.x .... Si aparece esa línea, PHP está instalado correctamente.
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.
sudo apt install mariadb-server -y
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.
Este asistente interactivo te guía para eliminar configuraciones inseguras que vienen por defecto.
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.
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.
Entramos a MariaDB y creamos todo lo que WordPress necesita para conectarse.
sudo mysql -u root -p
Una vez dentro, ejecuta estos comandos. Cambia TU_CONTRASEÑA por una contraseña segura y apúntala.
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.
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.
Descargamos WordPress desde su web oficial, lo colocamos en el servidor, ajustamos los permisos y lo conectamos a la base de datos.
Descargamos la última versión desde wordpress.org y la colocamos en la carpeta web.
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.
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.
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.
sudo chown -R www-data:www-data /var/www/html/miweb sudo chmod -R 755 /var/www/html/miweb
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.
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.
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:
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.
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.
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.
wp.puchilabs.jesusmagamu.dev) a direcciones IP.?p=123, usa /mi-articulo/).Crea el archivo de configuración para tu sitio.
sudo nano /etc/apache2/sites-available/miweb.conf
Escribe este contenido en el archivo:
<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.
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.
sudo a2ensite miweb.conf sudo a2enmod rewrite sudo a2dissite 000-default.conf sudo systemctl reload apache2
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.
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.
sudo apt install certbot python3-certbot-apache -y
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.
Certbot se conecta a Let's Encrypt, verifica el dominio y configura Apache automáticamente para usar HTTPS.
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.
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.
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.
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.
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.
Has instalado WordPress en un servidor real, desde cero. SSH, firewall, Apache, PHP, MariaDB, WordPress y HTTPS. Eso no lo hace cualquiera.