[Tutorial] Crie e hospede sites estáticos de graça na AWS usando Next.js (Alerta para ideia de negócio!)
Neste tutorial vamos hospedar um site estático criado com o Next.js na AWS com custo zero ou quase zero, mas com desempenho excelente!
O que você vai ter no final:
- Um site estático com custo mínimo
- O site será acessível através do endereço
www.exemplo.com.br
ouexemplo.com.br
- O site aceita conexões HTTPS para maior segurança
- O site terá um ótimo desempenho e terá uma ótima base para ter bom posicionamento nos mecanismos de busca
- O site usará um CDN (Content Delivery Network, saiba mais o que é isso) para melhor desempenho, possibilitar aceitar conexões HTTPS e estar bem posicionado nos resultados dos buscadores
O que é um site estático?
À primeira vista, o nome “estático” dá a entender que o site é uma página “parada”, um site antiquado dos anos 90, com HTML e CSS puros, que não tem interatividade, não mostra informações atualizadas e tem poucas possibilidades de uso. Na verdade, um site estático pode ser interativo, pode pegar dados de uma API, pode ter um CMS (Content Management System, do tipo Wordpress). Veja aqui alguns exemplos de sites estáticos e outros exemplos aqui.
Por quê o custo é zero ou quase zero?
Para esse projeto, vamos usar os seguintes serviços AWS:
- S3, que armazenará os arquivos HTML, CSS e JavaScript
- Cloudfront, que será o nosso CDN e retornará os nossos arquivos de um local mais próximo possível do usuário que está acessando o site
O S3 tem limites bem generosos para novas contas (saiba mais sobre os limites grátis) e o preço do armazenamento e transferência são na casa dos centavos (saiba mais sobre os custos). O Cloudfront têm um limite grátis vitalício muito generoso e suporta uma grande quantidade de transferências de dados também com custo na casa de centavos (saiba mais sobre os custos)
Vantagens
- Páginas muito rápidas
- Sem necessidade de criar, configurar e administrar servidores
- Custo zero ou quase zero
- Ótimo para mecanismos de busca: amigável para web crawlers, ótimo desempenho da página
- Seguro contra ataques: um site estático diminui em muito as rotas de ataques
Casos de uso
- Páginas de projetos pessoais
- Páginas comerciais, de negócios de bairro à páginas institucionais de empresas
- Criar diversas páginas ou projetos, mesmo com orçamento apertado
- Landing pages comerciais que recebem poucas ou muitas solicitações
- Blogs com poucas ou centenas de páginas
- E-commerces
Note que é possível criar diversos sites para clientes e ter um custo fixo muito baixo, sem precisar subir servidor, atualizar servidor, balancear a carga do servidor, que são tarefas técnicas, porém que não são valorizadas pelos clientes, o que é um diferencial competitivo enorme.
Pense quantos negócios poderiam substituir páginas feitas em Wordpress, que exigem uma atenção constante, por essa solução.
Você pode criar e manter diversos sites para pequenos negócios, por exemplo, tendo um custo fixo muito baixo e cobrando uma mensalidade mais em conta que os seus concorrentes. Pense naquela pizzaria do bairro que não tem site ou paga uma mensalidade alta para ter um site no Wix. Ou páginas de apresentação profissionais de médicos, dentistas, personal trainers, etc.
Pense também em páginas corporativas, páginas de eventos, landing page de produtos, as possibilidades são inúmeras.
Pré requisitos:
- Conta AWS
- Projeto Next.js (Pode ser o o projeto padrão gerado pelo create-next-app ou usar o meu que criei com o v0.dev)
- (Opcional) Um domínio próprio. Neste tutorial usaremos um domínio criado no Registro.br
Passo a passo
Você poderá acompanhar todos os passos detalhados no tutorial em Português da AWS sobre hospedar páginas estáticas com o AWS Cloudfront.
Nesse tutorial irei focar nos detalhes necesários para permitir o uso do Next.js e usando o Registo.br para obter o domínio, que o tutorial da AWS não cobre.
É necessário usar Next.js para criar sites estáticos?
Não, você pode criar um site estático com um único arquivo HTML, mas usando o Next.js é possível criar sites estáticos complexos sem precisar criar um processo completamente diferente do tradicional.
Passo 0: Crie um projeto Next.js
Você pode usar o meu projeto, que é uma landing page para uma personal trainer imaginária chamada Diana, que fiz com a ajuda do v0 (saiba mais no meu post sobre o v0.dev) ou criar o seu próprio projeto da maneira que preferir.
Caso você crie seu próprio projeto, é necessário ficar atendo a algumas limitações ao usar o Next.js para gerar páginas estáticas.
A grande maioria dos recursos do Next.js continua funcionando ao criar páginas estáticas. No entanto, como hospedaremos o site em um servidor que apenas retorna arquivos, não podemos usar funcionalidades que dependem de um servidor que processe dados, como por exemplo:
- usar a tag
<Image>
(possível usar com uma configuração extra) - usar server components
- Criar rotas de API
- Usar middleware
- Usar ISR (Incremental Static Regeneration)
Veja toda a lista de limitações na documentação oficial.
Passo 1: Crie o primeiro bucket S3 para www.exemplo.com.br
, vamos definir como “principal”
Um bucket
, ou balde em Português, é literalmente um lugar para guardar seus arquivos. Pense em uma pasta que você guarda todos os arquivos sobre um assunto. Logo, se você tem diferentes projetos, é melhor criar um bucket para cada projeto.
Como escolher uma região da AWS?
Ao criar o bucket, você pode criar em qualquer região, mas como iremos usar um CDN, podemos usar uma região que tenha custos mais baixos como a Virgínia do Norte (us-east-1), ao invés de usar a região de São Paulo (sa-east-1). A distância maior em relação aos usuários brasileiros é compensada pelo CDN, que irá retornar os arquivos do Brasil para os usuários brasileiros.
Defina o nome do bucket como quiser, mas o nome precisa ser único no mundo (então chamá-lo de www.exemplo.com.br
não vai funcionar, pois já deve ter um outro bucket com esse nome.
Nas configurações de criação do bucket mantenha todas as opções recomendadas e que já estão selecionadas.
Note que o S3 permite criar sites estáticos, mas esses sites criados pelo S3 aceitam somente conexões HTTP, que transfere dados sem criptografia, tornando as conexões inseguras. Você pode ter um site que aceita somente HTTP, mas será duramente penalizado pelos mecanismos de busca, pois o padrão atual de segurança é usar HTTPS e seus usuários notarão o cadeado aberto no browser, criando desconfiança.
Para aceitar conexões HTTPS no site estático, será necessário usar:
- Uma CDN, usaremos o AWS Cloudfront
- Um certificado SSL, criado gratuitamente pela AWS Certificate Manager
Vamos providenciar esses itens nos passos seguintes.
Passo 2: Crie um certificado SSL no AWS Certificate Manager
Ao criar um certificado na AWS Certificate Manger, você deverá selecionar as seguintes opções:
- Selecionar
Request a public certificate
, pois vamos usar um certificado fornecido pela Amazon - No campo
Fully qualified domain name
, colocarwww.exemplo.com.br
e*.exemplo.com.br
(o*
significa qualquer valor), assim o certificado valerá para seu domínio principal e também para todos os subdomínios, comoapi.exemplo.com.br
- Selecionar
DNS validation
emValidation Method
, pois vamos validar esse certificado criando um registro CNAME no Registro.br - Selecionar
RSA 2048
em key algorithm para maior compatibilidade
Clique no certificado criado e veja que existem duas chaves e valores CNAME. Adicione dois registros CNAME no Registro.br com essas chaves e valores para mostrar que você realmente tem o controle do domínio.
Depois de algum tempo, o painel do Certificate Manager irá mostrar que o certificado está ativo e funcionando.
Passo 3: Crie o segundo bucket S3 para exemplo.com
, vamos definir como “secundário”
Esse passo é opcional. Explico por quê.
Você pode lidar com acessos para o endereço do site sem www.
de duas maneiras:
- Usar um redirecionador grátis para redirecionar acessos do
exemplo.com.br
para o domíniowww.exemplo.com.br
. No entanto, haverá um aumento no tempo de resposta ao acessarexemplo.com.br
, pois a solicitação será redirecionada de um servidor para outro. Veja meu post sobre quais redirecionadores usar. - Usar o AWS Route53 para criar uma hosted zone e nela criar um registro A, que aponta para o CDN ligado a este bucket. Esse é a melhor solução, pois não há redirecionamentos, mas é necessário ter um pequeno gasto mensal de $0,50 para manter esse serviço
O Registro.br não permite apontar o domínio raíz exemplo.com.br
para uma URL, apenas para um IP. Já o Cloudfront fornece apenas uma URL como destino das requisições. Para continuar usando o DNS do Registro.br, é necessário usar a solução 1 acima e nessa caso, não será necessário criar o bucket deste passo.
Já para usar a solução 2, é necessário criar um segundo bucket que irá redirecionar a requisição internamente para o primeiro bucket.
Este bucket criado para o domínio raíz exemplo.com.br
irá redirecionar os acessos para o primeiro bucket www.exemplo.com.br
, que contém os arquivos do site estático.
Crie o bucket da mesma forma que o primeiro, só defina o nome deixando claro que é um bucket que é para o domínio sem www
.
Passo 4: Faça o upload do seu site estático para o primeiro bucket
Agora é hora de enviar os arquivos do site estático para o primeiro bucket. Vamos fazer algumas mudanças no nosso projeto Next.js.
Modifique o arquivo next.config.ts
, localizado na pasta raiz do projeto Next.js para habilitar a função de exportar em arquivos estáticos. Adicione a configuração output: ‘export’
. Veja mais detalhes na documentação oficial
O arquivo next.config.ts
ficará assim:
const nextConfig = {
output: 'export',
// Optional: Change links `/me` -> `/me/` and emit `/me.html` -> `/me/index.html`
// trailingSlash: true,
// Optional: Prevent automatic `/me` -> `/me/`, instead preserve `href`
// skipTrailingSlashRedirect: true,
// Optional: Change the output directory `out` -> `dist`
// distDir: 'dist',
}
Observe que sem essa configuração, o comando
npm run build
não produzirá os arquivos necessários para o site estático.
Agora digite no seu terminal, na pasta raíz do projeto: npm run build
. Esse comando produzirá uma pasta chamada ‘out’ na pasta raiz do projeto. Dentro dessa pasta estão todos os arquivos necessários para um site estático funcionar.
Agora vá para o bucket principal, que servirá arquivos para o domínio www.exemplo.com.br
e faça o upload de todos os arquivos que estão dentro da pasta out
.
Opcional
Os testes de velocidade como o pagespeed.web.dev
verificam se você tem uma política de cache e vão diminuir seus pontos de desempenho caso você não tenha especificado uma. Caso queira definir quanto tempo arquivos css, js, imagens podem ficar guardados no cache para evitar solicitações desnecessárias ao servidor, é bom configurar o TTL (Time to Live).
Na tela de upload em que você seleciona os arquivos para upload, clique em Properties para abrir mais opções, vá em Metadata
, clique em Add metadata
e escolha a opção System Defined
no campo Type
. Para o campo Key
, defina Cache-Control
e como value defina public, max-age=31536000
.
Essa configuração diz que public
permite que caches públicos como CDNs possam armazenar os arquivos (configurando como private
apenas caches privados, como o do navegador do usuário podem guardar os arquivos) e 31536000
se refere ao tempo de 1 ano em segundos que esses caches podem armazenar o arquivo antes de solicitar o arquivo novamente do servidor
Clique em ‘Upload’ para enviar esses arquivos para o bucket principal e espere o upload terminar.
Passo 5: Configure o bucket secundário para redirecionar para o bucket primário
Aqui não muda nada do tutorial. Veja instruções no tutorial da AWS.
Passo 6: Crie uma CDN na AWS Cloudfront para o bucket principal
-
Como origem preencha como:
<nome do bucket>.s3.us-east1-amazonaws.com
-
Nome: Bucket Principal
Em Origin access
, você irá configurar para permitir acesso ao bucket, apesar dos acessos a ele estarem bloqueados no momento. O Cloudfront irá liberar o acesso automaticamente.
-
Selecione
Legacy access identities
EmOrigin access identity
, selecioneAllows Cloudfront to reach the bucket
“Permita que o Cloudfront acesse o bucket”
EmBucket policy
, selecioneYes, update the bucket policy
(Sim, atualize a política do bucket). Você está permitindo que o bucket seja acessado pelo Cloudfront, apesar do bucket estar configurado por padrão para não permitir acessos -
Em
Viewer
, selecioneRedirect HTTP to HTTPS
(Redirecione acessos HTTP para HTTPS) -
Em
Web Application Firewall
, selecioneDo not enable security protections
Em Settings
:
- Em
Alternate domain name
, escolhaAdd item
e preencha com seu subdomíniowww.exemplo.com.br
- Em
Custom SSL certificate
, escolha o certificado que você criou anteriormente. - Na caixa de texto
Default root object
(Objeto raiz padrão), digite index.html.
Aceite os valores padrão dos demais campos e escolha Criar distribuição.
Crie a distribuição
Espere alguns minutos até que a criação da CDN esteja concluída. Neste momento você já tem um endereço para acessar o seu novo site!
Clique na distribuição que você criou, em General
você irá ver Distribution domain name
, copie o endereço e cole no seu navegador para visualizar o site.
Passo 7: Crie uma CDN na AWS Cloudfront para o bucket secundário
Esse passo não é necessário se você vai usar um redirecionador de exemplo.com.br
para www.exemplo.com.br
.
Caso você tenha optado por usar o Route53 para administrar o DNS do domínio, você precisará executar as instruções abaixo.
Agora vamos criar uma CDN para que possamos acessar o site sem o www
.
Ao criar uma nova distribuição e selecionamos como Origin domain
o valor <nome do domínio sem www>.s3.us-east-1.amazonaws.com
, vamos receber um alerta:
This S3 bucket has static web hosting enabled. If you plan to use this distribution as a website, we recommend using the S3 website endpoint rather than the bucket endpoint.
Como criamos o bucket com a funcionalidade de hospedagem de sites habilitada, ele nos avisa que é melhor usar o endpoint de site do que o endpoint de bucket. Vamos aceitar a sugestão clicando em Use website endpoint
. Observe que o Origin Domain
irá mudar para exemplo.com.br.s3-website-us-east-1.amazonaws.com
.
Use as configurações padrão que já estão selecionadas, exceto nas seguintes:
- Viewer protocol policy: selecione
Redirect HTTP to HTTPS
- Cache policy and origin request policy (recommended): selecione
CachingDisabled
- Web Application Firewall (WAF), selecione
Do not enable security protections
- Alternate domain name (CNAME) - optional, selecione o domínio raíz da sua URL (exemplo.com.br)
- Custom SSL certificate - optional, selecione o certificado que você criou anteriormente
Passo 8: Configure o Registro.br para que ele redirecione para o Cloudfront
Caso você tenha optador por usar um redirecionador para redirecionar de exemplo.com.br
para www.exemplo.com.br
, a configuração DNS do Registro.br ficará assim:
- Registro A com o valor de
exemplo.com.br
para o IP indicado pelo redirecionador de sites - Registro CNAME que valida o uso do certificado SSL criado pelo AWS Certificate Manager
- Registro CNAME para
www.exemplo.com.br
que aponta para o endereço do Cloudfront ligado ao bucket principal
Caso você tenha optado por usar o AWS Route53 para evitar redirecionamentos, ao criar a hosted zone
no Route53, você irá receber 4 endereços dos servidores da AWS. Clique em Alterar servidores DNS
no Registro.br e coloque os endereços nos campos indicados.
A partir deste momento, a administração de DNS do domínio passará do Registro.br para o painel do Route53. Veja as instruções de como configurar o DNS no tutorial da AWS.
Conclusão
Parabéns! Você criou um site estático na AWS! Ele tem um desempenho excelente, mas com um custo mensal bem pequeno.
Você pode incrementar seu site, fazendo com que ele converse com uma API, adicionando formulários ou integrando um CMS para que outras pessoas possam adicionar conteúdo sem precisar escrever código.
Próximos passos:
- Veja os números de desempenho do site no PageSpeed e no GTmetrix
- Veja custos do AWS Cloudfront e AWS S3 para verificar como qual será seus custos
- Use tag do Next.js, com alguns passos adicionais
- Crie um formlário e receba as respostas em um e-mail usando o W3Forms