¡Hola a todos!
En el día a día de un desarrollador PHP, es muy común necesitar un entorno rápido para pruebas, prototipado o incluso para alojar una aplicación de bajo tráfico. Y, muchas veces, queremos algo que sea fácil de configurar, sin la complejidad de SSH Keys o configuraciones avanzadas desde el principio.
Pensando en esto, ¡Azure surge como una herramienta poderosa y accesible para crear máquinas virtuales en pocos minutos!
En este post, vamos a desmitificar el proceso de creación de una Máquina Virtual en Azure con Debian 12 (Bookworm), la versión disponible en las imágenes de Azure, configurando un entorno completo con Apache, PHP 8.5 y los drivers para conexión con SQL Server.
Además, vamos a optimizar el rendimiento y la seguridad con OPcache, UFW, fail2ban y consejos de Cloudflare, incluyendo cómo activar el caché de páginas HTML.
Prepárate para tener tu entorno web funcionando en minutos, con todo lo que necesitas para conectar tus aplicaciones PHP a SQL Server o MySQL/MariaDB, y además con ese toque de rendimiento que marca la diferencia. ¡Así que, vamos allá!
Creando la base de demostración en Azure
Creando una cuenta gratuita en Azure
Si aún no tienes una cuenta en Azure, excelente noticia: Microsoft ofrece una cuenta gratuita con USD 200 en créditos para usar en los primeros 30 días, además de más de 55 servicios gratuitos por 12 meses, más que suficiente para este tutorial.
Para crear tu cuenta gratuita:
- Accede a azure.microsoft.com/free y haz clic en "Probar gratis".
- Inicia sesión con tu cuenta de Microsoft (Outlook, Hotmail, Xbox) — o haz clic en "Crear una" si no tienes.
- Completa tus datos personales: nombre completo, país y fecha de nacimiento.
- Proporciona un número de teléfono para recibir el código de verificación.
- Proporciona una tarjeta de crédito o débito. Se exige solo para verificar que eres una persona real y no genera cargos automáticos.
- Acepta los términos y haz clic en "Registrarse". En unos segundos tendrás acceso al portal.
La tarjeta se utiliza solo para la verificación de identidad. No se te cobrará mientras estés dentro de los límites de la cuenta gratuita y no realices una actualización manual a una suscripción de pago. Después de los primeros 30 días, los créditos de USD 200 caducan, pero los servicios marcados como "gratuitos por 12 meses" siguen disponibles sin costo.
Creando la Máquina Virtual en Azure
Con tu cuenta creada, accede a portal.azure.com y sigue los pasos a continuación para crear tu máquina virtual:
- En la barra de búsqueda, escribe "Máquinas virtuales" y selecciona la opción.
- Haz clic en "Crear" y luego en "Máquina virtual de Azure".
- Completa la información básica:
- Suscripción: Elige tu suscripción.
- Grupo de recursos: Crea uno nuevo (ej:
rg-webserver) o usa uno existente. - Nombre de la máquina virtual: Un nombre que tenga sentido (ej:
vm-debian-web). - Región: Elige la región más cercana a ti o a tus usuarios.
- Opciones de disponibilidad: Déjalo como "Ninguna redundancia de infraestructura necesaria".
- Tipo de seguridad: Déjalo en "Estándar".
- Imagen: Busca y selecciona "Debian 12 (Bookworm)".
- Tamaño: Elige un tamaño que satisfaga tus necesidades. Para pruebas, un
Standard_B1s(1 vCPU, 1 GB RAM) ya es suficiente para proyectos pequeños.
- En "Cuenta de administrador", aquí está el truco para quien no quiere complicaciones con SSH Keys:
- Tipo de autenticación: Selecciona "Contraseña".
- Nombre de usuario: Crea un nombre de usuario (ej:
dirceu). - Contraseña: Crea una contraseña segura y anótala, ya que la necesitarás para acceder a la VM.
- En "Reglas de puerto de entrada públicas", selecciona "Permitir puertos seleccionados" y elige "HTTP (80)", "HTTPS (443)" y "SSH (22)". El puerto SSH es necesario para acceder a la VM vía terminal.
- Haz clic en "Revisar + crear" y, tras la validación, en "Crear".

Espera unos minutos mientras Azure aprovisiona tu máquina virtual. Una vez que esté lista, tendrás una IP pública para acceder a ella. ¡Anota esa IP!
Configurando una IP pública estática
Por defecto, Azure asigna una IP pública dinámica a la VM, lo que significa que cambia cada vez que la VM se reinicia. Cuando esto sucede, pierdes el acceso SSH, el DNS de Cloudflare queda apuntando a la IP incorrecta y necesitas actualizar todo de nuevo. Por eso, el primer paso es hacer que la IP sea estática.
- En la página de tu VM en Azure, haz clic en el nombre de la IP pública que aparece en el panel de información general (algo como
vm-debian-web-ip). - En el menú lateral, haz clic en "Configuración" (Configuration).
- En "Asignación", cambia de "Dinámica" a "Estática".
- Haz clic en "Guardar".


