Deploy an app with a database (App plan)
Logins, orders, a dashboard with data: then your project is a Node or Next app, not a static site. It runs with us in its own container with its own Postgres database (€ 15 a month after a 14-day trial). The image is built on GitHub, never on our server, so this always goes through a workflow in your repository:
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 }}
The first run creates the site and a registry token, binds the site to your repository and tells you which three secrets to set: the site id and the two registry values. permissions: id-token: write lets every next run prove that it comes from your repository, so there is no deploy token to store; the registry values stay, because docker push needs them. In a public repository anyone can read what a run shows, so make the registry password in the portal there, as described below. Did a first publication already run in a public repository? Then also make a new deploy token in the portal, and do one run with that token (deploy-token) and bind-github: true: a token that once showed up in a run stops working, and the site is bound again. Keep the workflow on on: push to main and avoid pull_request_target: the platform trusts every run from your repository, so a workflow that also runs for pull requests from strangers would let them publish your site. Runs started by pull_request_target, issues, issue_comment, discussion or discussion_comment are refused anyway. Have a site with a deploy token already? Add bind-github: true to the step for one run: the platform then binds the site to your repository, and the token can go. Your app gets DATABASE_URL and PORT (default 3000) as environment variables. No Dockerfile needed: we then use npm ci, npm run build, npm start. Have your own Dockerfile? It is used as is. Lost the registry password, or does a run fail at docker login? On the Agents tab of your app in the portal, press New password under Registry token, and put the password in the DORELLI_REGISTRY_PASSWORD secret; the user stays the same, and only the last password shown works.
Secrets of your own, such as an API key: put them in your repository secrets and add a secrets block to the step, one NAME=value per line, for example API_KEY=${{ secrets.API_KEY }}. They go only to your container and arrive as environment variables, from the second run on, once the container exists; we keep the names, never the values. Names are capitals, digits and _, at most 20 per app; PORT, DATABASE_URL, POSTGRES_URL, REDIS_URL, STORAGE_CONNECTION_STRING (also with a suffix) and DORELLI_* are set by us. Secrets work on our own Azure places; a site that is paused gets none until it runs again.
The app scales to zero without traffic; the first visit after a quiet period takes 10 to 30 seconds, see Cold starts. Logs, restart and environment variables are in your portal, see Logs, restart and variables.
Checked against the code on 16 October 2026 · Evidence: app/deploy/page.tsx, lib/app-deploy.ts, lib/github-oidc.ts, .github/actions/dorelli-deploy/action.yml, components/RegistryTokenForm.tsx