Skip to content

Configuration Overview

The appmecca.yaml file is the heart of your AppMecca deployment. It lives in the root of your Git repository and tells AppMecca:

  1. What to build — which Docker images to create
  2. How to run it — ports, health checks, commands
  3. What it needs — database, cache, environment variables

Don't write it by hand

The dashboard's config wizard asks you a handful of questions and writes this file for you, validated against the platform's own rules before you download it. Open it from Apps → “No appmecca.yaml yet? Build one”.

Where It Goes

your-repo/
├── appmecca.yaml      ← this file
├── Dockerfile
├── src/
│   └── ...
└── ...

The file must be named exactly appmecca.yaml and must be in the repository root.

Minimal Example

The simplest possible appmecca.yaml for an app with one container:

containers:
  - name: myapp
    dockerfile: Dockerfile
    context: .

deploy:
  - name: web
    container: myapp
    port: 8000
    health_check:
      path: /health

This tells AppMecca: "Build a Docker image called myapp from the Dockerfile in the repo root, then run it as a service called web on port 8000, and check /health to know if it's alive."

Full Example

Here's a complete appmecca.yaml showing all available options:

# What Docker images to build
containers:
  - name: frontend
    dockerfile: frontend/Dockerfile
    context: frontend/

  - name: backend
    dockerfile: backend/Dockerfile
    context: backend/
    args:
      NODE_ENV: production

# How to run the containers
deploy:
  - name: frontend
    container: frontend
    port: 3000
    health_check:
      path: /
    environment:
      API_URL: "${service:backend:internal}"
    cache:
      enabled: true
      behaviors:
        - path: "/assets/*"
          ttl: 31536000
          compress: true
      default_ttl: 300
      invalidate_on_deploy: true

  - name: backend
    container: backend
    port: 8080
    path: /api          # mounted under the app's one URL; the mount is not stripped
    command: "gunicorn app:application -w 4 -b 0.0.0.0:8080"
    health_check:
      path: /api/health
      interval: 30
      timeout: 5
    environment:
      DJANGO_SETTINGS_MODULE: myapp.settings.production

  - name: worker
    container: backend
    command: "celery -A myapp worker -l info"
    # No port = internal service, no web traffic

# Enable PostgreSQL database
database:
  enabled: true
  # runtime_role: true   # optional — a non-owner role for row-level security (see Database)

# Enable Redis cache
redis:
  enabled: true

# Scheduled requests to your own endpoints
cron:
  - name: cleanup-old-sessions
    schedule: "0 3 * * *"
    url: /api/internal/cleanup   # includes backend's mount
    service: backend

All Top-Level Fields

Section Required Purpose Details
app_name No Override the app name (defaults to repository name) String
containers Conditional What Docker images to build. Not needed when every service is type: static Containers
deploy Yes The services that make up your app Services
static_site Conditional Build + output settings for type: static / type: spa services. Required when any service is type: static — either here or per-service Services
database No Enable a managed PostgreSQL database Database
cache (top-level) No Enable the managed Redis cache Cache
email No Enable transactional email through the platform relay Email
storage No Declare drives and buckets Storage
deploy[].cache No Enable edge content caching for a service Content Caching
cron No Scheduled HTTP requests to your own endpoints Cron Jobs

Unknown keys are silently ignored

AppMecca ignores any key it does not recognise — there is no error and no warning. A misspelled contaiers:, a cahe: block, or a field nested one level too deep simply does nothing, and the deploy proceeds as though you had never written it.

The same applies to a misspelled type: value: type: statik is not rejected, it just falls through to "ordinary container service".

If a setting appears to have no effect, check its spelling and indentation first.

containers is not always required

An app whose services are all type: static builds no image and runs no container, so it needs no containers: block and no Dockerfile. Add one only when at least one service actually runs as a container.

Cron Jobs

A cron job is a scheduled HTTP request the platform makes to one of your own endpoints — not a command run inside your container. You write the endpoint; AppMecca calls it on your schedule.

cron:
  - name: cleanup-old-sessions
    schedule: "0 3 * * *"      # daily at 03:00 UTC
    url: /api/internal/cleanup # must start with /, and include the mount
    service: backend           # required when the app has more than one service

  - name: generate-reports
    schedule: "0 */6 * * *"    # every 6 hours
    url: /api/internal/reports
    service: backend
    method: POST
    timeout: 120
Field Required Default Description
name Yes -- Unique job name within the app (1-64 chars).
schedule Yes -- Cron expression — exactly 5 fields, UTC.
url Yes -- Path under your app's URL to request. Must start with /. If the service is mounted with path:, the url must include that mount (here backend is mounted at /api), because the mount is passed to the service, not stripped. Preflight refuses a url that cannot reach the named service.
service Conditional -- Which service to call. Required when the app has more than one.
method No POST GET or POST.
timeout No 30 Seconds to wait for a response (5-300).

Design the endpoint for it

Because the trigger is an HTTP request, the work runs inside your already-running service — there is no separate container to start, and nothing to install. Guard the route so only the platform can call it (it is reachable on your service's normal URL), keep it idempotent, and return quickly: hand long work to a background worker rather than holding the request open. If a job needs longer than 300 s, the endpoint should enqueue rather than execute.

Cron jobs are synced to the platform on every deploy. Manage them from the CLI — note that the app name is a positional argument, not a -a flag:

mecca cron list myapp
mecca cron history myapp
mecca cron trigger myapp cleanup-old-sessions
mecca cron disable myapp generate-reports
mecca cron enable myapp generate-reports

Each run records its start time, HTTP status and duration.

How the Sections Connect

The containers section defines what to build. The deploy section defines how to run it. They connect through the container field:

containers:
  - name: my-image        # ← This name...
    dockerfile: Dockerfile
    context: .

deploy:
  - name: web
    container: my-image   # ← ...is referenced here
    port: 8000

You can run multiple services from the same container image. For example, a web server and a background worker can both use the same image but with different commands:

containers:
  - name: myapp
    dockerfile: Dockerfile
    context: .

deploy:
  - name: web
    container: myapp
    port: 8000
    command: "gunicorn app:application"

  - name: worker
    container: myapp
    command: "celery -A app worker"
    # No port — this is an internal worker

Next Steps