La IP que aparece en pantalla ahora es permanente y no cambiará aunque reinicies, apagues o redimensiones la VM. Anota esta IP, ya que la usarás en el NSG, en el DNS de Cloudflare y en las configuraciones de FileZilla/PuTTY.
Liberando el acceso SSH en el NSG (Network Security Group)
Antes de conectarte a la VM, vale la pena comprobar si el NSG (Network Security Group), el firewall de red de Azure, está permitiendo conexiones SSH desde tu IP. El NSG se crea junto con la VM, pero la regla SSH puede estar abierta para cualquier IP del mundo, lo cual es un riesgo de seguridad, o puede ni siquiera existir.
Lo recomendado es restringir el SSH solo a tu IP. Mira cómo:
1. Descubre tu IP pública actual
Antes de tocar el NSG, necesitas saber cuál es tu IP pública actual, que es la IP que Azure "verá" cuando intentes conectarte. Accede a uno de los sitios a continuación y anota el IPv4:
Si tu proveedor de internet usa IP dinámica (que es el caso en la mayoría de las conexiones residenciales), tu IP puede cambiar periódicamente. Siempre que pierdas el acceso SSH, verifica si tu IP cambió y actualiza la regla en el NSG.
2. Accede al NSG en el portal de Azure
- En portal.azure.com, accede a tu VM y, en el menú lateral izquierdo, haz clic en "Redes" (o "Networking").
- Haz clic en el nombre del NSG que se muestra junto a "Grupo de seguridad de red" — normalmente algo como
vm-debian-web-nsg. - En el menú lateral del NSG, haz clic en "Reglas de seguridad de entrada" (Inbound security rules).
3. Edita (o crea) la regla de SSH
Busca una regla existente con puerto de destino 22 y protocolo TCP. Si existe y tiene como origen Any o *, haz clic en ella para editarla. Si no existe, haz clic en "+ Agregar" para crear una nueva.
Completa los campos:
- Origen: selecciona "Direcciones IP"
- Direcciones IP / rangos CIDR de origen: pega tu IP pública seguida de
/32(ej:177.90.45.123/32). El/32significa "solo esta IP específica". - Rangos de puertos de destino:
22 - Protocolo: TCP
- Acción: Permitir
- Prioridad: un número bajo (ej:
300) garantiza que esta regla se evalúe antes que otras más genéricas. - Nombre: algo descriptivo, como
Allow-SSH-MiIP.
Haz clic en "Guardar". La regla entrará en vigor en unos segundos.



Si tu empresa o escuela usa una red corporativa con NAT, es posible que necesites liberar un rango de IPs en lugar de una sola dirección. En ese caso, consulta al administrador de red para obtener el bloque CIDR correcto (ej: 200.155.10.0/24).
Nunca dejes SSH abierto al mundo
Evita mantener la regla SSH con origen Any (0.0.0.0/0). Los servidores con SSH expuesto a internet reciben intentos de invasión automatizados (fuerza bruta) en cuestión de minutos después de su creación. Restringirlo a tu IP elimina prácticamente el 100% de estos intentos.
Accediendo a la VM vía SSH
Con la VM creada y la IP pública en mano (la encuentras en la página de detalles de la VM en Azure, en "IP pública"), es hora de conectarse a ella. La conexión es vía SSH, protocolo que cifra toda la comunicación con el servidor. Las opciones dependen de tu sistema operativo:
Opción 1: PuTTY (recomendado para principiantes en Windows)
PuTTY es un cliente SSH gratuito con interfaz gráfica, muy popular entre los usuarios de Windows. Para instalarlo y conectarte:
- Accede a chiark.greenend.org.uk/~sgtatham/putty/latest.html y descarga el instalador
putty-64bit-X.XX-installer.msi. - Ejecuta el instalador y haz clic en "Next" hasta finalizar.
- Abre PuTTY. En el campo "Host Name (or IP address)", pega la IP pública de tu VM en Azure.
- Confirma que el puerto sea 22 y el tipo de conexión sea SSH.
- Consejo: en el campo "Saved Sessions", dale un nombre a la conexión (ej:
vm-azure) y haz clic en "Save" — así no tendrás que escribir la IP cada vez. - Haz clic en "Open".
- En la primera conexión, PuTTY muestra un aviso sobre la clave del servidor — haz clic en "Accept". Esto es normal y esperado.
- En la ventana negra que se abra, escribe tu nombre de usuario (el que creaste en Azure) y presiona Enter.
- Escribe tu contraseña — los caracteres no aparecen en pantalla mientras escribes, esto es intencional — y presiona Enter.
¡Estás dentro de la VM! El terminal mostrará algo como tu_usuario@vm-debian-web:~$, confirmando la conexión exitosa.
Si vas a utilizar mRemoteNG, la pantalla de conexión se verá así:

