Fala pessoal!

No dia a dia de um desenvolvedor PHP, é muito comum precisarmos de um ambiente rápido para testes, prototipagem ou até mesmo para hospedar uma aplicação de baixo tráfego. E, muitas vezes, queremos algo que seja fácil de configurar, sem a complexidade de SSH Keys ou configurações avançadas logo de cara.

Pensando nisso, o Azure surge como uma ferramenta poderosa e acessível para criar máquinas virtuais em poucos minutos!

Nesse post, vamos desmistificar o processo de criação de uma Máquina Virtual no Azure com Debian 12 (Bookworm), a versão disponível nas imagens do Azure, configurando um ambiente completo com Apache, PHP 8.5 e os drivers para conexão com o SQL Server.

Além disso, vamos otimizar a performance e segurança com OPcache, UFW, fail2ban e dicas de Cloudflare, incluindo como ativar o cache de páginas HTML.

Prepare-se para ter seu ambiente web rodando em minutos, com tudo o que você precisa para conectar suas aplicações PHP ao SQL Server ou MySQL/MariaDB, e ainda com aquele toque de performance que faz toda a diferença. Então, vamos lá!

Criando a base de demonstração no Azure

Criando uma conta gratuita no Azure

Se você ainda não tem uma conta no Azure, ótima notícia: a Microsoft oferece uma conta gratuita com USD 200 em créditos para usar nos primeiros 30 dias, além de mais de 55 serviços gratuitos por 12 meses, mais do que suficiente pra esse tutorial.

Para criar sua conta gratuita:

  1. Acesse azure.microsoft.com/free e clique em "Experimente gratuitamente".
  2. Entre com sua conta Microsoft (Outlook, Hotmail, Xbox) — ou clique em "Criar uma" se não tiver.
  3. Preencha seus dados pessoais: nome completo, país e data de nascimento.
  4. Informe um número de telefone para receber o código de verificação.
  5. Informe um cartão de crédito ou débito. Ele é exigido apenas para verificar que você é uma pessoa real e não gera cobrança automática.
  6. Aceite os termos e clique em "Inscrever-se". Em alguns segundos você terá acesso ao portal.

O cartão é usado apenas para verificação de identidade. Você não será cobrado enquanto estiver dentro dos limites da conta gratuita e não fizer um upgrade manual para uma assinatura paga. Após os primeiros 30 dias, os créditos de USD 200 expiram, mas os serviços marcados como "gratuitos por 12 meses" continuam disponíveis sem custo.

Criando a Máquina Virtual no Azure

Com sua conta criada, acesse o portal.azure.com e siga os passos abaixo para criar sua máquina virtual:

  1. Na barra de pesquisa, digite "Máquinas Virtuais" e selecione a opção.
  2. Clique em "Criar" e depois em "Máquina Virtual do Azure".
  3. Preencha as informações básicas:
    • Assinatura: Escolha sua assinatura.
    • Grupo de recursos: Crie um novo (ex: rg-webserver) ou use um existente.
    • Nome da máquina virtual: Um nome que faça sentido (ex: vm-debian-web).
    • Região: Escolha a região mais próxima de você ou dos seus usuários.
    • Opções de disponibilidade: Deixe como "Nenhuma redundância de infraestrutura necessária".
    • Tipo de segurança: Deixe "Standard".
    • Imagem: Procure e selecione "Debian 12 (Bookworm)".
    • Tamanho: Escolha um tamanho que atenda às suas necessidades. Para testes, um Standard_B1s (1 vCPU, 1 GB RAM) já é suficiente para projetos pequenos.
  4. Em "Conta de administrador", aqui está o pulo do gato para quem não quer complicação com SSH Keys:
    • Tipo de autenticação: Selecione "Senha".
    • Nome de usuário: Crie um nome de usuário (ex: dirceu).
    • Senha: Crie uma senha forte e anote-a, pois você precisará dela para acessar a VM.
  5. Em "Regras de porta de entrada públicas", selecione "Permitir portas selecionadas" e escolha "HTTP (80)", "HTTPS (443)" e "SSH (22)". A porta SSH é necessária para acessarmos a VM via terminal.
  6. Clique em "Revisar + criar" e, após a validação, em "Criar".
como instalar e configurar o php numa mquina virtual do azure 1

Aguarde alguns minutos enquanto o Azure provisiona sua máquina virtual. Assim que estiver pronta, você terá um IP público para acessá-la. Anote esse IP!

Configurando um IP público estático

