Deployment

Maravilla offers multiple ways to deploy your applications, from simple manual uploads to fully automated CI/CD pipelines. All deployments are atomic, immutable, and distributed globally with zero downtime.

Deployment Methods

1. Git Push Deployment

Push code to a Maravilla-hosted git remote and your site is built and deployed automatically. This is the recommended workflow for most projects.

# Add the Maravilla remote to your project
git remote add maravilla http://<tenant>.git.maravilla.cloud/<namespace>/<project>.git

# Push to deploy
git push maravilla main

When you push:

  1. The receive-pack hook detects the push event
  2. If .maravilla/pipeline.yml exists, the full pipeline runs (test, lint, build, etc.)
  3. If no pipeline file exists, Maravilla runs a single build job: clone, detect framework, install dependencies, build, and deploy
  4. The build artifact is extracted to the deployment directory
  5. Your site is live at https://<project>-<handle>.maravilla.page

2. Pipeline Deployment

For projects with a .maravilla/pipeline.yml, deployment is triggered automatically when the pipeline completes. The pipeline produces build artifacts, and Maravilla deploys them directly — no re-build happens on the deployment side.

# .maravilla/pipeline.yml
name: build-and-deploy
image: node:22-alpine

on:
  push:
    branches: [main]

jobs:
  install:
    commands:
      - npm ci
    artifacts:
      paths: [node_modules/]

  test:
    needs: install
    commands:
      - npm test

  build:
    needs: [install, test]
    commands:
      - npm run build
    artifacts:
      paths: [dist/]

The build job’s dist/ artifact is collected and deployed automatically. See the Pipelines documentation for the full YAML reference.

3. ZIP Upload via Web UI

Upload a ZIP file containing your static site through the Maravilla dashboard. Best for quick updates and one-off deployments.

  1. Navigate to your project dashboard
  2. Click Deploy or drag and drop a ZIP file
  3. The archive is extracted and deployed immediately

File limits:

  • Individual file: 50 MB
  • Total deployment: 250 MB

4. API Key Deployment

Deploy programmatically using project-scoped API keys. This integrates with any CI/CD system.

# Upload a ZIP file with an API key
curl -X POST https://api.maravilla.cloud/api/upload \
  -H "X-API-Key: your-project-api-key" \
  -F "file=@dist.zip"

Generate an API key in your project settings under Settings > API Keys. Each key is scoped to a single project.

API keys work with any CI/CD provider:

# GitHub Actions example
- name: Deploy to Maravilla
  run: |
    zip -r dist.zip dist/
    curl -X POST https://api.maravilla.cloud/api/upload \
      -H "X-API-Key: ${{ secrets.MARAVILLA_API_KEY }}" \
      -F "file=@dist.zip"

Deployment Process

1. Upload Phase

Your files are uploaded to Maravilla’s processing servers:

  • ZIP extraction (for uploads)
  • Git clone (for push deployments)
  • File validation

2. Build Phase

If build settings are configured (or auto-detected):

  • Framework detection (40+ frameworks supported)
  • Dependency installation (npm ci, yarn install, bundle install, etc.)
  • Build command execution
  • Output collection

Maravilla auto-detects frameworks like Astro, Next.js, Gatsby, Hugo, Jekyll, Vite, SvelteKit, and many more. You can override detection with manual build settings.

3. Deploy Phase

Files are distributed to the hosting infrastructure:

  • Atomic switch to new version
  • Zero downtime
  • Subdomain routing via https://<project>-<handle>.maravilla.page

Custom Domains and SSL

Custom domains are supported with automatic SSL certificate provisioning:

  1. Add your custom domain in Settings > Domains
  2. Configure DNS to point to your Maravilla deployment:
    • CNAME record: yourdomain.com -> <project>-<handle>.maravilla.page
    • Or an A record pointing to the provided IP address
  3. SSL certificates are automatically provisioned and renewed via Let’s Encrypt

Request Headers

The Maravilla delivery proxy injects metadata onto every request before forwarding it to your app — on both *.maravilla.page URLs and custom domains. Read these headers from your framework’s request object the same way you’d read any other HTTP header.

X-Country-Code

Two-letter ISO 3166-1 alpha-2 country code for the visitor’s IP address (e.g. US, DE, CH, JP). Useful for currency selection, regional content, or compliance gating without shipping a GeoIP database to the browser.

