¡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, prototipos 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 las claves SSH o configuraciones avanzadas de inmediato.
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 controladores 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árese para tener su entorno web funcionando en minutos, con todo lo que necesita para conectar sus 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 tiene una cuenta en Azure, una 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 su cuenta gratuita:
- Acceda a azure.microsoft.com/free y haga clic en "Pruebe gratis".
- Inicie sesión con su cuenta Microsoft (Outlook, Hotmail, Xbox) — o haga clic en "Crear una" si no tiene.
- Rellene sus datos personales: nombre completo, país y fecha de nacimiento.
- Introduzca un número de teléfono para recibir el código de verificación.
- Introduzca una tarjeta de crédito o débito. Se exige solo para verificar que usted es una persona real y no genera cargos automáticos.
- Acepte los términos y haga clic en "Registrarse". En unos segundos tendrá acceso al portal.
La tarjeta se usa solo para verificación de identidad. No se le cobrará mientras esté dentro de los límites de la cuenta gratuita y no realice una actualización manual a una suscripción de pago. Después de los primeros 30 días, los créditos de USD 200 expiran, pero los servicios marcados como "gratuitos por 12 meses" siguen disponibles sin costo.
Creando la Máquina Virtual en Azure
Con su cuenta creada, acceda al portal.azure.com y siga los pasos a continuación para crear su máquina virtual:
- En la barra de búsqueda, escriba "Máquinas Virtuales" y seleccione la opción.
- Haga clic en "Crear" y luego en "Máquina Virtual de Azure".
- Rellene la información básica:
- Suscripción: Elija su suscripción.
- Grupo de recursos: Cree uno nuevo (ej:
rg-webserver) o use uno existente. - Nombre de la máquina virtual: Un nombre que tenga sentido (ej:
vm-debian-web). - Región: Elija la región más cercana a usted o a sus usuarios.
- Opciones de disponibilidad: Deje como "Ninguna redundancia de infraestructura necesaria".
- Tipo de seguridad: Deje "Estándar".
- Imagen: Busque y seleccione "Debian 12 (Bookworm)".
- Tamaño: Elija un tamaño que se adapte a sus 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 quienes no quieren complicaciones con las claves SSH:
- Tipo de autenticación: Seleccione "Contraseña".
- Nombre de usuario: Cree un nombre de usuario (ej:
dirceu). - Contraseña: Cree una contraseña fuerte y anótela, ya que la necesitará para acceder a la VM.
- En "Reglas de puerto de entrada públicas", seleccione "Permitir puertos seleccionados" y elija "HTTP (80)", "HTTPS (443)" y "SSH (22)". El puerto SSH es necesario para acceder a la VM a través del terminal.
- Haga clic en "Revisar + crear" y, después de la validación, en "Crear".

Espere unos minutos mientras Azure aprovisiona su máquina virtual. Una vez que esté lista, tendrá una IP pública para acceder a ella. ¡Anote 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 se reinicia la VM. Cuando esto sucede, pierdes el acceso SSH, el DNS de Cloudflare apunta 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 visión general (algo como
vm-debian-web-ip). - En el menú lateral, haz clic en "Configuración" (Configuration).
- En "Asignación", cambia de "Dinámico" a "Estático".
- Haz clic en "Guardar".