Por padrão, o Azure atribui um IP público dinâmico à VM, o que significa que ele muda toda vez que a VM é reiniciada. Quando isso acontece, você perde o acesso SSH, o DNS do Cloudflare fica apontando pro IP errado e precisa atualizar tudo de novo. Por isso, o primeiro passo é tornar o IP estático.

  1. Na página da sua VM no Azure, clique no nome do IP público que aparece no painel de visão geral (algo como vm-debian-web-ip).
  2. No menu lateral, clique em "Configuração" (Configuration).
  3. Em "Atribuição", mude de "Dinâmico" para "Estático".
  4. Clique em "Salvar".
como instalar e configurar o php numa mquina virtual do azure 3 c8c1a9
como instalar e configurar o php numa mquina virtual do azure 2 493c0d

O IP que aparece na tela agora é permanente e não vai mudar mesmo que você reinicie, desligue ou redimensione a VM. Anote esse IP, pois você vai usá-lo no NSG, no DNS do Cloudflare e nas configurações do FileZilla/PuTTY.

Liberando o acesso SSH no NSG (Network Security Group)

Antes de se conectar à VM, vale checar se o NSG (Network Security Group), o firewall de rede do Azure, está liberando conexões SSH do seu IP. O NSG é criado junto com a VM, mas a regra SSH pode estar aberta pra qualquer IP do mundo, o que é um risco de segurança, ou pode nem existir.

O recomendado é restringir o SSH apenas ao seu IP. Veja como:

1. Descubra seu IP público atual

Antes de mexer no NSG, você precisa saber qual é o seu IP público atual, que é o IP que o Azure vai "ver" quando você tentar se conectar. Acesse um dos sites abaixo e anote o IPv4:

Se o seu provedor de internet usa IP dinâmico (o que é o caso na maioria das conexões residenciais), seu IP pode mudar periodicamente. Sempre que perder o acesso SSH, verifique se seu IP mudou e atualize a regra no NSG.

2. Acesse o NSG no portal do Azure

  1. No portal.azure.com, acesse sua VM e, no menu lateral esquerdo, clique em "Rede" (ou "Networking").
  2. Clique no nome do NSG exibido ao lado de "Grupo de segurança de rede" — normalmente algo como vm-debian-web-nsg.
  3. No menu lateral do NSG, clique em "Regras de segurança de entrada" (Inbound security rules).

3. Edite (ou crie) a regra de SSH

Procure por uma regra existente com porta de destino 22 e protocolo TCP. Se ela existir e estiver com origem Any ou *, clique nela para editar. Se não existir, clique em "+ Adicionar" para criar uma nova.

Preencha os campos:

  • Origem: selecione "Endereços IP"
  • Endereços IP / intervalos CIDR de origem: cole o seu IP público seguido de /32 (ex: 177.90.45.123/32). O /32 significa "somente este IP específico".
  • Intervalos de portas de destino: 22
  • Protocolo: TCP
  • Ação: Permitir
  • Prioridade: um número baixo (ex: 300) garante que essa regra seja avaliada antes de outras mais genéricas.
  • Nome: algo descritivo, como Allow-SSH-MeuIP.

Clique em "Salvar". A regra entra em vigor em alguns segundos.

como instalar e configurar o php numa mquina virtual do azure 4 87b85e
como instalar e configurar o php numa mquina virtual do azure 5 f9c5a7
como instalar e configurar o php numa mquina virtual do azure 6 b8e5b1

Se sua empresa ou escola usa uma rede corporativa com NAT, você pode precisar liberar um intervalo de IPs em vez de um único endereço. Nesse caso, consulte o administrador de rede para obter o bloco CIDR correto (ex: 200.155.10.0/24).

Nunca deixe SSH aberto para o mundo

Evite manter a regra SSH com origem Any (0.0.0.0/0). Servidores com SSH exposto para a internet recebem tentativas de invasão automatizadas (brute-force) em questão de minutos após a criação. Restringir ao seu IP elimina praticamente 100% dessas tentativas.

Acessando a VM via SSH

Com a VM criada e o IP público em mãos (você o encontra na página de detalhes da VM no Azure, em "IP público"), é hora de se conectar a ela. A conexão é via SSH, protocolo que criptografa toda a comunicação com o servidor. As opções dependem do seu sistema operacional:

Opção 1: PuTTY (recomendado para iniciantes no Windows)

O PuTTY é um cliente SSH gratuito com interface gráfica, muito popular entre usuários Windows. Para instalá-lo e conectar:

  1. Acesse chiark.greenend.org.uk/~sgtatham/putty/latest.html e baixe o instalador putty-64bit-X.XX-installer.msi.
  2. Execute o instalador e clique em "Next" até finalizar.
  3. Abra o PuTTY. No campo "Host Name (or IP address)", cole o IP público da sua VM no Azure.
  4. Confirme que a porta é 22 e o tipo de conexão é SSH.
  5. Dica: no campo "Saved Sessions", dê um nome à conexão (ex: vm-azure) e clique em "Save" — assim você não precisa digitar o IP toda vez.
  6. Clique em "Open".
  7. Na primeira conexão, o PuTTY exibe um aviso sobre a chave do servidor — clique em "Accept". Isso é normal e esperado.
  8. Na janela preta que abrir, digite seu nome de usuário (o que você criou no Azure) e pressione Enter.
  9. Digite sua senha — os caracteres não aparecem na tela enquanto você digita, isso é intencional — e pressione Enter.