Opción 2: Terminal nativo (Linux, macOS o Windows 10+)
En Linux, macOS y Windows 10/11 (PowerShell o Terminal de Windows), SSH ya está disponible sin necesidad de instalar nada. Abre el terminal y ejecuta:
ssh seu_usuario@IP_PUBLICO_DA_VM
En la primera conexión, confirma con yes cuando se te pregunte sobre la autenticidad del host. Luego, ingresa tu contraseña. Una vez conectado, ¡vamos a empezar!
Preparando el sistema
Con la conexión establecida, eleva los privilegios al usuario root para facilitar las instalaciones:
sudo su
A continuación, actualiza los repositorios para garantizar que estamos instalando las versiones más recientes de los paquetes:
apt-get update
Resultado: Tu entorno está listo para recibir el software que necesitamos.
Instalando y configurando Apache
Ahora vamos a instalar el servidor web Apache y algunas dependencias importantes para PHP y otras funcionalidades.
Utiliza el script a continuación:
# Instalar Apache y dependencias
apt-get --yes install build-essential autoconf flex bison
apt-get --yes install apache2 apache2-dev libapache2-mod-evasive apache2-utils
apt-get --yes install libpng-dev
apt-get --yes install zlib1g zlib1g-dev libxml2 libxml2-dev
apt-get --yes install openssl libssl-dev
apt-get --yes install libgd-dev
apt-get --yes install vim curl libcurl4 libcurl4-openssl-dev
apt-get --yes install libfreetype6-dev libreadline-dev sqlite3
apt-get --yes install rpl zip libzip-dev libbz2-dev unzip libldap2-dev pwgen
apt-get --yes install unixodbc unixodbc-dev s3cmd
Paquetes eliminados en Debian 12
Los paquetes libssl1.1, libmcrypt-dev, libmcrypt4, mcrypt, libgdchart-gd2-xpm y libaio1 no existen en Debian 12 (Bookworm) y causarán errores de instalación. OpenSSL 3.x ya está cubierto por libssl-dev incluido en la lista anterior.
Resultado: Apache y sus dependencias esenciales están instalados. Ya puedes acceder a la IP pública de tu VM en el navegador y verás la página predeterminada de Apache ("Apache2 Debian Default Page").
Habilitando .htaccess y Módulos
Para que Apache funcione correctamente con aplicaciones PHP como WordPress, necesitamos habilitar el uso de archivos .htaccess y algunos módulos importantes.
Para habilitar .htaccess y aumentar el límite de la línea de solicitud:
# Habilitar htaccess y enlaces simbólicos
rpl -e "\n\tOptions Indexes FollowSymLinks\n\tAllowOverride None" \
"\n\tOptions FollowSymLinks\n\tAllowOverride All" \
/etc/apache2/apache2.conf
echo "LimitRequestLine 100000" >> /etc/apache2/apache2.conf
El comando rpl es una herramienta para sustitución de texto en archivos, similar a sed, pero con una sintaxis más amigable. Sustituye la configuración predeterminada de Apache para permitir AllowOverride All, que habilita .htaccess.
Ahora, vamos a habilitar los módulos de Apache que son cruciales para el rendimiento y la reescritura de URLs:
# Habilitar módulos de Apache
a2dismod mpm_event
a2dismod mpm_worker
a2enmod mpm_prefork
a2enmod rewrite
a2enmod headers
Resultado: Apache está configurado para usar el módulo mpm_prefork (necesario para funcionar con mod_php), y los módulos de reescritura y encabezados están activos, permitiendo URLs amigables y manipulación de HTTP headers.
Instalando y configurando PHP 8.5
¡Ha llegado el momento de instalar PHP! Vamos a utilizar la versión 8.5, lanzada en noviembre de 2025, que es la más reciente y trae mejoras de rendimiento y nuevas funcionalidades en comparación con las versiones anteriores. Para ello, vamos a añadir el repositorio de paquetes de Ondřej Surý, quien mantiene versiones actualizadas de PHP para Debian/Ubuntu.
Primero, añade la clave GPG y el repositorio:
# Añadir repositorio PHP (Ondřej Surý) — método moderno sin apt-key
apt install apt-transport-https lsb-release ca-certificates curl gnupg -y
curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" \
| tee /etc/apt/sources.list.d/php.list
apt update
El método con signed-by es la forma actual y recomendada de añadir repositorios externos en Debian/Ubuntu. El antiguo apt-key add ha sido marcado como obsoleto (deprecated) y será eliminado en versiones futuras de APT.
Ahora instala PHP 8.5 y las extensiones necesarias:
# Instalar PHP 8.5 y extensiones
apt install php8.5 php8.5-cli php8.5-{bz2,curl,mbstring,intl,xml,gd,zip,mysql,opcache,readline} -y
apt install php-pear wget git php-cgi php-common php-net-socket -y
Además de las extensiones básicas, ya instalamos php8.5-opcache. OPcache es un acelerador de bytecode nativo de PHP que almacena el código compilado en memoria, eliminando la necesidad de recompilar los scripts en cada solicitud. En aplicaciones PHP reales, la ganancia de rendimiento suele estar entre 3x y 5x, y ya viene integrado en PHP sin costo alguno.
Con OPcache instalado, vamos a configurarlo de forma optimizada. Ejecuta el comando a continuación para crear o reemplazar el archivo de configuración de una vez, sin necesidad de abrir un editor de texto:
cat > /etc/php/8.5/mods-available/opcache.ini << 'EOF'
zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=0
EOF
Ahora, vamos a integrar PHP 8.5 con Apache usando el módulo mod_php:
# Instalar mod_php para Apache
apt install libapache2-mod-php8.5 -y
a2enmod php8.5
# Reiniciar Apache para cargar el módulo
systemctl restart apache2
Resultado: PHP 8.5 está instalado y configurado para funcionar con Apache. ¡Tus aplicaciones PHP ya pueden ejecutarse!
Para verificar la versión de PHP y los módulos cargados, puedes usar:
php -v
php -m
Resultado: Verás la versión de PHP 8.5 y una lista de todos los módulos activos, incluyendo OPcache.
Conectando PHP a SQL Server (ODBC)
¡Esta es la cereza del pastel para quienes trabajan con SQL Server! Vamos a instalar los drivers ODBC de Microsoft para que PHP pueda comunicarse con SQL Server, ya sea en Azure, on-premises o en otro servidor.
Atención: repositorio correcto para Debian
Los drivers ODBC de Microsoft tienen repositorios específicos por distribución. Utiliza siempre el repositorio para Debian — nunca el de Ubuntu — para evitar incompatibilidades de paquetes y fallos de instalación silenciosos.
Para instalar los drivers ODBC:
# Añadir clave GPG y repositorio Microsoft para Debian
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \
| gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
curl -s https://packages.microsoft.com/config/debian/12/prod.list \
| tee /etc/apt/sources.list.d/mssql-release.list
apt-get update
# Instalar drivers ODBC y herramientas de línea de comandos
ACCEPT_EULA=Y apt-get -y install msodbcsql18 mssql-tools18
# Añadir herramientas al PATH
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc
# Instalar dependencias de compilación para PECL (headers de PHP 8.5 + extensión XML)
apt install php8.5-dev php8.5-xml -y
# Instalar extensiones PHP para SQL Server vía PECL
# PHP_PEAR_PHP_BIN garantiza que pecl use PHP 8.5, no el PHP predeterminado del sistema
export PHP_PEAR_PHP_BIN=/usr/bin/php8.5
pecl channel-update pecl.php.net
pecl install sqlsrv
pecl install pdo_sqlsrv
El paquete php8.5-dev proporciona los headers de compilación necesarios para que PECL construya extensiones nativas. php8.5-xml es obligatorio para que el propio PEAR funcione. La variable PHP_PEAR_PHP_BIN instruye a PECL a usar específicamente PHP 8.5 como base de compilación. Sin ella, PECL usa el PHP predeterminado del sistema (que puede ser una versión diferente) y falla con el error "XML Extension not found".
Habilitando los drivers en PHP.ini
Después de instalar los drivers vía PECL, necesitamos informar a PHP que deben ser cargados. En Debian con el repositorio de Ondřej Surý, la forma correcta es crear los archivos en mods-available y usar phpenmod, que habilita la extensión para todos los SAPIs (CLI, Apache, FPM) de una vez.
# Crear los archivos de configuración de las extensiones
echo "extension=sqlsrv.so" > /etc/php/8.5/mods-available/sqlsrv.ini
echo "extension=pdo_sqlsrv.so" > /etc/php/8.5/mods-available/pdo_sqlsrv.ini
# Habilitar para todos los SAPIs de PHP 8.5 (crea symlinks en cli/conf.d, apache2/conf.d, etc.)
phpenmod -v 8.5 sqlsrv pdo_sqlsrv
phpenmod es la herramienta nativa de Debian para activar extensiones PHP. Crea automáticamente los symlinks en los directorios conf.d de cada SAPI instalado (CLI, Apache, FPM), sin necesidad de descubrir la ruta manualmente. Es equivalente a a2enmod, pero para extensiones PHP.
Para que los cambios tengan efecto, reinicia Apache:
systemctl restart apache2
Resultado: ¡Tu PHP ahora está listo para conectarse a SQL Server! Para confirmar, crea un archivo /var/www/html/phpinfo.php con el contenido <?php phpinfo(); ?> y accede a él en el navegador. Verifica si las secciones sqlsrv, pdo_sqlsrv y opcache aparecen listadas.
Seguridad: Tras validar la instalación, elimina inmediatamente el archivo phpinfo.php del servidor. Este archivo expone información sensible sobre el entorno (versión de PHP, módulos, configuraciones, rutas) y no debe quedar accesible públicamente.
Probando la conexión PHP → SQL Server
Además de phpinfo(), vale la pena hacer una prueba real de conexión. Crea el archivo a continuación (sustituye los datos de conexión por los tuyos):
nano /var/www/html/test-sqlsrv.php
<?php
$servidor = 'SEU_SERVIDOR.database.windows.net'; // o IP del SQL Server
$usuario = 'seu_login';
$senha = 'SuaSenha@123';
$banco = 'seu_banco';
$conn = sqlsrv_connect($servidor, [
'Database' => $banco,
'UID' => $usuario,
'PWD' => $senha,
'TrustServerCertificate' => true,
]);
if ($conn === false) {
echo '<h2>ERRO na conexão:</h2><pre>';
print_r(sqlsrv_errors());
echo '</pre>';
} else {
echo '<h2>✅ Conexão bem-sucedida!</h2>';
$result = sqlsrv_query($conn, 'SELECT @@VERSION AS versao');
$row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC);
echo '<p>' . htmlspecialchars($row['versao']) . '</p>';
sqlsrv_close($conn);
}
?>
Accede a http://IP_DE_LA_VM/test-sqlsrv.php en el navegador. Si aparece el mensaje verde ✅ con la versión de SQL Server, ¡la conexión está funcionando!
Al igual que phpinfo.php, elimina este archivo inmediatamente después de la prueba. Contiene credenciales y no debe quedar expuesto públicamente.
rm /var/www/html/test-sqlsrv.php
Configuraciones de permisos y seguridad básica
Los permisos son cruciales para la seguridad y el buen funcionamiento de las aplicaciones. Vamos a ajustar algunos de ellos e instalar herramientas útiles.
# Añadir su usuario al grupo www-data para gestionar archivos de Apache
# Reemplace 'seu_usuario' por el nombre de usuario que creó en la VM
usermod -a -G www-data seu_usuario
# Actualizar y limpiar paquetes innecesarios
apt-get update
apt-get upgrade -y
apt autoremove -y
# Instalar herramientas útiles
apt-get install htop ncdu -y
Atención
Recuerda sustituir tu_usuario por el nombre de usuario que creaste al aprovisionar la VM en Azure. Añadir el usuario al grupo www-data te permite gestionar archivos en la carpeta de Apache sin necesidad de usar sudo para cada operación. Evita añadir tu usuario al grupo root — esto representa un riesgo de seguridad innecesario.
Firewall con UFW
Una buena práctica de seguridad es configurar el firewall de la VM directamente en el sistema operativo, además de las reglas de Azure. UFW (Uncomplicated Firewall) facilita mucho esta tarea:
# Instalar y configurar UFW
apt-get install ufw -y
# Definir política predeterminada: bloquear entrada, permitir salida
ufw default deny incoming
ufw default allow outgoing
# Liberar los puertos necesarios
ufw allow ssh # puerto 22
ufw allow http # puerto 80
ufw allow https # puerto 443
# Activar el firewall
ufw enable
# Verificar el estado
ufw status verbose
Atención
Asegúrate de liberar el puerto SSH (ufw allow ssh) antes de activar UFW. De lo contrario, perderás el acceso remoto a la VM.
Protección contra Brute-force con fail2ban
fail2ban monitorea los logs del sistema y bloquea automáticamente las IPs que realizan muchos intentos de inicio de sesión fallidos vía SSH. Es una buena capa de defensa adicional, especialmente útil si necesitas liberar SSH para más de una IP (casa, trabajo...).
# Instalar fail2ban
apt-get install fail2ban -y
# Crear archivo de configuración local (nunca edite el .conf original)
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edita el archivo local para ajustar las configuraciones de SSH:
nano /etc/fail2ban/jail.local
Localiza la sección [sshd] y ajusta los valores:
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 5
bantime = 3600
findtime = 600
Qué hace cada directiva:
maxretry = 5: bloquea la IP tras 5 intentos de inicio de sesión erróneosfindtime = 600: los 5 intentos deben ocurrir en un lapso de hasta 10 minutosbantime = 3600: la IP queda bloqueada por 1 hora (usa-1para bloqueo permanente)
# Activar e iniciar el servicio
systemctl enable fail2ban
systemctl start fail2ban
# Verificar el estado e IPs baneadas
fail2ban-client status sshd
Si tú mismo fallas la contraseña más de 5 veces seguidas, podrías banear tu propia IP. En ese caso, usa la Consola Serial de Azure (disponible en el portal, en Soporte + Solución de problemas → Consola Serial) para acceder a la VM sin SSH y ejecutar fail2ban-client set sshd unbanip TU_IP.
Certificado SSL/HTTPS con Certbot
Para tener un sitio seguro con HTTPS, vamos a instalar Certbot, que automatiza la obtención y renovación de certificados SSL gratuitos de Let's Encrypt.
# Instalar Certbot para Apache
apt install certbot python3-certbot-apache -y
# Obtener certificado (reemplace por su dominio real)
certbot --apache -d seudominio.com.br -d www.seudominio.com.br
Resultado: Tu sitio ahora puede configurarse para usar HTTPS, garantizando seguridad en la comunicación con tus usuarios. Certbot también configura la renovación automática del certificado.
Configurando VirtualHost para tu dominio
Hasta aquí, todo el contenido queda dentro de /var/www/html/. Esto funciona para un único sitio, pero Apache tiene una forma mejor de organizar esto: VirtualHost, que asocia un dominio a una carpeta específica. Certbot también necesita un VirtualHost configurado para generar el certificado SSL correctamente.
# Crear la carpeta del sitio (reemplace 'seudominio.com.br' por su dominio)
mkdir -p /var/www/seudominio.com.br/public
chown -R seu_usuario:www-data /var/www/seudominio.com.br
# Crear el archivo de configuración del VirtualHost
nano /etc/apache2/sites-available/seudominio.com.br.conf
Rellena el archivo con el contenido a continuación (sustituye el dominio y el correo electrónico):
<VirtualHost *:80>
ServerName seudominio.com.br
ServerAlias www.seudominio.com.br
ServerAdmin [email protected]
DocumentRoot /var/www/seudominio.com.br/public
<Directory /var/www/seudominio.com.br/public>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/seudominio-error.log
CustomLog ${APACHE_LOG_DIR}/seudominio-access.log combined
</VirtualHost>
Guarda y sal: Ctrl+O → Enter → Ctrl+X. Ahora, activa el VirtualHost y recarga Apache:
# Activar el nuevo VirtualHost
a2ensite seudominio.com.br.conf
# Probar la configuración antes de recargar
apache2ctl configtest
# Recargar (sin cerrar conexiones activas)
systemctl reload apache2
Resultado: Apache ahora sirve el contenido de /var/www/tudominio.com.br/public/ cuando alguien accede a http://tudominio.com.br. Coloca tus archivos PHP en esa carpeta (vía FileZilla) y Certbot usará este VirtualHost automáticamente al generar el certificado SSL.
Opcional: Instalando MariaDB y WordPress
Si necesitas una base de datos local o quieres probar WordPress, sigue estos pasos. Recuerda que puedes usar un servicio de base de datos gestionado en Azure (como Azure Database for MySQL) o un SQL Server en otro lugar.
Instalando MariaDB
# Instalar MariaDB server y client
apt-get install mariadb-server mariadb-client -y
# Iniciar y habilitar el servicio
systemctl start mariadb
systemctl enable mariadb
# Ejecutar la configuración segura inicial
mysql_secure_installation
Durante mysql_secure_installation, serás guiado para definir una contraseña para el usuario root de MariaDB, eliminar usuarios anónimos, deshabilitar el inicio de sesión remoto del root y eliminar la base de datos de prueba. Sigue las instrucciones recomendadas.
Para crear una base de datos y un usuario para WordPress (o tu aplicación), accede a MariaDB y ejecuta los comandos a continuación:
mysql -u root -p
-- Crear base de datos
CREATE DATABASE wordpressdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Crear usuario (sintaxis correcta para MariaDB 10.4+)
CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'SuaSenhaForte@2024';
GRANT ALL PRIVILEGES ON wordpressdb.* TO 'wordpressuser'@'localhost';
FLUSH PRIVILEGES;
QUIT;
Atención
La sintaxis GRANT ... IDENTIFIED BY fue eliminada en MariaDB 10.4+. Crea siempre el usuario con CREATE USER por separado antes de ejecutar GRANT. Además, sustituye TuContraseñaFuerte@2024 por una contraseña única y segura — nunca uses contraseñas genéricas en producción.
Resultado: Tienes un servidor MariaDB ejecutándose y una base de datos lista para tu aplicación.
Instalando WordPress
# Descargar y extraer WordPress
cd /var/www/html
wget https://wordpress.org/latest.zip
unzip latest.zip
mv wordpress/* .
rm latest.zip
rmdir wordpress
# Crear el archivo de configuración
cp wp-config-sample.php wp-config.php
nano wp-config.php
En el editor nano, edita el archivo wp-config.php y rellena la información de la base de datos que creaste:
define( 'DB_NAME', 'wordpressdb' );
define( 'DB_USER', 'wordpressuser' );
define( 'DB_PASSWORD', 'SuaSenhaForte@2024' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
Guarda y sal: Ctrl+O → Enter → Ctrl+X.
Ajusta los permisos para que WordPress funcione correctamente:
cd /var/www/html
# Añadir el usuario actual al grupo www-data
sudo usermod -aG www-data seu_usuario
newgrp www-data
# Definir propietario de los archivos
chown -R www-data:www-data .
# Permisos correctos: 775 para directorios, 664 para archivos
find . -type d -exec chmod 775 {} \;
find . -type f -exec chmod 664 {} \;
# Eliminar el index predeterminado de Apache
rm -f index.html
Resultado: WordPress está instalado y listo para ser configurado accediendo a la IP pública (o dominio) de tu VM en el navegador.
Gestionando costos y la VM en Azure
¿Cuánto cuesta mantener la VM?
Después de que los créditos gratuitos de USD 200 expiren (o los 30 días), comienzas a pagar por el uso real. Los precios a continuación son aproximados para la región Brazil South (pueden variar ligeramente):
Standard_B1ms(1 vCPU, 2 GB RAM): ~USD 15/mes si permanece encendida 24h/díaStandard_B2s(2 vCPU, 4 GB RAM): ~USD 35/mes si permanece encendida 24h/día- Disco SSD Premium 30 GB: ~USD 5/mes, cobrado incluso con la VM apagada
- IP pública estática: cobrada solo mientras la VM está apagada (~USD 0,004/hora)
Para fines de prueba y aprendizaje, B1ms ya es más que suficiente. Para producción con tráfico real, considera al menos una B2s. Consulta la Calculadora de precios de Azure para simular los costos de tu escenario exacto.
Cómo apagar y pausar la VM (y ahorrar)
Para entornos de prueba que solo usas durante el día o en horarios específicos, apagar la VM cuando no la estás usando puede reducir el costo de computación hasta en un 70%.
Atención: apagar desde el SO no es suficiente
Si ejecutas shutdown -h now dentro de la VM o cierras PuTTY, la VM entra en estado "Detenido" (Stopped), pero Azure sigue cobrando la CPU y RAM. Para detener el cobro de computación, es necesario desasignar la VM desde el portal de Azure.
Para apagar y desasignar la VM correctamente (deteniendo el cobro de CPU/RAM):
- En el portal de Azure, accede a tu VM.
- Haz clic en el botón "Detener" (Stop) en la barra superior.
- Confirma la acción. El estado debe cambiar a "Detenido (desasignado)", que es el estado correcto.
Para encenderla nuevamente:
- En el portal de Azure, accede a tu VM.
- Haz clic en "Iniciar" (Start).
- Espera 1-2 minutos. La VM estará lista cuando el estado cambie a "En ejecución".
Consejo de automatización: Azure permite programar el apagado automático de la VM. En la página de la VM, busca "Apagado automático" en el menú lateral y configura el horario que tenga sentido para ti (ej: medianoche todos los días). ¡Es bueno para no olvidar la VM encendida!
Enviando archivos con FileZilla (SFTP)
Con el servidor configurado, necesitarás enviar archivos a él — el código de tu aplicación, imágenes, plantillas o cualquier otro contenido. FileZilla es un cliente SFTP gratuito con interfaz gráfica, perfecto para esto sin necesidad de usar la línea de comandos.
SFTP ≠ FTP: Usa siempre SFTP (SSH File Transfer Protocol), nunca FTP simple. SFTP usa el mismo canal SSH para transferir archivos con cifrado total. El FTP clásico transmite todo en texto plano — incluyendo tu contraseña — y no debe usarse en servidores de producción.
Instalando FileZilla
- Accede a filezilla-project.org y descarga FileZilla Client (no el Server).
- Ejecuta el instalador y sigue los pasos predeterminados (Next → I Agree → Next → Install).
Conectando al servidor vía SFTP
Abre FileZilla. En la barra de conexión rápida que se encuentra en la parte superior de la ventana, rellena los campos:
- Host:
sftp://IP_PUBLICA_DE_LA_VM— el prefijosftp://es obligatorio para indicar que queremos SFTP, no FTP. - Nombre de usuario: el usuario que creaste en Azure.
- Contraseña: la contraseña definida en la creación de la VM.
- Puerto:
22
Haz clic en "Conexión rápida".
En la primera conexión, FileZilla muestra una ventana preguntando si confías en la clave del servidor — haz clic en "OK" (o marca "Confiar siempre en este host" para no ver más este aviso).
¡Conectado! La pantalla se divide en dos paneles: el panel izquierdo muestra los archivos de tu computadora y el panel derecho muestra los archivos de la VM. Para enviar un archivo o carpeta, arrástralo del panel izquierdo al derecho — o haz clic derecho sobre él y elige "Subir".
Dónde colocar los archivos del sitio
Los archivos de tu sitio deben quedar en /var/www/html/. Para navegar hasta esa carpeta en FileZilla, haz clic en el campo "Sitio remoto" (panel derecho, parte superior), escribe /var/www/html y presiona Enter.
Si FileZilla muestra un error de permiso al intentar crear o enviar archivos en /var/www/html/, ejecuta los comandos a continuación en el terminal SSH (sustituyendo tu_usuario por tu usuario real):
chown -R seu_usuario:www-data /var/www/html
chmod -R 775 /var/www/html
Este paso ya fue cubierto en la sección de permisos, pero vale la pena verificarlo en caso de que aún encuentres errores.
Consejo: Guardar la conexión para uso futuro
Para no tener que escribir la IP y la contraseña cada vez, guarde la conexión en el Gestor de sitios:
- Vaya a Archivo → Gestor de sitios (o presione Ctrl+S).
- Haga clic en "Nuevo sitio" y asígnele un nombre (ej:
vm-azure). - En Protocolo, seleccione "SFTP — SSH File Transfer Protocol".
- Rellene Host (solo la IP, sin
sftp://aquí), Usuario y Contraseña. - Haga clic en "Conectar". La conexión quedará guardada para acceder con un clic en las próximas ocasiones.
Apuntando un dominio a la VM
Con el servidor configurado y la IP estática definida, llega el momento de usar un dominio real en lugar de la IP. Vea el flujo completo:
Registrando un dominio
Para dominios .com.br, el registro se realiza a través de Registro.br (el organismo oficial en Brasil):
- Acceda a registro.br, cree una cuenta y busque la disponibilidad del dominio deseado.
- El costo es de R$ 40/año (~US$ 7/año) para dominios
.com.br. - Tras el pago, el dominio queda activo en un plazo de hasta 24 horas (normalmente en minutos).
Para dominios internacionales (.com, .net, .io, etc.), utilice registradores como Namecheap o GoDaddy.
Apuntando el DNS a la VM mediante Cloudflare
La manera más práctica es usar Cloudflare como DNS (gratuito), que configuraremos en detalle en la siguiente sección. El flujo es:
- Cree una cuenta gratuita en Cloudflare y añada su dominio.
- Cloudflare le proporcionará 2 nameservers (ej:
ava.ns.cloudflare.comybob.ns.cloudflare.com). - En el panel de Registro.br, acceda a su dominio → DNS → cambie los nameservers predeterminados por los de Cloudflare.
- De vuelta en Cloudflare, añada un registro DNS de tipo A:
- Nombre:
@(representa el dominio raíz, ej:sudominio.com.br) - Contenido (IPv4): la IP estática de su VM en Azure
- Proxy: active el icono naranja, que habilita CDN y protección DDoS de Cloudflare
- Nombre:
- Añada también un registro CNAME:
- Nombre:
www - Destino:
@(o el nombre del dominio raíz) - Proxy: activo
- Nombre:
La propagación de los nameservers puede llevar desde unos minutos hasta 48 horas, pero normalmente ocurre en menos de 1 hora. Para verificar si ya se ha propagado, utilice el sitio dnschecker.org y compruebe si los registros A están apuntando a la IP correcta en varias regiones del mundo.
Optimizando con Cloudflare
Ahora que su servidor está en línea, vamos a darle un toque de magia para hacerlo más rápido y seguro con Cloudflare. Cloudflare actúa como una CDN (Content Delivery Network), firewall y optimizador de rendimiento, todo esto de forma gratuita en los planes básicos.
Cómo funciona y cómo aplicarlo
- Cree una cuenta en Cloudflare: Acceda a cloudflare.com y añada su dominio.
- Cambie los Nameservers: Cloudflare le indicará que cambie los nameservers de su dominio por los suyos. Esto es fundamental: todo el tráfico de su sitio pasará a ser enrutado por Cloudflare.
- Configuración de DNS: Cloudflare importará sus entradas DNS existentes automáticamente. Asegúrese de que el registro
Ade su dominio principal y del subdominiowwwapunte a la IP pública de su VM en Azure.
Con Cloudflare activo, su sitio ya se beneficia de protección DDoS básica y caché automático para assets estáticos (CSS, JS, imágenes).
Cache Rules para páginas HTML
Para un impulso de rendimiento aún mayor, podemos configurar Cloudflare para realizar caché de páginas HTML. Esto es ideal para sitios con contenido que no cambia con frecuencia (blogs, sitios institucionales) y puede reducir drásticamente el tiempo de carga.
Siga los pasos para crear una Cache Rule:
- En el panel de Cloudflare, seleccione su dominio.
- Vaya a la sección "Rules" y luego a "Cache Rules".
- Haga clic en "Create rule".
- En el campo de condición, defina el patrón de URLs que desea cachear. Por ejemplo:
sudominio.com.br/*(para cachear todo) osudominio.com.br/blog/*(solo la sección del blog). - En "Cache status", seleccione "Eligible for cache".
- En "Edge TTL", defina un tiempo de vida para el caché (ej: 1 hora, 4 horas, 1 día). Esto significa que Cloudflare servirá la página en caché durante ese periodo antes de buscar una nueva versión en su servidor.
- Haga clic en "Deploy".
Resultado: Con esta regla, Cloudflare almacenará una copia de sus páginas HTML en sus servidores de borde. Cuando un usuario solicite una página, si está en caché y dentro del TTL, Cloudflare la entregará instantáneamente, sin siquiera tocar su VM en Azure. ¡Esto significa un sitio mucho más rápido y con menos carga en el servidor!
ATENCIÓN: Tenga mucho cuidado al aplicar caché de páginas completas en sitios con contenido dinámico, áreas de inicio de sesión o carritos de compra. Esto puede causar problemas serios, como usuarios visualizando información de otros usuarios. ¡Use esta regla solo en páginas estáticas o en secciones que esté seguro de que pueden ser cacheadas por igual para todos los visitantes!
Script Completo
Para facilitar las cosas, aquí está el script completo con todos los comandos que utilizamos para configurar el entorno:
#!/bin/bash
# ================================================================
# Script de configuración: Debian 12 (Bookworm) + Apache + PHP 8.5
# + OPcache + Drivers ODBC SQL Server
# ================================================================
## Elevar privilegios a root ##
sudo su
## Actualizar repositorios ##
apt-get update
## Instalar Apache y dependencias ##
apt-get --yes install build-essential autoconf flex bison
apt-get --yes install apache2 apache2-dev libapache2-mod-evasive apache2-utils
apt-get --yes install libpng-dev zlib1g zlib1g-dev libxml2 libxml2-dev
apt-get --yes install openssl libssl-dev libgd-dev
apt-get --yes install vim curl libcurl4 libcurl4-openssl-dev
apt-get --yes install libfreetype6-dev libreadline-dev sqlite3
apt-get --yes install rpl zip libzip-dev libbz2-dev unzip libldap2-dev pwgen
apt-get --yes install unixodbc unixodbc-dev s3cmd
## Habilitar htaccess ##
rpl -e "\n\tOptions Indexes FollowSymLinks\n\tAllowOverride None" \
"\n\tOptions FollowSymLinks\n\tAllowOverride All" \
/etc/apache2/apache2.conf
echo "LimitRequestLine 100000" >> /etc/apache2/apache2.conf
## Habilitar módulos de Apache ##
a2dismod mpm_event
a2dismod mpm_worker
a2enmod mpm_prefork
a2enmod rewrite
a2enmod headers
## Añadir repositorio PHP (Ondřej Surý) ##
apt install apt-transport-https lsb-release ca-certificates curl gnupg -y
curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" \
| tee /etc/apt/sources.list.d/php.list
apt update
## Instalar PHP 8.5 ##
apt install php8.5 php8.5-cli php8.5-{bz2,curl,mbstring,intl,xml,gd,zip,mysql,opcache,readline} -y
apt install php-pear wget git php-cgi php-common php-net-socket -y
## Configurar OPcache ##
cat > /etc/php/8.5/mods-available/opcache.ini << 'EOF'
zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=0
EOF
## Instalar mod_php para Apache ##
apt install libapache2-mod-php8.5 -y
a2enmod php8.5
## Añadir repositorio Microsoft (ODBC — Debian) ##
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \
| gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
curl -s https://packages.microsoft.com/config/debian/12/prod.list \
| tee /etc/apt/sources.list.d/mssql-release.list
apt-get update
## Instalar drivers ODBC de SQL Server ##
ACCEPT_EULA=Y apt-get -y install msodbcsql18 mssql-tools18
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc
## Instalar extensiones PHP para SQL Server vía PECL ##
apt install php8.5-dev php8.5-xml -y
export PHP_PEAR_PHP_BIN=/usr/bin/php8.5
pecl channel-update pecl.php.net
pecl install sqlsrv
pecl install pdo_sqlsrv
## Habilitar extensiones en PHP ##
echo "extension=sqlsrv.so" > /etc/php/8.5/mods-available/sqlsrv.ini
echo "extension=pdo_sqlsrv.so" > /etc/php/8.5/mods-available/pdo_sqlsrv.ini
phpenmod -v 8.5 sqlsrv pdo_sqlsrv
## Permisos y actualizaciones finales ##
# Reemplace 'seu_usuario' por su usuario real
usermod -a -G www-data seu_usuario
newgrp www-data
apt-get upgrade -y
apt autoremove -y
apt-get install htop ncdu -y
## Configurar UFW ##
apt-get install ufw -y
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow http
ufw allow https
ufw --force enable
## Reiniciar Apache ##
systemctl restart apache2
# Instalar Certbot para Apache
apt install certbot python3-certbot-apache -y
# Obtener certificado (reemplace por su dominio real)
certbot --apache -d seudominio.com.br -d www.seudominio.com.br
cd /var/www/html
# Añadir el usuario actual al grupo www-data
sudo usermod -aG www-data seu_usuario
newgrp www-data
# Definir propietario de los archivos
chown -R www-data:www-data .
# Permisos correctos: 775 para directorios, 664 para archivos
find . -type d -exec chmod 775 {} \;
find . -type f -exec chmod 664 {} \;
echo ""
echo "======================================================"
echo " Configuração concluída com sucesso!"
echo " PHP $(php -r 'echo PHP_VERSION;') instalado com drivers SQL Server."
echo " OPcache ativo. UFW configurado."
echo "======================================================"
¡Y eso es todo, amigos!
Espero que les haya gustado este post. ¡Un abrazo y hasta la próxima!
Comentarios (0)
Cargando comentarios...