// React Router 7 — loader / action
export async function loader({ request }: Route.LoaderArgs) {
  const country = request.headers.get('x-country-code') ?? 'XX';
  return { country };
}
// SvelteKit — +page.server.ts
export const load: PageServerLoad = ({ request }) => {
  const country = request.headers.get('x-country-code') ?? 'XX';
  return { country };
};

Treat the value as a hint, not as proof of location — VPNs, mobile carriers, and unknown IPs can produce wrong or empty results. Always provide a sensible fallback for an unknown value.


Environment Variables and Secrets

Maravilla stores two kinds of build-time configuration on every project:

  • Variables — plain key/value pairs (e.g. PUBLIC_API_BASE, BRAND_DOMAIN). Visible to project members.
  • Secrets — encrypted at rest with AES-256-GCM and gated behind a vault password (e.g. STRIPE_API_KEY, DATABASE_URL).

Each entry has three independent slots so you can set distinct values per environment:

SlotUsed by
defaultFallback when a more specific slot isn’t set.
productionProduction builds.
previewPreview / PR-deploy builds.

Both kinds can live at two scopes:

  • Project — applies to one project. Project values override org values for the same key.
  • Org — applies to every project in the org. Set once, reuse everywhere.

From the CLI

The CLI mirrors gh variable / gh secret:

# Plain variables
maravilla variable set PUBLIC_API_BASE --body https://api.example.com --env production
maravilla variable list --env production
maravilla variable set --env-file .env.production --env production   # bulk import

# Encrypted secrets (prompts for the vault password)
maravilla secret set STRIPE_API_KEY --env production
maravilla secret list

# Org-scope — applies to every project in the org
maravilla variable set BRAND_DOMAIN --body example.com --org acme
maravilla secret set SHARED_DB_URL --org acme --env production

# See exactly what a build will receive
maravilla env list --env production
maravilla env list --env production --show-secrets   # decrypt values

Full flag list: CLI reference › variable, secret, env.

From the dashboard

The same operations are available in the project dashboard under Settings > Vault, including a paste-an-.env-blob bulk import. The CLI and dashboard write to the same store.

How values reach your build

  • Variables and the matching environment’s secrets are injected as process env vars at build time.
  • Your build commands (npm run build, anything in .maravilla/pipeline/*.yml) have full access via process.env.
  • Secrets never appear in deployed files, build logs, or API responses; values are encrypted at rest.
  • Org values cascade into projects automatically — no per-project copy needed.

Framework prefixes for client-side values

Follow your framework’s conventions for variables that should ship to the browser:

FrameworkPrefixExample
Vite / AstroVITE_VITE_API_URL
Create React AppREACT_APP_REACT_APP_API_URL
Next.js (client)NEXT_PUBLIC_NEXT_PUBLIC_API_URL

Never put real secrets behind these prefixes — the values end up in the JS bundle. Keep client-safe values as variables, anything sensitive as secrets.

Pipeline integration

Variables and secrets are automatically merged into the env passed to every pipeline job. Reference them by name in your pipeline.yml:

jobs:
  build:
    commands:
      - npm ci
      - npm run build
    env:
      NODE_ENV: production
    secrets: [DATABASE_URL, DEPLOY_TOKEN]

See Pipelines › Secrets for the full pipeline-side reference.


Deployment Rollback

Every deployment is immutable and tracked. Roll back to any previous deployment:

  1. Navigate to your project’s Deployments tab
  2. Find the deployment you want to revert to
  3. Click Rollback

Rollback is instant — the previous version is activated without a rebuild. Your site switches atomically with zero downtime.


Deployment States

StateDescription
PendingDeployment created, waiting for processing
BuildingExecuting build commands and installing dependencies
DeployingUploading to hosting infrastructure
SuccessDeployment complete, site is live
FailedError occurred; check logs for details. Previous version remains active.

Best Practices

  1. Test locally before deploying — run npm run build (your framework’s build, which invokes the Maravilla adapter) and then maravilla preview to verify your production build
  2. Use pipelines for team projects — add tests and linting as gates before deployment
  3. Store secrets in the Vault — never commit API keys or credentials to your repository
  4. Use framework auto-detection — Maravilla handles build commands and output directories automatically for 40+ frameworks
  5. Tag releases — use git tags to mark deployments for easy rollback identification