Você está dentro da VM! O terminal exibirá algo como seu_usuario@vm-debian-web:~$, confirmando a conexão bem-sucedida.


Se for utilizar o mRemoteNG, a tela de conexão vai ficar assim:

como instalar e configurar o php numa mquina virtual do azure 7

Opção 2: Terminal nativo (Linux, macOS ou Windows 10+)

No Linux, macOS e no Windows 10/11 (PowerShell ou Terminal do Windows), o SSH já está disponível sem precisar instalar nada. Abra o terminal e execute:

ssh seu_usuario@IP_PUBLICO_DA_VM

Na primeira conexão, confirme com yes quando perguntado sobre a autenticidade do host. Em seguida, informe sua senha. Uma vez conectado, vamos começar!

Preparando o sistema

Com a conexão estabelecida, eleve os privilégios para o usuário root para facilitar as instalações:

sudo su

Em seguida, atualize os repositórios para garantir que estamos instalando as versões mais recentes dos pacotes:

apt-get update

Resultado: Seu ambiente está pronto para receber os softwares que precisamos.

Instalando e Configurando o Apache

Agora vamos instalar o servidor web Apache e algumas dependências importantes para o PHP e outras funcionalidades.

Utilize o script abaixo:

# Instalar Apache e dependências
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

Pacotes removidos no Debian 12

Os pacotes libssl1.1, libmcrypt-dev, libmcrypt4, mcrypt, libgdchart-gd2-xpm e libaio1 não existem no Debian 12 (Bookworm) e causarão erro de instalação. O OpenSSL 3.x já é coberto pelo libssl-dev incluso na lista acima.

Resultado: O Apache e suas dependências essenciais estão instalados. Você já pode acessar o IP público da sua VM no navegador e verá a página padrão do Apache ("Apache2 Debian Default Page").

Habilitando .htaccess e Módulos

Para que o Apache funcione corretamente com aplicações PHP como o WordPress, precisamos habilitar o uso de arquivos .htaccess e alguns módulos importantes.

Para habilitar o .htaccess e aumentar o limite da linha de requisição:

# Habilitar htaccess e links 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

O comando rpl é uma ferramenta para substituição de texto em arquivos, similar ao sed, mas com sintaxe mais amigável. Ele substitui a configuração padrão do Apache para permitir o AllowOverride All, que habilita o .htaccess.

Agora, vamos habilitar os módulos do Apache que são cruciais para a performance e reescrita de URLs:

# Habilitar módulos do Apache
a2dismod mpm_event
a2dismod mpm_worker
a2enmod mpm_prefork
a2enmod rewrite
a2enmod headers

Resultado: O Apache está configurado para usar o módulo mpm_prefork (necessário para funcionar com o mod_php), e os módulos de reescrita e cabeçalhos estão ativos, permitindo URLs amigáveis e manipulação de HTTP headers.

Instalando e Configurando o PHP 8.5

Chegou a hora de instalar o PHP! Vamos usar a versão 8.5, lançada em novembro de 2025, que é a mais recente e traz melhorias de performance e novas funcionalidades em relação às versões anteriores. Para isso, vamos adicionar o repositório de pacotes de Ondřej Surý, que mantém versões atualizadas do PHP para Debian/Ubuntu.

Primeiro, adicione a chave GPG e o repositório:

# Adicionar repositório PHP (Ondřej Surý) — método moderno sem 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

O método com signed-by é a forma atual e recomendada de adicionar repositórios externos no Debian/Ubuntu. O antigo apt-key add foi marcado como obsoleto (deprecated) e será removido em versões futuras do APT.

Agora instale o PHP 8.5 e as extensões necessárias:

# Instalar PHP 8.5 e extensões
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

Além das extensões básicas, já instalamos o php8.5-opcache. O OPcache é um acelerador de bytecode nativo do PHP que armazena o código compilado em memória, eliminando a necessidade de recompilar os scripts a cada requisição. Em aplicações PHP reais, o ganho de performance costuma ficar entre 3x e 5x, e ele já vem embutido no PHP sem custo nenhum.

Com o OPcache instalado, vamos configurá-lo de forma otimizada. Execute o comando abaixo para criar ou substituir o arquivo de configuração de uma vez, sem precisar abrir um 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

Agora, vamos integrar o PHP 8.5 ao Apache usando o módulo mod_php:

