🚀 Guia Completo: Deploy Laravel na AWS

Roteiro passo a passo para clonar servidor EC2, configurar subdomínio, Cloudflare + SSL, Laravel com Nginx e PostgreSQL. Tudo otimizado para Amazon Linux 2023.

Laravel PostgreSQL Nginx AWS EC2 SSL
0

Clonar Servidor EC2 (Opcional)

Como duplicar corretamente uma instância EC2 existente

Opção A: AMI (Recomendado)

💡 O que faz: Cria uma "imagem" completa do servidor incluindo disco e configurações. Depois você pode lançar novas instâncias idênticas a partir dessa imagem.

Passos no Console AWS:

  1. Acesse EC2 → Instances
  2. Selecione a instância → Actions → Image and templates → Create image
  3. Defina um nome para a AMI
  4. Aguarde a criação (pode levar alguns minutos)
  5. Vá em AMIs → Selecione sua imagem → Launch instance from AMI
Vantagem: Mais fiel que reinstalar tudo do zero. Mantém todas as configurações, pacotes instalados e personalizações.
⚠️
Atenção: O IP público mudará. Você precisará reconfigurar o DNS e os virtual hosts do Nginx.

Opção B: Snapshot do EBS

💡 O que faz: Cria um snapshot do disco (volume EBS) e permite criar um novo volume/instância a partir dele.

Use esta opção quando precisar apenas do disco, sem as configurações da instância.

1

Acessar Nova Instância e Preparar

Configurações iniciais do servidor

Ajustar Timezone para Brasil

💡 O que faz: Define o fuso horário do servidor para Brasília. Isso garante que os logs e timestamps do Laravel estejam corretos.
BASH
sudo timedatectl set-timezone America/Sao_Paulo
timedatectl

O comando timedatectl sem parâmetros mostra a configuração atual para confirmar.

2

Instalar Pacotes Essenciais

Resolver conflitos e instalar ferramentas básicas

Resolver Conflito do Curl

💡 O que faz: No Amazon Linux 2023 existe um conflito entre curl-minimal e curl completo. Precisamos remover o minimal e instalar a versão completa.
BASH
sudo dnf remove -y curl-minimal
sudo dnf install -y curl
curl --version
💡
Se ainda houver conflito, use: sudo dnf install -y curl --allowerasing

Instalar Utilitários do Sistema

💡 O que faz: Instala ferramentas essenciais: Git para clonar repositórios, unzip para extrair arquivos, htop para monitorar recursos.
BASH
sudo dnf update -y
sudo dnf install -y git unzip htop
git --version
3

Preparar Diretório do Site

Criar estrutura de pastas e página placeholder

Criar Pasta do Domínio

💡 O que faz: Cria a pasta onde ficará o conteúdo do site e define as permissões corretas para o Nginx.
BASH
sudo mkdir -p /var/www/pastabase
sudo chown -R nginx:nginx /var/www/pastabase
sudo chmod -R 755 /var/www/pastabase
📁
Estrutura: /var/www/ é o diretório padrão para sites. Cada projeto terá sua própria pasta.

Criar Página HTML Inicial