La IP que aparece en la 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, es importante verificar 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 que es un riesgo de seguridad, o puede que ni siquiera exista.
Lo recomendado es restringir el SSH solo a tu IP. Mira cómo:
1. Descubre tu IP pública actual
Antes de modificar 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 (lo cual 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 ha cambiado y actualiza la regla en el NSG.
2. Accede al NSG en el portal de Azure
- En el portal.azure.com, accede a tu VM y, en el menú lateral izquierdo, haz clic en "Red" (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 origen Any o *, haz clic en ella para editar. Si no existe, haz clic en "+ Agregar" para crear una nueva.
Rellena 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 entra en vigor en unos segundos.



Si tu empresa o escuela utiliza una red corporativa con NAT, es posible que necesites liberar un rango de IPs en lugar de una única 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 intrusión automatizados (fuerza bruta) en cuestión de minutos después de su creación. Restringir 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 encripta 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 usuarios de Windows. Para instalarlo y conectar:
- 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 es 22 y el tipo de conexión es 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 abrirá, escribe tu nombre de usuario (el que creaste en Azure) y presiona Enter.
- Escribe tu contraseña — los caracteres no aparecen en la 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 en 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, introduce 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 asegurar 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 un error 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 la 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 cabeceras están activos, permitiendo URLs amigables y manipulación de encabezados HTTP.
Instalando y Configurando PHP 8.5
¡Llegó la hora de instalar PHP! Usaremos 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 relación con las versiones anteriores. Para ello, vamos a añadir el repositorio de paquetes de Ondřej Surý, que 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 futuras versiones 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 hemos instalado 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 coste alguno.
Con OPcache instalado, vamos a configurarlo de forma optimizada. Ejecuta el comando de abajo 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 en 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 guinda 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 asegura 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 estándar 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 surtan 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 accéde a él en el navegador. Verifica si las secciones sqlsrv, pdo_sqlsrv y opcache aparecen listadas.
Seguridad: Después de 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 ser 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 de abajo (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 ser 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 'su_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 reemplazar su_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 monitoriza 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 después de 5 intentos de inicio de sesión erróneosfindtime = 600: los 5 intentos deben ocurrir en un máximo de 10 minutosbantime = 3600: la IP permanece bloqueada durante 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 te equivocas en la contraseña más de 5 veces seguidas, podrás 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 ser configurado 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 se encuentra dentro de /var/www/html/. Esto funciona para un único sitio, pero Apache tiene una mejor manera de organizar esto: el 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 'sudominio.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 de abajo (sustituye el dominio y el e-mail):
<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 derribar 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 el servidor y cliente MariaDB
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 el 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+. Siempre crea el usuario con CREATE USER por separado antes de ejecutar el GRANT. Además, reemplaza TuContraseñaFuerte@2024 por una contraseña única y segura — nunca uses contraseñas genéricas en producción.
Resultado: Tienes un servidor MariaDB funcionando 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ñade 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 {} \;
# Remover el índice 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?
Una vez que expiren los créditos gratuitos de USD 200 (o los 30 días), usted comenzará 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: cobrado solo mientras la VM está apagada (~USD 0,004/hora)
Para fines de prueba y aprendizaje, la B1ms ya es más que suficiente. Para producción con tráfico real, considere al menos una B2s. Consulte el Azure Pricing Calculator para simular los costos de su escenario exacto.
Cómo apagar y pausar la VM (y ahorrar)
Para entornos de prueba que solo usa durante el día o en horarios específicos, apagar la VM cuando no la está usando puede reducir el costo de la computación hasta en un 70%.
Atención: apagar desde el SO no es suficiente
Si ejecuta shutdown -h now dentro de la VM o cierra 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, acceda a su VM.
- Haga clic en el botón "Detener" (Stop) en la barra superior.
- Confirme la acción. El estado debe cambiar a "Detenido (desasignado)", que es el estado correcto.
Para encenderla nuevamente:
- En el portal de Azure, acceda a su VM.
- Haga clic en "Iniciar" (Start).
- Espere 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, busque "Apagado automático" en el menú lateral y configure el horario que tenga sentido para usted (ej: medianoche todos los días). ¡Bueno para no olvidar la VM encendida!
Enviando Archivos con FileZilla (SFTP)
Con el servidor configurado, necesitará enviar archivos a él — el código de su 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: Use 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 su contraseña — y no debe usarse en servidores de producción.
Instalando FileZilla
- Acceda a filezilla-project.org y descargue el FileZilla Client (no el Server).
- Ejecute el instalador y siga los pasos estándar (Next → I Agree → Next → Install).
Conectando al servidor vía SFTP
Abra FileZilla. En la barra de conexión rápida que se encuentra en la parte superior de la ventana, complete los campos:
- Host:
sftp://IP_PUBLICO_DA_VM— el prefijosftp://es obligatorio para indicar que queremos SFTP, no FTP. - Nombre de usuario: el usuario que creó en Azure.
- Contraseña: la contraseña definida en la creación de la VM.
- Puerto:
22
Haga clic en "Conexión Rápida".
En la primera conexión, FileZilla muestra una ventana preguntando si confía en la clave del servidor — haga clic en "OK" (o marque "Confiar siempre en este host" para no volver a ver este aviso).
¡Conectado! La pantalla se divide en dos paneles: el panel izquierdo muestra los archivos de su computadora y el panel derecho muestra los archivos de la VM. Para enviar un archivo o carpeta, arrástrelo del panel izquierdo al derecho — o haga clic derecho sobre él y elija "Subir".
Dónde colocar los archivos del sitio
Los archivos de su sitio deben estar en /var/www/html/. Para navegar hasta esa carpeta en FileZilla, haga clic en el campo "Sitio remoto" (panel derecho, parte superior), escriba /var/www/html y presione Enter.
Si FileZilla muestra un error de permiso al intentar crear o enviar archivos en /var/www/html/, ejecute los comandos a continuación en el terminal SSH (reemplazando seu_usuario por su 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 verificar si aún encuentra 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 Administrador de Sitios:
- Vaya a Archivo → Administrador de Sitios (o presione Ctrl+S).
- Haga clic en "Nuevo sitio" y dele 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 las próximas veces.
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 para dominios
.com.br. - Después del pago, el dominio estará activo en hasta 24h (normalmente en minutos).
Para dominios internacionales (.com, .net, .io etc.), use registradores como Namecheap o GoDaddy.
Apuntando el DNS a la VM vía Cloudflare
La forma más práctica es usar Cloudflare como DNS (gratuito), que configuraremos en detalle en la próxima sección. El flujo es:
- Cree una cuenta gratuita en Cloudflare y añada su dominio.
- Cloudflare le dará 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 tardar desde unos minutos hasta 48 horas, pero normalmente ocurre en menos de 1 hora. Para verificar si ya se ha propagado, use el sitio dnschecker.org y verifique 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 un 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 aplicar
- 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 activos estáticos (CSS, JS, imágenes).
Reglas de Caché para Páginas HTML
Para un impulso de rendimiento aún mayor, podemos configurar Cloudflare para que almacene en caché las páginas HTML. Esto es excelente 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 Regla de Caché:
- 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:
seudominio.com.br/*(para cachear todo) oseudominio.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 la caché (ej: 1 hora, 4 horas, 1 día). Esto significa que Cloudflare servirá la página en caché durante ese período antes de buscar una nueva versión de 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 igualmente para todos los visitantes!
Script Completo
Para facilitar, 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 'su_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
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 esta publicación. ¡Un abrazo y hasta la próxima!
Comentários (0)
Carregando comentários…