Quick Start¶
Deploy your first application on AppMecca in under 5 minutes. We'll use the hello-flask sample app — a tiny Python Flask application.
What You'll Do¶
- Add an
appmecca.yamlconfig file to your repo - Register your app
- Build a Docker image
- Deploy it
- See it live
Prerequisites¶
- The
meccaCLI installed and configured (installation guide) - A Git repository accessible via SSH (GitHub, GitLab, etc.)
- An AppMecca environment ready (ask your admin for the environment name)
Step 1: Create Your App¶
You need a Git repository with at least two things: your application code and a Dockerfile.
Here's a minimal Flask app as an example. Your app can use any language or framework — as long as it runs in Docker, AppMecca can deploy it.
app.py:
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello from AppMecca!"
@app.route("/health")
def health():
return jsonify({"status": "healthy"})
Dockerfile:
FROM python:3.12-slim
WORKDIR /app
RUN pip install flask gunicorn
COPY app.py .
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
Health check endpoint
Every app deployed on AppMecca needs a health check endpoint — a URL that returns HTTP 200 when the app is working. This is how AppMecca knows your app is alive. It can be any path (e.g., /health, /healthz, /), and it just needs to return a 200 status code.
Step 2: Add appmecca.yaml¶
Create an appmecca.yaml file in the root of your repository:
containers:
- name: hello-flask
dockerfile: Dockerfile
context: .
deploy:
- name: web
container: hello-flask
port: 5000
health_check:
path: /health
This tells AppMecca:
- Build a Docker image called
hello-flaskusing theDockerfilein the repo root - Deploy it as a service called
web - The app listens on port 5000 inside the container
- Check
/healthto know if the app is running
Commit and push this file to your repository.
Unrecognised keys are silently ignored
AppMecca does not warn you about keys it doesn't recognise — a typo
like helth_check:, dockerfle: or replica: 2 is dropped without any
error, and your app deploys with the default behaviour instead of the one
you wrote. If a setting seems to have no effect, check its spelling against
the Configuration Reference first.
Step 3: Register Your App¶
Expected output
Some names are reserved, and you get the next one free
Your app's slug becomes part of its URL and of the paths the platform's
own API answers on, so a small set of names is reserved — the platform's
hostnames (api, dashboard, docs, monitor, mail, …) and the literal
segments of its API routes (claim, stable, summary, history, …).
You are never refused for asking. If the name you want is reserved, or another app in your group already has it, AppMecca registers you on the next free numbered variant and says so:
Apps registered before this rule existed keep the slug they have — a slug is a live URL, and AppMecca does not rename one out from under you.
This tells AppMecca about your app. It does not queue a build — instead it
runs a repository pre-flight check: AppMecca clones your repo and verifies
that it can reach the branch, that appmecca.yaml is present and valid, and
that every referenced Dockerfile exists. Until that check passes the app is
quarantined and builds and deploys are refused. If it reports a problem,
fix your repo and re-run:
Your app starts out private
New apps are registered as private: anyone outside your group gets an authentication challenge instead of your site. That's why the very first thing you may see at your app's URL is a login page rather than your homepage. Make it public whenever you're ready:
In the dashboard the same control is the Make public button next to
the Visibility badge on the app's overview. To take it private again
later, use mecca app protect hello-flask -e dev (or the dashboard's
Settings → Visibility).
A container app is public within a minute or two. A static site takes a few minutes the first time — going public creates its CloudFront distribution, and the URL 404s until that finishes. That is expected and needs no redeploy.
The app name is derived from the repository name (e.g., hello-flask). To use a different name, pass it as the second argument:
Registering a private repository
Bind it to your linked GitHub/GitLab account, so the platform clones with
your OAuth token instead of the environment deploy key. Link the account in
the dashboard first — binding uses an account you already have, it does not
create one. Then register with --link-git:
--link-git works out the provider from the repository URL (GitHub and
GitLab only), and it needs a signed-in session (mecca login) — an API key
has no linked account to bind. Picking the repository in the dashboard's
repo picker creates the same binding.
Without a binding, a private repo the deploy key cannot read is registered
and then held at no_access until you fix access, so nothing builds.
Which branch gets registered?
mecca register asks your repository for its default branch and uses that
— it no longer assumes main. If your repo's default is dev (or anything
else), that's what gets registered, so the first build compiles the code you
actually expect.
Pass -b <branch> to pick a different one explicitly (branch-isolated deploys
are a first-class feature — each branch gets its own database, URL and
containers). If the branch you choose isn't the repo's default, you'll get a
heads-up:
⚠ Registering branch 'main', but this repo's default branch is 'dev'.
If that's intentional, carry on. Otherwise re-run with -b dev.
That warning exists because registering a stale branch is silent and expensive: the build succeeds at cloning, then fails deep inside Docker with an error that says nothing about branches.
Step 4: Build¶
Expected output
mecca build trigger is fire-and-forget — it queues the work and returns
immediately rather than blocking. Follow progress with the commands it prints:
mecca queue status <build-id> -e dev # current state of the build
mecca build logs <build-id> -e dev # live build output
What happens during a build
AppMecca clones your repo, reads appmecca.yaml, builds each container using Docker, and pushes the images to the AppMecca private image registry. Each image is tagged with the Git commit hash.
A build deploys automatically
By default mecca build trigger also queues a deploy that runs as soon as
the build succeeds — that's the second id in the output above. Pass
--no-deploy if you want to build the image without shipping it. (There is
no --deploy flag; auto-deploy is the default.)
Step 5: Deploy¶
Step 4 already queued a deploy for you, so this step is only needed when you want to ship again without rebuilding — for example to redeploy the current image:
Expected output
Useful variants:
mecca app deploy hello-flask --no-build -e dev # ship the latest existing image
mecca app deploy hello-flask --image-tag abc1234 -e dev # roll back to a specific tag
Once the deploy reaches completed, your app is live at
https://hello-flask-web-<your-group>.dev.appmecca.net.
Step 6: Verify¶
Check that everything is working:
Expected output
mecca status <app> shows per-service health and anything currently
building or deploying. To inspect one queued action by its ID, use
mecca queue status <action-id>.
Two options are worth knowing:
mecca status hello-flask -b dev -e dev # a specific branch
mecca status hello-flask --json -e dev # machine-readable, app-scoped
Omit -b and the app's production branch is used, with the pipeline
list covering every branch. The --json form emits one document —
app, branch, branch_filter, pipeline, incidents, stats —
and keeps stdout a pure JSON stream, so it pipes into jq
cleanly; errors go to stderr and exit non-zero. (mecca status --json
with no app still returns the environment-wide summary.)
Visit https://hello-flask-web-<your-group>.dev.appmecca.net in your browser.
You should see "Hello from AppMecca!" — or a login page, if you haven't run
mecca app publish hello-flask yet.
What Just Happened?¶
Behind the scenes, AppMecca:
- Built your Docker image with the AppMecca build service
- Pushed the image to the AppMecca private image registry
- Queued a deployment request in the platform
deploy_queue - An agent on one of the AppMecca hosts picked up the request
- The agent pulled your image from the image registry
- The agent started your container with
docker run - The AppMecca HTTPS router started routing traffic to your container
- The router's health check confirmed your app was responding
All of this happened automatically. You just ran three commands.
Next Steps¶
Now that your first app is deployed, explore these topics:
- Configuration Reference — Learn all the options in
appmecca.yaml - Add a Database — Add PostgreSQL to your app with one line
- Add Redis Caching — Enable Redis with one line
- Multi-Container Apps — Deploy a frontend + backend from one repo
- Branch Deployments — Deploy feature branches side by side with full isolation
- Environment Variables — Pass secrets and config to your containers
- Examples — See complete sample apps for every pattern
Redeploy an Existing App¶
If you need to redeploy an app (e.g., after a failed deployment or to restore a known-good state), use the redeploy command:
This rebuilds from the registered repository and branch, then deploys. To skip the build and redeploy the latest existing image:
To roll back to a specific older image instead, use mecca app deploy with
--image-tag (redeploy has no tag selector):
mecca build list -a hello-flask -e dev # Tag column, newest first
mecca app deploy hello-flask --image-tag abc1234 --no-build -e dev
Retry a Failed Deploy (Transient Failures)¶
When a deploy fails for a transient platform reason — an image-pull flake, a health check racing a slow startup, a router drain timeout — you can retry only the failing phase in-place on the same host slot and same blue/green color the failed attempt used, without re-computing placement or rebuilding the image:
Retry refuses with a concrete hint when the failure class is
non-retriable (app error, invalid config, build failed). For those
cases the hint points at the right tool (mecca app redeploy,
mecca build trigger, rollback with mecca app deploy --image-tag), so
retry is safe as the first-line response to any failed deploy.
Capped at 3 attempts; after the cap the endpoint refuses with a
pointer at mecca debug <app> + redeploy.
It also refuses once the failure has been superseded — that is, once a later deploy of the same app and branch exists that did not itself fail or get cancelled, including a retry you already queued:
✗ Not retried: a later DEPLOY (9a1b2c3d, completed) of 'hello-flask' on branch
'main' exists. Retrying the older failure would reuse its image and
blue/green slot over it. Redeploy instead.
That is not a limitation to work around. A retry deliberately reuses the failed
attempt's image and blue/green slot, so retrying a failure that something newer
has already replaced would put the old image back over the newer attempt's live
container. Redeploy instead, or — if the named row is still queued or running —
wait for it, or cancel it with mecca queue cancel <id>.
Shortcut: Build and Deploy in One Command¶
There is nothing extra to do — Step 4's mecca build trigger already queues
the deploy for you:
Auto-deploy is the default. Pass --no-deploy to build the image without
shipping it.