# Receitas: sites estáticos

Exemplos prontos para copiar, do site novo ao deploy automático. Cada receita
traz o comando, o que ele devolve e um prompt para pedir a mesma coisa ao seu
agente. As saídas abaixo são reais, tiradas do rapadura em produção.

Antes de começar: CLI instalada e `rapadura login` feito
([Começando](comecando.md)). Nos exemplos o site se chama `php-sobral-2026`;
troque pelo seu.

## Um site novo em HTML puro

Uma pasta com `index.html` na raiz já é um site. Nada para instalar, nada
para configurar.

```
site/
  index.html
  programacao.html
  palestrantes/index.html
  404.html
  style.css
  img/palco.png
```

```sh
rapadura publish ./site --site php-sobral-2026 --create --title "PHP Sobral 2026"
```

```text
Packed 7 files (0.0 MB), uploading...
Created php-sobral-2026.rapadura.net
PHP Sobral 2026 is live at https://php-sobral-2026.rapadura.net (version 1).
  live: https://php-sobral-2026.rapadura.net
  version: 1 (7 files, 0.0 MB)
  version url: https://php-sobral-2026--v1.rapadura.net
  next: Open https://php-sobral-2026.rapadura.net to confirm the result; the first HTTPS visit may take a few seconds while the certificate is issued.
  next: Publish again to the same site to update it. Roll back any time with: rapadura rollback php-sobral-2026.rapadura.net 1
  next: Version 1 keeps its own address for as long as it is retained: https://php-sobral-2026--v1.rapadura.net
```

O que o servidor faz com essa pasta:

- `programacao.html` responde em `/programacao` e em `/programacao.html`.
- `palestrantes/index.html` responde em `/palestrantes/` (e `/palestrantes`
  redireciona para lá).
- `404.html` vira a página de "não encontrado".
- Imagens, CSS e JS ficam em cache por uma semana. Ao trocar um arquivo,
  troque o nome (`style.v2.css`) se precisar que todo mundo veja na hora.

```prompt
Crie um hotsite de uma página para o PHP Sobral 2026 (14 de novembro, Sobral, Ceará) na pasta ./site: apresentação, programação, palestrantes e um botão de inscrição apontando para https://www.sympla.com.br/. HTML e CSS puros, sem frameworks. Depois publique no rapadura como php-sobral-2026 e me diga o endereço e a versão.
```

## Com um gerador de sites

Rode o build e publique **a pasta de saída**, nunca a raiz do projeto.

| ferramenta | build | publique |
|---|---|---|
| Astro | `npm run build` | `./dist` |
| Vite (React, Vue, Svelte) | `npm run build` | `./dist` |
| Hugo | `hugo` | `./public` |
| Eleventy | `npx @11ty/eleventy` | `./_site` |
| Jekyll | `bundle exec jekyll build` | `./_site` |
| Next.js com `output: 'export'` | `npm run build` | `./out` |

```sh
npm run build && rapadura publish ./dist --site php-sobral-2026 --create
```

O site é servido na raiz do domínio. Se o gerador pede o endereço final
(`site` no Astro, `baseURL` no Hugo, `url` no Jekyll), use
`https://php-sobral-2026.rapadura.net/` e deixe o `base` vazio.

**O tropeço comum.** Publicar a raiz do repositório leva junto `.env`,
chaves ou arquivos `.php`, e o rapadura recusa tudo de uma vez, com a lista:

```text
error (archive_forbidden_file): 2 file(s) cannot be published:
  .env (credential-like file)
  contato.php (server-side code is never executed on the static lane)
hint: publish a generated output directory that holds only the public files
```

Não existe forma de forçar. Publique a pasta de saída ou tire os arquivos.
`.git`, `node_modules`, `vendor` e `.cache` são ignorados sem aviso.

```prompt
Faça o build deste projeto e publique a pasta de saída no rapadura como php-sobral-2026, criando o site se ainda não existir. Se o rapadura recusar algum arquivo, me mostre a lista e não tente contornar.
```

## Atualizar, conferir e voltar

Publicar de novo no mesmo site cria uma versão nova. `-m` guarda uma nota.

```sh
rapadura publish ./site --site php-sobral-2026 -m "inscrições abertas"
rapadura versions php-sobral-2026
```

```text
VERSION  STATUS    FILES  SIZE   BY    WHEN              URL                                       MESSAGE
v2       live      7      0.0MB  rtio  2026-10-13 11:54  https://php-sobral-2026--v2.rapadura.net  inscrições abertas
v1       archived  7      0.0MB  rtio  2026-10-13 11:54  https://php-sobral-2026--v1.rapadura.net
```

Cada versão guarda o próprio endereço (`php-sobral-2026--v1.rapadura.net`)
enquanto for mantida: compare duas versões lado a lado, ou mostre a alguém
uma versão que já não está no ar (depois de uma volta de versão, por
exemplo).

Algo quebrou? Volte para a versão anterior. Nada é reconstruído: a troca é
instantânea e atômica.

```sh
rapadura rollback php-sobral-2026 1
rapadura sites show php-sobral-2026
```

```text
php-sobral-2026.rapadura.net
  status: live
  version: v1
  owner: rtio
  live: https://php-sobral-2026.rapadura.net
  created: 2026-10-13 11:54
  title: PHP Sobral 2026
```