💡 O que faz: Cria um arquivo HTML temporário para testar se o Nginx está funcionando antes de instalar o Laravel.
BASH
sudo tee /var/www/pastabase/index.html >/dev/null <<'HTML'
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title>Site em Construção</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 0;
        }
        .container {
            text-align: center;
            background: white;
            padding: 3rem;
            border-radius: 1rem;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
        }
        h1 { color: #667eea; }
    </style>
</head>
<body>
    <div class="container">
        <h1>🚀 Site em Construção</h1>
        <p>Laravel será instalado em breve!</p>
    </div>
</body>
</html>
HTML
sudo chown nginx:nginx /var/www/pastabase/index.html
4

Configurar VHost do Nginx

Criar configuração para o subdomínio

Criar Arquivo de Configuração

💡 O que faz: Define como o Nginx deve responder às requisições para seu domínio. Inicialmente aponta para o HTML estático.
⚠️
Importante: Substitua DOMINIO pelo seu domínio real (ex: app.exemplo.com.br)
NGINX
sudo tee /etc/nginx/conf.d/DOMINIO.conf >/dev/null <<'NGINX'
server {
    listen 80;
    server_name DOMINIO;

    root /var/www/pastabase;
    index index.html;

    access_log /var/log/nginx/DOMINIO.access.log;
    error_log  /var/log/nginx/DOMINIO.error.log;

    location / {
        try_files $uri $uri/ =404;
    }
}
NGINX

Validar e Recarregar Nginx

💡 O que faz: Testa a sintaxe da configuração e aplica as mudanças sem derrubar o serviço.
BASH
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl status nginx --no-pager

Teste Local (Sem DNS)

💡 O que faz: Verifica se o Nginx está respondendo corretamente simulando uma requisição com o header Host.
BASH
curl -I -H "Host: DOMINIO" http://127.0.0.1

Você deve receber um HTTP/1.1 200 OK se tudo estiver funcionando.

5

Configurar DNS no Cloudflare

Apontar o subdomínio para o servidor

Descobrir IP Público da EC2

💡 O que faz: Obtém o IP público da instância EC2 que será usado no DNS.
BASH
curl -s https://checkip.amazonaws.com

Criar Registro DNS

💡 O que faz: Cria o registro A no Cloudflare que aponta seu domínio para o IP do servidor.

No painel do Cloudflare:

  1. Acesse a seção DNS
  2. Clique em Add Record
  3. Configure:
    • Type: A
    • Name: seu subdomínio (ex: app)
    • IPv4 address: IP da EC2
    • Proxy status: DNS only (nuvem cinza)
⚠️
Importante: Use "DNS only" inicialmente para evitar erro 521. Depois do SSL, você pode ativar o proxy.
6

Ajustar Security Group

Liberar portas HTTP e HTTPS

💡 O que faz: Configura o firewall da AWS para permitir tráfego web. Sem isso, o Cloudflare retorna erro 521.

No Console AWS:

  1. Vá em EC2 → Security Groups
  2. Selecione o SG da sua instância
  3. Clique em Edit inbound rules
  4. Adicione:
    • HTTP (80): Source 0.0.0.0/0
    • HTTPS (443): Source 0.0.0.0/0
    • SSH (22): Source seu IP apenas
Segurança: Mantenha SSH restrito ao seu IP para evitar ataques de força bruta.
7

Instalar Certificado SSL

Configurar HTTPS com Let's Encrypt

Instalar Certbot

💡 O que faz: Instala o Certbot com plugin Nginx para automatizar a geração e renovação de certificados SSL gratuitos.
BASH
sudo dnf install -y certbot python3-certbot-nginx
certbot --version

Gerar Certificado

💡 O que faz: Gera o certificado SSL e configura automaticamente o Nginx para HTTPS com redirecionamento.
BASH
sudo certbot --nginx -d DOMINIO

Durante a execução:

  • Digite seu email
  • Aceite os termos
  • Escolha redirecionar HTTP para HTTPS (opção 2)

Validar Renovação Automática

💡 O que faz: Testa se a renovação automática está funcionando (certificados Let's Encrypt expiram em 90 dias).
BASH
sudo certbot renew --dry-run
8

Configurar Laravel

Clonar projeto, instalar dependências e configurar banco

8.1 - Clonar Projeto do GitHub

💡 O que faz: Baixa o código do seu repositório Laravel para o servidor.
BASH
# Criar pasta do projeto
sudo mkdir -p /var/www/app
sudo chown -R ec2-user:ec2-user /var/www/app

# Clonar repositório
cd /var/www
git clone REPO_URL app
cd /var/www/app
git status
🔐
Para repositório privado via SSH: git clone [email protected]:USER/REPO.git app

8.2 - Instalar PHP e Extensões

💡 O que faz: Instala o PHP, PHP-FPM e todas as extensões necessárias para o Laravel funcionar.
BASH
sudo dnf install -y \
    php \
    php-fpm \
    php-cli \
    php-mbstring \
    php-xml \
    php-pdo \
    php-pgsql \
    php-bcmath \
    php-json \
    php-opcache \
    php-zip

php -v
sudo systemctl enable --now php-fpm
sudo systemctl status php-fpm --no-pager

8.3 - Instalar Composer

💡 O que faz: Instala o gerenciador de dependências PHP usado pelo Laravel.
BASH
cd ~
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
sudo mv composer.phar /usr/local/bin/composer
composer --version

8.4 - Instalar Dependências Laravel

💡 O que faz: Baixa e instala todas as bibliotecas PHP definidas no composer.json.
BASH
cd /var/www/app
composer install --no-dev --optimize-autoloader

8.5 - Build Frontend (Se usar Vite/Mix)

💡 O que faz: Compila assets do frontend (CSS, JS) se o projeto usar Vite ou Laravel Mix.
BASH
# Instalar Node.js se necessário
sudo dnf install -y nodejs npm

cd /var/www/app
npm install
npm run build

8.6 - Configurar Permissões

💡 O que faz: Define permissões corretas para que o Nginx/PHP possam ler e escrever nos diretórios necessários.
BASH
sudo chown -R nginx:nginx /var/www/app
sudo find /var/www/app -type f -exec chmod 644 {} \;
sudo find /var/www/app -type d -exec chmod 755 {} \;

# Permissões especiais para storage e cache
sudo chmod -R 775 /var/www/app/storage
sudo chmod -R 775 /var/www/app/bootstrap/cache

8.7 - Configurar PostgreSQL

💡 O que faz: Cria usuário e banco de dados no PostgreSQL para o Laravel.
SQL
# Acessar PostgreSQL como superusuário
sudo -u postgres psql

-- Criar usuário e banco
CREATE ROLE app WITH LOGIN PASSWORD 'SenhaForte!2026@' CREATEDB;
CREATE DATABASE appdb OWNER app;
\q

# Testar conexão
psql -h 127.0.0.1 -U app -d appdb -c "SELECT NOW();"

8.8 - Configurar .env Laravel

💡 O que faz: Cria e configura o arquivo de ambiente com as credenciais do banco e URL da aplicação.
BASH
cd /var/www/app

# Copiar arquivo exemplo e gerar chave
cp .env.example .env
php artisan key:generate

# Configurar banco de dados
sudo sed -i "s|^APP_URL=.*|APP_URL=https://DOMINIO|g" .env
sudo sed -i "s|^DB_CONNECTION=.*|DB_CONNECTION=pgsql|g" .env
sudo sed -i "s|^DB_HOST=.*|DB_HOST=127.0.0.1|g" .env
sudo sed -i "s|^DB_PORT=.*|DB_PORT=5432|g" .env
sudo sed -i "s|^DB_DATABASE=.*|DB_DATABASE=appdb|g" .env
sudo sed -i "s|^DB_USERNAME=.*|DB_USERNAME=app|g" .env
sudo sed -i "s|^DB_PASSWORD=.*|DB_PASSWORD=SenhaForte!2026@|g" .env

8.9 - Rodar Migrations e Otimizações

💡 O que faz: Cria as tabelas no banco de dados e otimiza caches para produção.
BASH
cd /var/www/app

# Criar tabelas
php artisan migrate --force

# Otimizar para produção
php artisan config:cache
php artisan route:cache
php artisan view:cache
9

Trocar Root do Nginx para Laravel

Apontar domínio para pasta public do Laravel

Atualizar VHost para Laravel

💡 O que faz: Modifica a configuração do Nginx para servir o Laravel ao invés do HTML estático, incluindo processamento PHP.
NGINX
sudo tee /etc/nginx/conf.d/DOMINIO.conf >/dev/null <<'NGINX'
server {
    listen 80;
    server_name DOMINIO;

    root /var/www/app/public;
    index index.php index.html;

    access_log /var/log/nginx/DOMINIO.access.log;
    error_log  /var/log/nginx/DOMINIO.error.log;

    # Laravel routing
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # PHP processing
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php-fpm/www.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    # Cache static files
    location ~* \.(jpg|jpeg|png|gif|svg|ico|css|js|woff2?)$ {
        expires 7d;
        access_log off;
        add_header Cache-Control "public";
    }

    # Security
    location ~ /\.(?!well-known).* {
        deny all;
    }
}
NGINX

Aplicar Configuração

💡 O que faz: Valida a sintaxe e recarrega o Nginx com as novas configurações.
BASH
sudo nginx -t
sudo systemctl reload nginx

Reinstalar Certificado SSL

💡 O que faz: Garante que o Certbot atualize a configuração SSL para o novo server block.
BASH
sudo certbot --nginx -d DOMINIO
10

Finalização e Cloudflare

Últimos ajustes e ativação do proxy

💡 Após confirmar que tudo funciona:

Teste o acesso:

  • Acesse https://DOMINIO
  • Verifique se o Laravel está rodando
  • Teste algumas rotas da aplicação

Ativar Proxy Cloudflare

No painel do Cloudflare:

  1. Vá em DNS
  2. Edite o registro A do seu domínio
  3. Mude o Proxy para ON (nuvem laranja)

Configurar SSL no Cloudflare

No painel do Cloudflare:

  1. Vá em SSL/TLS
  2. Selecione Full (strict)
🔐
Full (strict): Garante conexão SSL tanto do usuário para Cloudflare quanto do Cloudflare para seu servidor.

📋 Checklist Final - Validação Completa

EC2 criada via AMI ou nova instância
Security Group com portas 80 e 443 liberadas
DNS Cloudflare apontando para IP da EC2
VHost Nginx configurado para o domínio
Certificado SSL instalado via Certbot
Repositório Laravel clonado em /var/www/app
Dependências instaladas (composer install + npm build)
.env configurado com PostgreSQL
Migrations executadas no banco
Root do Nginx apontando para /var/www/app/public
Cloudflare com proxy ON e SSL Full (strict)
🎉
Parabéns! Seu Laravel está rodando em produção com HTTPS, cache CDN e todas as otimizações!