Cómo montar un servidor web con Apache en Ubuntu

Montar tu propio servidor web es el mejor ejercicio práctico para aprender Linux, y con Apache en Ubuntu se hace en un cuarto de hora. Al final de esta guía tendrás un sitio sirviendo páginas con su propio dominio, un certificado SSL gratuito que se renueva solo y las nociones necesarias para diagnosticar los errores más habituales. Los comandos sirven para Ubuntu 22.04 y 24.04 LTS, y funcionan casi igual en Debian.
Qué necesitas: un servidor o máquina virtual con Ubuntu, un usuario con permisos de sudo, acceso por SSH y, si quieres publicarlo en Internet, un dominio cuyo DNS puedas modificar. Si aún no tienes el sistema a punto, empieza por esta lista de primeros pasos tras instalar Ubuntu 24.04.
1. Instalar Apache
sudo apt update
sudo apt install apache2 -y
apache2 -v # versión instalada
systemctl status apache2 # debe decir active (running)
Abre http://IP-de-tu-servidor en el navegador: si ves la página «Apache2 Ubuntu Default Page», ya está sirviendo. Si no la ves y estás en un servidor remoto, el culpable casi seguro es el cortafuegos, que configuramos a continuación.
2. Abrir el cortafuegos
sudo ufw allow OpenSSH # IMPORTANTE: antes de activar, o perderás el acceso por SSH
sudo ufw allow 'Apache Full' # puertos 80 (HTTP) y 443 (HTTPS)
sudo ufw enable
sudo ufw status
El orden importa: si activas UFW sin permitir antes SSH en un servidor al que accedes de forma remota, te quedarás fuera. Si solo quieres abrir el puerto 80 de momento (hasta tener el certificado), usa el perfil 'Apache' en lugar de 'Apache Full'.
3. Cómo está organizado Apache en Ubuntu
Conocer la estructura te ahorra muchas búsquedas. Apache en Debian y Ubuntu separa la configuración en carpetas con una lógica de «disponible» y «activo»:
/etc/apache2/apache2.conf: configuración principal./etc/apache2/sites-available/ysites-enabled/: los sitios (VirtualHosts) que existen y los que están activos. Se activan con enlaces simbólicos que gestionaa2ensite./etc/apache2/mods-available/ymods-enabled/: módulos, que se activan cona2enmody se desactivan cona2dismod./etc/apache2/conf-available/yconf-enabled/: ajustes generales, cona2enconfya2disconf./var/www/: donde suelen ir los archivos de los sitios./var/log/apache2/: los registros de acceso y de errores.
4. Crear tu primer sitio con VirtualHost
Los VirtualHosts permiten alojar varios sitios en el mismo servidor, cada uno con su dominio. Crea la carpeta del sitio y una página de prueba:
sudo mkdir -p /var/www/misitio.com/html
echo '<h1>Funciona</h1>' | sudo tee /var/www/misitio.com/html/index.html
sudo chown -R $USER:www-data /var/www/misitio.com
sudo find /var/www/misitio.com -type d -exec chmod 755 {} \;
sudo find /var/www/misitio.com -type f -exec chmod 644 {} \;
Con ese reparto de propietario y permisos, tu usuario puede editar los archivos y Apache (que corre como www-data) puede leerlos, pero no modificarlos, lo que limita el daño si un script del sitio es explotado. Ahora la configuración del VirtualHost:
sudo nano /etc/apache2/sites-available/misitio.com.conf
<VirtualHost *:80>
ServerName misitio.com
ServerAlias www.misitio.com
DocumentRoot /var/www/misitio.com/html
<Directory /var/www/misitio.com/html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/misitio-error.log
CustomLog ${APACHE_LOG_DIR}/misitio-access.log combined
</VirtualHost>
Las opciones del bloque Directory merecen una explicación: -Indexes evita que se muestre el listado de archivos cuando no hay un index.html, AllowOverride All permite usar archivos .htaccess (imprescindible para muchos CMS, como WordPress) y Require all granted autoriza el acceso. Activa el sitio y comprueba la sintaxis antes de recargar:
sudo a2ensite misitio.com.conf
sudo a2dissite 000-default.conf
sudo apache2ctl configtest # Syntax OK = todo bien
sudo systemctl reload apache2
sudo apache2ctl -S # lista los VirtualHosts que Apache ha cargado
Prefiere reload a restart: recarga la configuración sin cortar las conexiones activas.
5. Apuntar el dominio y probar
En el panel DNS de tu dominio crea un registro A para misitio.com y otro para www (o un CNAME) con la IP pública del servidor. La propagación puede tardar desde minutos hasta unas horas. Compruébalo con:
dig +short misitio.com # (instala dnsutils si no tienes dig)
curl -I http://misitio.com
¿Quieres probar el sitio antes de que el DNS esté listo? Puedes forzar el nombre en tu equipo con el archivo hosts, como explicamos en la guía sobre el archivo hosts de Windows, o usar curl --resolve misitio.com:80:IP-del-servidor http://misitio.com.
6. SSL gratis con Let’s Encrypt
Con el dominio ya apuntando a la IP del servidor y el puerto 80 accesible desde Internet:
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d misitio.com -d www.misitio.com
Certbot te pregunta un correo de contacto, configura HTTPS, ofrece redirigir todo el tráfico HTTP a HTTPS (acepta) y programa la renovación automática del certificado, que dura 90 días. Compruébala con:
sudo certbot renew --dry-run # simula la renovación
systemctl list-timers | grep certbot # el temporizador que la lanza
Si la renovación fallara, recibirás avisos por correo cuando el certificado esté a punto de caducar. Es buena idea comprobar el estado del certificado desde el navegador y no depender solo de esos avisos.
7. Ajustes básicos de seguridad
Con tres cambios reduces la información que Apache revela y refuerzas lo esencial. Edita /etc/apache2/conf-available/security.conf:
ServerTokens Prod
ServerSignature Off
Esto evita que Apache anuncie su versión exacta en las cabeceras y en las páginas de error. Después, activa el módulo de cabeceras y añade protecciones sencillas en tu VirtualHost:
sudo a2enmod headers
# Dentro del VirtualHost:
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Además, mantén el sistema actualizado (sudo apt update && sudo apt upgrade), desactiva los módulos que no uses y considera instalar fail2ban para bloquear direcciones que intenten adivinar contraseñas. Si el servidor admite conexiones SSH, protégelo con claves en lugar de contraseñas y sigue las buenas prácticas de nuestra guía para crear contraseñas seguras.
8. Dónde mirar cuando algo falla
sudo tail -f /var/log/apache2/error.log: el registro de errores en vivo (y el del sitio,misitio-error.log).sudo apache2ctl configtest: detecta errores de sintaxis antes de recargar.sudo apache2ctl -S: muestra qué VirtualHost atiende cada nombre.sudo ss -tulpn | grep ':80': comprueba qué proceso escucha en el puerto 80.
Los problemas más comunes:
- AH00558: Could not reliably determine the server’s fully qualified domain name: es solo un aviso. Se quita con
echo "ServerName localhost" | sudo tee /etc/apache2/conf-available/servername.confysudo a2enconf servername. - Sigue saliendo la página por defecto: el sitio no está activado, falta recargar o el
ServerNameno coincide con el dominio que visitas. Revisaapache2ctl -S. - Error 403 Forbidden: permisos incorrectos en la carpeta (el usuario
www-datadebe poder leer los archivos y atravesar los directorios), faltaRequire all grantedo no hayindex.htmlcon-Indexesactivo. - Address already in use: … :80: otro servicio (por ejemplo, Nginx) ya usa el puerto. Identifícalo con el comando
ssde arriba. - Página en blanco tras un cambio: revisa el registro de errores; casi siempre es un permiso o un error de sintaxis en un archivo de configuración.
9. Mantenimiento: registros y copias
Ubuntu rota los registros de Apache automáticamente con logrotate, así que no se llenarán el disco por sí solos. Para las copias de seguridad de tus sitios y bases de datos, programa un script con cron y guarda las copias fuera del propio servidor. Y para moverte con soltura por el sistema mientras administras el servidor, repasa los comandos básicos de la terminal de Linux.
El siguiente paso: PHP y base de datos
Si quieres alojar WordPress u otra aplicación, necesitarás PHP y una base de datos. La base es sencilla:
sudo apt install php libapache2-mod-php php-mysql php-curl php-gd php-mbstring php-xml php-zip -y
sudo a2enmod rewrite
sudo systemctl restart apache2
Para comprobar que PHP funciona, crea un archivo temporal con <?php phpinfo();, ábrelo en el navegador y bórralo en cuanto termines: muestra información sensible sobre el servidor.
Preguntas frecuentes
¿Apache o Nginx?
Ambos son excelentes. Apache destaca por su flexibilidad (archivos .htaccess, muchísimos módulos y documentación) y es la opción más cómoda para empezar y para CMS como WordPress. Nginx suele rendir mejor con muchas conexiones simultáneas. Aprende primero uno; los conceptos se trasladan al otro.
¿Qué diferencia hay entre reload y restart?
reload vuelve a leer la configuración sin cortar las conexiones activas; restart detiene y arranca el servicio, con una pequeña interrupción. Usa reload salvo que cambies módulos o ajustes que lo exijan.
¿Puedo alojar varios sitios en el mismo servidor?
Sí: crea un archivo en sites-available por cada dominio, con su propio ServerName y DocumentRoot, y actívalos con a2ensite.
Conclusión
Con Apache instalado, el cortafuegos abierto, un VirtualHost limpio con permisos correctos y SSL automático, tienes una base de hosting profesional. Añade los ajustes de seguridad básicos, aprende a leer los registros y programa tus copias, y estarás listo para el siguiente paso: instalar PHP y una base de datos para alojar tu primera aplicación.