Logins, encomendas, um dashboard com dados: então o teu projeto é uma app Node ou Next, não um site estático. Corre connosco num contentor próprio com base de dados Postgres própria (€ 15 por mês depois de 14 dias de teste). A imagem é construída no GitHub, nunca no nosso servidor, por isso isto passa sempre por um workflow no teu repositório:

```yaml
name: Deploy app to Dorelli
on:
  push:
    branches: [main]

permissions:
  contents: read
  id-token: write

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: dorelli-cloud/action@v1
        with:
          plan: app
          email: you@example.com
          site-id: ${{ secrets.DORELLI_SITE_ID }}
          registry-user: ${{ secrets.DORELLI_REGISTRY_USER }}
          registry-password: ${{ secrets.DORELLI_REGISTRY_PASSWORD }}
```

A primeira execução cria o site e um token de registry, liga o site ao teu repositório e diz-te que três secrets deves definir: o id do site e os dois valores de registry. Com `permissions: id-token: write`, cada execução seguinte prova que vem do teu repositório, por isso não há token de deploy para guardar; os valores de registry ficam, porque o docker push precisa deles. Num repositório público qualquer pessoa pode ler o que uma execução mostra, por isso cria a palavra-passe de registry no portal, como se explica mais abaixo. Já houve uma primeira publicação num repositório público? Então cria também um novo token de deploy no portal, e faz uma execução com esse token (`deploy-token`) e `bind-github: true`: um token que alguma vez apareceu numa execução deixa de funcionar, e o site volta a ficar ligado. Mantém o workflow em `on: push` para `main` e evita `pull_request_target`: a plataforma confia em cada execução vinda do teu repositório, por isso um workflow que também corra para pull requests de desconhecidos deixá-los-ia publicar o teu site. Execuções iniciadas por `pull_request_target`, `issues`, `issue_comment`, `discussion` ou `discussion_comment` são recusadas de qualquer forma. Já tens um site com token de deploy? Põe `bind-github: true` no passo durante uma execução: a plataforma liga então o site ao teu repositório, e o token pode desaparecer. A tua app recebe `DATABASE_URL` e `PORT` (3000 por omissão) como variáveis de ambiente. Não é preciso Dockerfile: usamos então `npm ci`, `npm run build`, `npm start`. Tens um Dockerfile próprio? É usado tal como está. Perdeste a palavra-passe do registry, ou uma execução falha no docker login? No portal, separador Agents da tua app, em Token de registry, carrega em Nova palavra-passe e põe a palavra-passe no secret `DORELLI_REGISTRY_PASSWORD`; o utilizador continua o mesmo, e só a última palavra-passe mostrada funciona.

Os teus próprios segredos, como uma chave de API: guarda-os nos secrets do teu repositório e acrescenta ao passo um bloco `secrets`, um `NOME=valor` por linha, por exemplo `API_KEY=${{ secrets.API_KEY }}`. Vão apenas para o teu contentor e chegam como variáveis de ambiente, a partir da segunda execução, quando o contentor já existe; guardamos os nomes, nunca os valores. Os nomes são maiúsculas, algarismos e `_`, no máximo 20 por app; `PORT`, `DATABASE_URL`, `POSTGRES_URL`, `REDIS_URL`, `STORAGE_CONNECTION_STRING` (também com um sufixo) e `DORELLI_*` somos nós que definimos. Os segredos funcionam nos nossos próprios locais Azure; um site em pausa só os recebe quando volta a funcionar.

A app escala até zero sem tráfego; a primeira visita depois de um período parado demora 10 a 30 segundos, vê [Arranques a frio](/docs/apps/cold-start). Os logs, o reinício e as variáveis de ambiente estão no teu portal, vê [Logs, reinício e variáveis](/docs/apps/portal).