# Instalar mod_php para Apache
apt install libapache2-mod-php8.5 -y
a2enmod php8.5

# Reiniciar o Apache para carregar o módulo
systemctl restart apache2

Resultado: O PHP 8.5 está instalado e configurado para funcionar com o Apache. Suas aplicações PHP já podem ser executadas!

Para verificar a versão do PHP e os módulos carregados, você pode usar:

php -v
php -m

Resultado: Você verá a versão do PHP 8.5 e uma lista de todos os módulos ativos, incluindo o OPcache.

Conectando o PHP ao SQL Server (ODBC)

Essa é a cereja do bolo para quem trabalha com SQL Server! Vamos instalar os drivers ODBC da Microsoft para que o PHP possa se comunicar com o SQL Server, seja ele no Azure, on-premises ou em outro servidor.

Atenção: repositório correto para Debian

Os drivers ODBC da Microsoft possuem repositórios específicos por distribuição. Utilize sempre o repositório para Debian — nunca o de Ubuntu — para evitar incompatibilidades de pacotes e falhas de instalação silenciosas.

Para instalar os drivers ODBC:

# Adicionar chave GPG e repositório 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 e ferramentas de linha de comando
ACCEPT_EULA=Y apt-get -y install msodbcsql18 mssql-tools18

# Adicionar ferramentas ao PATH
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc

# Instalar dependências de compilação para o PECL (headers do PHP 8.5 + extensão XML)
apt install php8.5-dev php8.5-xml -y

# Instalar extensões PHP para SQL Server via PECL
# PHP_PEAR_PHP_BIN garante que o pecl use o PHP 8.5, não o PHP padrão do sistema
export PHP_PEAR_PHP_BIN=/usr/bin/php8.5
pecl channel-update pecl.php.net
pecl install sqlsrv
pecl install pdo_sqlsrv

O pacote php8.5-dev fornece os headers de compilação necessários para o PECL construir extensões nativas. O php8.5-xml é obrigatório para o próprio PEAR funcionar. A variável PHP_PEAR_PHP_BIN instrui o PECL a usar especificamente o PHP 8.5 como base de compilação. Sem ela, o PECL usa o PHP padrão do sistema (que pode ser uma versão diferente) e falha com o erro "XML Extension not found".

Habilitando os drivers no PHP.ini

Após instalar os drivers via PECL, precisamos informar ao PHP que eles devem ser carregados. No Debian com o repositório do Ondřej Surý, o jeito correto é criar os arquivos em mods-available e usar o phpenmod, que habilita a extensão para todos os SAPIs (CLI, Apache, FPM) de uma vez.

# Criar os arquivos de configuração das extensões
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 os SAPIs do PHP 8.5 (cria symlinks em cli/conf.d, apache2/conf.d, etc.)
phpenmod -v 8.5 sqlsrv pdo_sqlsrv

O phpenmod é a ferramenta nativa do Debian para ativar extensões PHP. Ele cria automaticamente os symlinks nos diretórios conf.d de cada SAPI instalado (CLI, Apache, FPM), sem precisar descobrir o caminho manualmente. É equivalente ao a2enmod, mas para extensões PHP.

Para que as mudanças tenham efeito, reinicie o Apache:

systemctl restart apache2

Resultado: Seu PHP agora está pronto para se conectar ao SQL Server! Para confirmar, crie um arquivo /var/www/html/phpinfo.php com o conteúdo <?php phpinfo(); ?> e acesse-o no navegador. Verifique se as seções sqlsrv, pdo_sqlsrv e opcache aparecem listadas.

Segurança: Após validar a instalação, remova imediatamente o arquivo phpinfo.php do servidor. Esse arquivo expõe informações sensíveis sobre o ambiente (versão do PHP, módulos, configurações, caminhos) e não deve ficar acessível publicamente.

Testando a conexão PHP → SQL Server

Além do phpinfo(), vale fazer um teste real de conexão. Crie o arquivo abaixo (substitua os dados de conexão pelos seus):

nano /var/www/html/test-sqlsrv.php
<?php
$servidor = 'SEU_SERVIDOR.database.windows.net'; // ou IP do 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);
}
?>

Acesse http://IP_DA_VM/test-sqlsrv.php no navegador. Se aparecer a mensagem verde ✅ com a versão do SQL Server, a conexão está funcionando!

Assim como o phpinfo.php, remova esse arquivo imediatamente após o teste. Ele contém credenciais e não deve ficar exposto publicamente.

rm /var/www/html/test-sqlsrv.php

Configurações de Permissões e Segurança Básica

Permissões são cruciais para a segurança e o bom funcionamento das aplicações. Vamos ajustar algumas delas e instalar ferramentas úteis.