Para avançar de novo, rode `rollback` com o número da versão mais nova. As
últimas 20 versões ficam guardadas.

```prompt
A última publicação do php-sobral-2026 quebrou a página inicial. Veja as versões no rapadura, volte para a anterior e confirme abrindo o site.
```

## Redirecionamentos e página 404

Um arquivo `_redirects` na raiz do site, uma regra por linha:
`origem destino [301|302]`. Só caminhos exatos, sem curingas.

```
/inscricoes   https://www.sympla.com.br/   302
/2025/        /                            301
```

```sh
curl -sI https://php-sobral-2026.rapadura.net/inscricoes | grep -iE '^(HTTP|location)'
```

```text
HTTP/2 302
location: https://www.sympla.com.br/
```

O `_redirects` em si nunca é servido, e uma linha inválida recusa a
publicação dizendo qual é. Para a página de erro, basta um `404.html` na
raiz.

## Tirar do ar e trazer de volta

```sh
rapadura sites delete php-sobral-2026 --yes
```

```text
php-sobral-2026.rapadura.net is offline. Files are kept for a while; bring it back with: rapadura sites restore php-sobral-2026.rapadura.net
```

Os visitantes recebem `410 Gone` e o nome continua reservado para você.
Mudou de ideia?

```sh
rapadura sites restore php-sobral-2026
```

```text
php-sobral-2026.rapadura.net is back online at https://php-sobral-2026.rapadura.net (status live, version v1).
```

O site volta com a versão que estava no ar e todo o histórico.

## Um domínio próprio

Um hotsite estático também pode responder num domínio do evento, como
`www.phpsobral.com.br`. Peça; o pedido espera a aprovação do owner e já diz
qual registro de DNS criar enquanto isso:

```sh
rapadura domain add php-sobral-2026 www.phpsobral.com.br --reason "domínio do evento, registrado pela organização"
```

```text
Request #2 (domain.add www.phpsobral.com.br → php-sobral-2026.rapadura.net) is waiting for the owner's approval.
  next: Point www.phpsobral.com.br at 168.196.105.251 (A record) — the certificate is issued automatically on first visit after approval.
  next: Nothing changes until the owner approves; the site keeps answering at https://php-sobral-2026.rapadura.net.
  next: The owner decides at https://agents.rapadura.net/approvals or with: rapadura approvals approve 2
  next: Undecided, the request expires on 2026-10-20. Follow it with: rapadura approvals
```

Acompanhe com `rapadura approvals`; depois de aprovado,
`rapadura domain list php-sobral-2026` mostra o domínio.
`rapadura domain remove` desliga sem precisar de aprovação. As regras
(nomes recusados, sites WordPress) estão em [Regras e limites](regras.md#nomes).

```prompt
Peça ao rapadura para ligar www.phpsobral.com.br ao hotsite php-sobral-2026, me diga exatamente qual registro de DNS eu preciso criar e como acompanho o pedido.
```

## No domínio phpcomrapadura.org

O mesmo site pode morar em `phpcomrapadura.org`. Use o nome completo:

```sh
rapadura publish ./site --site php-sobral-2026.phpcomrapadura.org --create
```

ou `--site php-sobral-2026 --zone phpcomrapadura.org`. São dois sites
independentes, cada um com suas versões. `rapadura zones` lista os domínios
disponíveis e os limites.

## Acompanhar os acessos

```sh
rapadura logs php-sobral-2026 -n 20
```

Cada linha é um JSON com hora, caminho, status, tamanho e navegador. Com
`jq`, as páginas mais vistas entre os últimos 2000 acessos:

```sh
rapadura --json logs php-sobral-2026 -n 2000 \
  | jq -r '.lines[] | fromjson | .uri' | sort | uniq -c | sort -rn | head
```

```prompt
Olhe os últimos 2000 acessos do php-sobral-2026 no rapadura e me diga as páginas mais visitadas, quantos 404 houve e em quais endereços.
```

## Publicar a cada push (GitHub Actions)

Peça ao administrador um token só para o CI, um por repositório (ele cunha
com `rapadura admin bootstrap-token`, veja [Administração](admin.md#tokens)).
Salve como secret `RAPADURA_TOKEN` no repositório. Nunca use o token do seu
computador nem cole token em arquivo do projeto.

```yaml
# .github/workflows/publicar.yml
name: publicar
on:
  push:
    branches: [main]

jobs:
  publicar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci && npm run build
      - name: Instalar a CLI do rapadura
        run: |
          curl -fsSL https://agents.rapadura.net/install.sh | sh
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
      - name: Publicar
        run: rapadura publish ./dist --site php-sobral-2026 -m "commit ${GITHUB_SHA::7}"
        env:
          RAPADURA_TOKEN: ${{ secrets.RAPADURA_TOKEN }}
```

Se a publicação falhar, o passo falha e a versão anterior continua no ar.

## Mais prompts para testar

```prompt
Liste meus hotsites no rapadura com a versão de cada um e me diga quais não recebem publicação há mais de 30 dias.
```

```prompt
Atualize só a programação do php-sobral-2026 a partir do arquivo programacao.csv (colunas: horário, título, palestrante). Mantenha o resto do site igual, publique com a mensagem "programação atualizada" e me mande o endereço.
```

```prompt
Copie o php-sobral-2026 para php-sobral-2026.phpcomrapadura.org: publique a mesma pasta lá e confira que as duas URLs abrem.
```