# Adicionar seu usuário ao grupo www-data para gerenciar arquivos do Apache
# Substitua 'seu_usuario' pelo nome de usuário que você criou na VM
usermod -a -G www-data seu_usuario

# Atualizar e limpar pacotes desnecessários
apt-get update
apt-get upgrade -y
apt autoremove -y

# Instalar ferramentas úteis
apt-get install htop ncdu -y

Atenção

Lembre-se de substituir seu_usuario pelo nome de usuário que você criou ao provisionar a VM no Azure. Adicionar o usuário ao grupo www-data permite que você gerencie arquivos na pasta do Apache sem precisar usar sudo para cada operação. Evite adicionar seu usuário ao grupo root — isso representa um risco de segurança desnecessário.

Firewall com UFW

Uma boa prática de segurança é configurar o firewall da VM diretamente no sistema operacional, além das regras do Azure. O UFW (Uncomplicated Firewall) facilita muito essa tarefa:

# Instalar e configurar o UFW
apt-get install ufw -y

# Definir política padrão: bloquear entrada, permitir saída
ufw default deny incoming
ufw default allow outgoing

# Liberar as portas necessárias
ufw allow ssh      # porta 22
ufw allow http     # porta 80
ufw allow https    # porta 443

# Ativar o firewall
ufw enable

# Verificar o status
ufw status verbose

Atenção

Certifique-se de liberar a porta SSH (ufw allow ssh) antes de ativar o UFW. Caso contrário, você perderá o acesso remoto à VM.

Proteção contra Brute-force com fail2ban

O fail2ban monitora os logs do sistema e bloqueia automaticamente IPs que fazem muitas tentativas de login malsucedidas via SSH. É uma boa camada de defesa a mais, especialmente útil se você precisar liberar o SSH pra mais de um IP (casa, trabalho...).

# Instalar o fail2ban
apt-get install fail2ban -y

# Criar arquivo de configuração local (nunca edite o .conf original)
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Edite o arquivo local para ajustar as configurações do SSH:

nano /etc/fail2ban/jail.local

Localize a seção [sshd] e ajuste os valores:

[sshd]
enabled  = true
port     = ssh
logpath  = %(sshd_log)s
backend  = %(sshd_backend)s
maxretry = 5
bantime  = 3600
findtime = 600

O que cada diretiva faz:

  • maxretry = 5: bloqueia o IP após 5 tentativas de login erradas
  • findtime = 600: as 5 tentativas precisam ocorrer em até 10 minutos
  • bantime = 3600: o IP fica bloqueado por 1 hora (use -1 pra bloqueio permanente)
# Ativar e iniciar o serviço
systemctl enable fail2ban
systemctl start fail2ban

# Verificar o status e IPs banidos
fail2ban-client status sshd

Se você mesmo errar a senha mais de 5 vezes seguidas, poderá banir o seu próprio IP. Nesse caso, use o Console Serial do Azure (disponível no portal, em Suporte + Solução de Problemas → Console Serial) para acessar a VM sem SSH e executar fail2ban-client set sshd unbanip SEU_IP.

Certificado SSL/HTTPS com Certbot

Para ter um site seguro com HTTPS, vamos instalar o Certbot, que automatiza a obtenção e renovação de certificados SSL gratuitos do Let's Encrypt.

# Instalar Certbot para Apache
apt install certbot python3-certbot-apache -y

# Obter certificado (substitua pelo seu domínio real)
certbot --apache -d seudominio.com.br -d www.seudominio.com.br

Resultado: Seu site agora pode ser configurado para usar HTTPS, garantindo segurança na comunicação com seus usuários. O Certbot também configura a renovação automática do certificado.

Configurando VirtualHost para seu domínio

Até aqui, todo o conteúdo fica dentro de /var/www/html/. Isso funciona para um único site, mas o Apache tem um jeito melhor de organizar isso: o VirtualHost, que associa um domínio a uma pasta específica. O Certbot também precisa de um VirtualHost configurado pra gerar o certificado SSL corretamente.

# Criar a pasta do site (substitua 'seudominio.com.br' pelo seu domínio)
mkdir -p /var/www/seudominio.com.br/public
chown -R seu_usuario:www-data /var/www/seudominio.com.br

# Criar o arquivo de configuração do VirtualHost
nano /etc/apache2/sites-available/seudominio.com.br.conf

Preencha o arquivo com o conteúdo abaixo (substitua o domínio e o 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>

Salve e saia: Ctrl+OEnterCtrl+X. Agora, ative o VirtualHost e recarregue o Apache:

# Ativar o novo VirtualHost
a2ensite seudominio.com.br.conf

# Testar a configuração antes de recarregar
apache2ctl configtest

# Recarregar (sem derrubar conexões ativas)
systemctl reload apache2

Resultado: O Apache agora serve o conteúdo de /var/www/seudominio.com.br/public/ quando alguém acessa http://seudominio.com.br. Coloque seus arquivos PHP nessa pasta (via FileZilla) e o Certbot usará esse VirtualHost automaticamente ao gerar o certificado SSL.

Opcional: Instalando MariaDB e WordPress

Se você precisar de um banco de dados local ou quiser testar o WordPress, siga estes passos. Lembre-se que você pode usar um serviço de banco de dados gerenciado no Azure (como Azure Database for MySQL) ou um SQL Server em outro lugar.

Instalando MariaDB

# Instalar o MariaDB server e client
apt-get install mariadb-server mariadb-client -y

# Iniciar e habilitar o serviço
systemctl start mariadb
systemctl enable mariadb

# Executar a configuração segura inicial
mysql_secure_installation

Durante o mysql_secure_installation, você será guiado para definir uma senha para o usuário root do MariaDB, remover usuários anônimos, desabilitar login remoto do root e remover o banco de dados de teste. Siga as instruções recomendadas.

Para criar um banco de dados e usuário para o WordPress (ou sua aplicação), acesse o MariaDB e execute os comandos abaixo:

mysql -u root -p
-- Criar banco de dados
CREATE DATABASE wordpressdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- Criar usuário (sintaxe correta para MariaDB 10.4+)
CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'SuaSenhaForte@2024';
GRANT ALL PRIVILEGES ON wordpressdb.* TO 'wordpressuser'@'localhost';
FLUSH PRIVILEGES;
QUIT;

Atenção

A sintaxe GRANT ... IDENTIFIED BY foi removida no MariaDB 10.4+. Sempre crie o usuário com CREATE USER separadamente antes de executar o GRANT. Além disso, substitua SuaSenhaForte@2024 por uma senha única e segura — nunca use senhas genéricas em produção.

Resultado: Você tem um servidor MariaDB rodando e um banco de dados pronto para sua aplicação.

Instalando o WordPress

# Baixar e extrair o WordPress
cd /var/www/html
wget https://wordpress.org/latest.zip
unzip latest.zip
mv wordpress/* .
rm latest.zip
rmdir wordpress

# Criar o arquivo de configuração
cp wp-config-sample.php wp-config.php
nano wp-config.php

No editor nano, edite o arquivo wp-config.php e preencha as informações do banco de dados que você criou:

define( 'DB_NAME',     'wordpressdb' );
define( 'DB_USER',     'wordpressuser' );
define( 'DB_PASSWORD', 'SuaSenhaForte@2024' );
define( 'DB_HOST',     'localhost' );
define( 'DB_CHARSET',  'utf8mb4' );

Salve e saia: Ctrl+OEnterCtrl+X.

Ajuste as permissões para o WordPress funcionar corretamente:

cd /var/www/html

# Adiciona o usuário atual no grupo www-data
sudo usermod -aG www-data seu_usuario
newgrp www-data

# Definir dono dos arquivos
chown -R www-data:www-data .

# Permissões corretas: 775 para diretórios, 664 para arquivos
find . -type d -exec chmod 775 {} \;
find . -type f -exec chmod 664 {} \;

# Remover o index padrão do Apache
rm -f index.html

Resultado: O WordPress está instalado e pronto para ser configurado acessando o IP público (ou domínio) da sua VM no navegador.

Gerenciando Custos e a VM no Azure

Quanto custa manter a VM?

Após os créditos gratuitos de USD 200 expirarem (ou os 30 dias), você começa a pagar pelo uso real. Os preços abaixo são aproximados para a região Brazil South (pode variar ligeiramente):

  • Standard_B1ms (1 vCPU, 2 GB RAM): ~USD 15/mês se ficar ligada 24h/dia
  • Standard_B2s (2 vCPU, 4 GB RAM): ~USD 35/mês se ficar ligada 24h/dia
  • Disco SSD Premium 30 GB: ~USD 5/mês, cobrado mesmo com a VM desligada
  • IP público estático: cobrado só enquanto a VM está desligada (~USD 0,004/hora)

Para fins de teste e aprendizado, a B1ms já é mais que suficiente. Para produção com tráfego real, considere pelo menos uma B2s. Consulte o Azure Pricing Calculator para simular custos do seu cenário exato.

Como desligar e pausar a VM (e economizar)

Para ambientes de teste que você só usa durante o dia ou em horários específicos, desligar a VM quando não está usando pode reduzir o custo da computação em até 70%.

Atenção: desligar pelo SO não é suficiente

Se você executar shutdown -h now dentro da VM ou fechar o PuTTY, a VM entra em estado "Parado" (Stopped), mas o Azure continua cobrando a CPU e RAM. Para parar a cobrança de computação, é preciso desalocar a VM pelo portal do Azure.

Para desligar e desalocar a VM corretamente (parando a cobrança de CPU/RAM):

  1. No portal do Azure, acesse sua VM.
  2. Clique no botão "Parar" (Stop) na barra superior.
  3. Confirme a ação. O status deve mudar para "Parado (desalocado)", que é o estado correto.

Para ligar novamente:

  1. No portal do Azure, acesse sua VM.
  2. Clique em "Iniciar" (Start).
  3. Aguarde 1-2 minutos. A VM estará pronta quando o status mudar para "Em execução".

Dica de automação: O Azure permite agendar o desligamento automático da VM. Na página da VM, procure por "Desligamento automático" no menu lateral e configure o horário que fizer sentido para você (ex: meia-noite todo dia). Bom para não esquecer a VM ligada!

Enviando Arquivos com FileZilla (SFTP)

Com o servidor configurado, você vai precisar enviar arquivos para ele — o código da sua aplicação, imagens, templates ou qualquer outro conteúdo. O FileZilla é um cliente SFTP gratuito com interface gráfica, perfeito para isso sem precisar usar a linha de comando.

SFTP ≠ FTP: Use sempre SFTP (SSH File Transfer Protocol), nunca FTP simples. O SFTP usa o mesmo canal SSH para transferir arquivos com criptografia total. O FTP clássico trafega tudo em texto puro — incluindo sua senha — e não deve ser usado em servidores de produção.

Instalando o FileZilla

  1. Acesse filezilla-project.org e baixe o FileZilla Client (não o Server).
  2. Execute o instalador e siga os passos padrão (Next → I Agree → Next → Install).

Conectando ao servidor via SFTP

Abra o FileZilla. Na barra de conexão rápida que fica no topo da janela, preencha os campos:

  • Host: sftp://IP_PUBLICO_DA_VM — o prefixo sftp:// é obrigatório para indicar que queremos SFTP, não FTP.
  • Nome de usuário: o usuário que você criou no Azure.
  • Senha: a senha definida na criação da VM.
  • Porta: 22

Clique em "Conexão Rápida".

Na primeira conexão, o FileZilla exibe uma janela perguntando se você confia na chave do servidor — clique em "OK" (ou marque "Sempre confiar nesse host" para não ver mais esse aviso).

Conectado! A tela se divide em dois painéis: o painel esquerdo mostra os arquivos do seu computador e o painel direito mostra os arquivos da VM. Para enviar um arquivo ou pasta, arraste-o do painel esquerdo para o direito — ou clique com o botão direito sobre ele e escolha "Fazer upload".

Onde colocar os arquivos do site

Os arquivos do seu site devem ficar em /var/www/html/. Para navegar até essa pasta no FileZilla, clique no campo "Site remoto" (painel direito, parte superior), digite /var/www/html e pressione Enter.

Se o FileZilla mostrar erro de permissão ao tentar criar ou enviar arquivos em /var/www/html/, execute os comandos abaixo no terminal SSH (substituindo seu_usuario pelo seu usuário real):

chown -R seu_usuario:www-data /var/www/html
chmod -R 775 /var/www/html

Essa etapa já foi coberta na seção de permissões, mas vale verificar caso ainda encontre erros.

Dica: Salvar a conexão para uso futuro

Para não precisar digitar o IP e a senha toda vez, salve a conexão no Gerenciador de Sites:

  1. Vá em Arquivo → Gerenciador de Sites (ou pressione Ctrl+S).
  2. Clique em "Novo site" e dê um nome (ex: vm-azure).
  3. Em Protocolo, selecione "SFTP — SSH File Transfer Protocol".
  4. Preencha Host (só o IP, sem sftp:// aqui), Usuário e Senha.
  5. Clique em "Conectar". A conexão ficará salva para acessar com um clique nas próximas vezes.

Apontando um domínio para a VM

Com o servidor configurado e o IP estático definido, chega a hora de usar um domínio real em vez do IP. Veja o fluxo completo:

Registrando um domínio

Para domínios .com.br, o registro é feito pelo Registro.br (o órgão oficial no Brasil):

  1. Acesse registro.br, crie uma conta e pesquise a disponibilidade do domínio desejado.
  2. O custo é de R$ 40/ano para domínios .com.br.
  3. Após o pagamento, o domínio fica ativo em até 24h (normalmente em minutos).

Para domínios internacionais (.com, .net, .io etc.), use registradoras como Namecheap ou GoDaddy.

Apontando o DNS para a VM via Cloudflare

A maneira mais prática é usar o Cloudflare como DNS (gratuito), que vamos configurar em detalhe na próxima seção. O fluxo é:

  1. Crie uma conta gratuita no Cloudflare e adicione seu domínio.
  2. O Cloudflare vai te dar 2 nameservers (ex: ava.ns.cloudflare.com e bob.ns.cloudflare.com).
  3. No painel do Registro.br, acesse seu domínio → DNS → troque os nameservers padrão pelos do Cloudflare.
  4. De volta ao Cloudflare, adicione um registro DNS do tipo A:
    • Nome: @ (representa o domínio raiz, ex: seudominio.com.br)
    • Conteúdo (IPv4): o IP estático da sua VM no Azure
    • Proxy: ative o ícone laranjado, que habilita CDN e proteção DDoS do Cloudflare
  5. Adicione também um registro CNAME:
    • Nome: www
    • Destino: @ (ou o nome do domínio raíz)
    • Proxy: ativo

A propagação dos nameservers pode levar de alguns minutos até 48 horas, mas normalmente acontece em menos de 1 hora. Para verificar se já propagou, use o site dnschecker.org e verifique se os registros A estão apontando para o IP correto em várias regiões do mundo.

Otimizando com Cloudflare

Agora que seu servidor está no ar, vamos dar um toque de magia para torná-lo mais rápido e seguro com o Cloudflare. O Cloudflare atua como um CDN (Content Delivery Network), firewall e otimizador de performance, tudo isso gratuitamente nos planos básicos.

Como funciona e como aplicar

  1. Crie uma conta no Cloudflare: Acesse cloudflare.com e adicione seu domínio.
  2. Altere os Nameservers: O Cloudflare irá te instruir a mudar os nameservers do seu domínio para os deles. Isso é fundamental — todo o tráfego do seu site passará a ser roteado pelo Cloudflare.
  3. Configuração de DNS: O Cloudflare importará suas entradas DNS existentes automaticamente. Certifique-se de que o registro A do seu domínio principal e do subdomínio www aponte para o IP público da sua VM no Azure.

Com o Cloudflare ativo, seu site já se beneficia de proteção DDoS básica e cache automático para assets estáticos (CSS, JS, imagens).

Cache Rules para Páginas HTML

Para um boost de performance ainda maior, podemos configurar o Cloudflare para fazer cache de páginas HTML. Isso é ótimo para sites com conteúdo que não muda com frequência (blogs, sites institucionais) e pode reduzir drasticamente o tempo de carregamento.

Siga os passos para criar uma Cache Rule:

  1. No painel do Cloudflare, selecione seu domínio.
  2. Vá para a seção "Rules" e depois em "Cache Rules".
  3. Clique em "Create rule".
  4. No campo de condição, defina o padrão de URLs que deseja cachear. Por exemplo: seudominio.com.br/* (para cachear tudo) ou seudominio.com.br/blog/* (apenas a seção do blog).
  5. Em "Cache status", selecione "Eligible for cache".
  6. Em "Edge TTL", defina um tempo de vida para o cache (ex: 1 hora, 4 horas, 1 dia). Isso significa que o Cloudflare servirá a página em cache por esse período antes de buscar uma nova versão do seu servidor.
  7. Clique em "Deploy".

Resultado: Com essa regra, o Cloudflare armazenará uma cópia das suas páginas HTML em seus servidores de borda. Quando um usuário solicitar uma página, se ela estiver em cache e dentro do TTL, o Cloudflare a entregará instantaneamente — sem sequer tocar na sua VM no Azure. Isso significa um site muito mais rápido e com menos carga no servidor!

ATENÇÃO: Tenha muito cuidado ao aplicar cache de páginas inteiras em sites com conteúdo dinâmico, áreas de login ou carrinhos de compra. Isso pode causar problemas sérios, como usuários visualizando informações de outros usuários. Use essa regra apenas em páginas estáticas ou em seções que você tem certeza que podem ser cacheadas igualmente para todos os visitantes!

Script Completo

Para facilitar, aqui está o script completo com todos os comandos que utilizamos para configurar o ambiente:

#!/bin/bash
# ================================================================
# Script de configuração: Debian 12 (Bookworm) + Apache + PHP 8.5
#                         + OPcache + Drivers ODBC SQL Server
# ================================================================

## Elevar privilégios para root ##
sudo su

## Atualizar repositórios ##
apt-get update

## Instalar Apache e dependências ##
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 do Apache ##
a2dismod mpm_event
a2dismod mpm_worker
a2enmod mpm_prefork
a2enmod rewrite
a2enmod headers

## Adicionar repositório 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

## Adicionar repositório 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 do SQL Server ##
ACCEPT_EULA=Y apt-get -y install msodbcsql18 mssql-tools18

echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc

## Instalar extensões PHP para SQL Server via 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 extensões no 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

## Permissões e atualizações finais ##
# Substitua 'seu_usuario' pelo seu usuário 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 "======================================================"

E é isso aí, pessoal!

Espero que tenham gostado desse post. Um abraço e até a próxima!