Skip to content

Part 1: Your First Deployment

Deploy a hello-world Spring Boot application to AppMecca in under ten minutes.

Mix and match

If you've completed another tutorial track, you can mix and match -- any frontend from one track works with any backend from another. The API contract is identical across all tracks.

What you'll learn

  • Writing a minimal Spring Boot application with a health endpoint
  • Creating a multi-stage Dockerfile for Java apps
  • Writing an appmecca.yaml build and deploy manifest
  • Authenticating, registering, building, deploying, and undeploying

What you'll need

  • An AppMecca environment with infrastructure already set up (appmecca infra setup)
  • Java 21 and Gradle 8 installed locally (for development only -- builds run in the cloud)
  • A Git repository (GitHub or GitLab) for your application code

Scaffold the Spring Boot app

Create a minimal Spring Boot application with two endpoints.

// src/main/java/com/example/todo/TodoApplication.java
package com.example.todo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@SpringBootApplication
@RestController
public class TodoApplication {

    public static void main(String[] args) {
        SpringApplication.run(TodoApplication.class, args);
    }

    @GetMapping("/")
    public Map<String, String> index() {
        return Map.of("message", "Hello from AppMecca!");
    }

    @GetMapping("/health")
    public Map<String, String> health() {
        return Map.of("status", "healthy");
    }
}
# src/main/resources/application.properties
server.port=8080

Write the Dockerfile

Use a multi-stage build to keep the runtime image small. The build stage compiles with Gradle, and the runtime stage uses a minimal JRE.

# Stage 1: Build
FROM gradle:8-jdk21 AS build
WORKDIR /app
COPY build.gradle settings.gradle ./
COPY src ./src
RUN gradle bootJar --no-daemon

# Stage 2: Runtime
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Why multi-stage?

The Gradle build image is over 800 MB. The final JRE-alpine image is around 200 MB. Multi-stage builds discard the build tools and ship only the compiled JAR.

Write the appmecca.yaml

Create appmecca.yaml in the repository root. This tells AppMecca how to build and deploy your app.

containers:
  - name: todo-app
    dockerfile: Dockerfile
    context: .

deploy:
  - name: web
    container: todo-app
    port: 8080
    health_check:
      path: /health
      startup_timeout: 300   # Spring Boot needs headroom to boot (default 120)

Unknown keys are silently ignored

appmecca.yaml discards any key it does not recognise — no error, no warning. Misspell health_check as healthcheck and it simply vanishes; you find out when the deploy behaves differently from what you wrote. Copy key names exactly.

JVM memory

You do not need to set resources.memory here. AppMecca inspects the built image, recognises a JVM runtime, and applies a 512 MB default instead of the platform's 128 MB. If you do set it explicitly, keep it at 512m or above — and note the unit suffix is mandatory (a bare 512 means 512 bytes).

Set a default environment

Avoid typing -e dev on every command:

export APPMECCA_ENV=dev

Or store it persistently in your CLI config:

mecca configure -e dev

The app name is a positional argument

Most mecca app … commands take the app name as a positional argument — mecca app deploy todo-app, mecca app show todo-app. There is no environment variable that fills it in for you, so the examples below always name the app explicitly.

Authenticate with your Git provider

AppMecca needs permission to clone your repository during builds.

appmecca git-auth login --provider github

This opens a browser for the OAuth Device Authorization flow. Once approved, the token is stored locally in ~/.appmecca/tokens/.

Register the application

mecca register git@github.com:yourorg/todo-app.git

This creates the app's entry in the platform registry and runs a repository pre-flight check — it clones the repo, confirms appmecca.yaml parses, and confirms the Dockerfiles it names exist. It does not queue a build. Until the pre-flight passes, builds and deploys are refused; re-run it with mecca app recheck todo-app after fixing whatever it reports.

Verify the app is registered:

mecca app list

Trigger a build

mecca build trigger -g git@github.com:yourorg/todo-app.git

The command queues the build and returns immediately, printing an action ID; a deploy is queued automatically once the build succeeds. Follow it with:

mecca build status <build-id>
mecca build logs <build-id>
mecca build list

To build without deploying, pass --no-deploy:

mecca build trigger -g git@github.com:yourorg/todo-app.git --no-deploy

Deploy

mecca app deploy todo-app

AppMecca queues the deployment. An AppMecca host picks it up, pulls the container image from the platform's private image registry, and starts it.

Monitor progress. mecca queue status takes the action ID the deploy printed (an 8-character prefix is enough):

mecca queue status <action-id>
mecca queue status <action-id> --json
mecca queue list -a todo-app        # everything in flight for this app

Once the status shows completed, view the app and its live URL:

mecca app show todo-app

The URL always carries the service name: https://todo-app-web-yourgroup.dev.yourdomain.com. There is no bare todo-app.dev… hostname, even with a single service.

Health check timing

Spring Boot apps can take 10-30 seconds to start. The new container must pass its health check within startup_timeout (default 120 s, range 30-600) before AppMecca switches traffic to it — which is why the manifest above raises it to 300. Until then the previous version keeps serving; a deploy that never becomes healthy is marked failed and changes nothing.

Verify it works

Open the URL from mecca app show in your browser. You should see:

{"message": "Hello from AppMecca!"}

And the health endpoint at /health:

{"status": "healthy"}

Clean up

Undeploy the application. This stops the containers and removes its routing, but keeps the registry entry, build history and database:

mecca app undeploy todo-app

Add --force to skip the confirmation prompt:

mecca app undeploy todo-app --force

To permanently purge the app — it backs up and then drops the database, and removes the built images, build history, stored secrets and every platform resource the app owns:

mecca app unregister todo-app

Command reference

Command Purpose
appmecca git-auth login Authenticate with Git provider
mecca register <url> Register an app + run the repository pre-flight
mecca app recheck <app> Re-run the pre-flight after fixing the repo
mecca build trigger -g <url> Build container images (auto-deploys unless --no-deploy)
mecca build status <id> Check build progress
mecca build logs <id> Read build logs
mecca build list List recent builds
mecca app deploy <app> Deploy latest build
mecca queue list -a <app> List in-flight actions for an app
mecca queue status <action-id> Check one action
mecca app show <app> Per-service status and URLs
mecca app undeploy <app> [--force] Stop a running deployment
mecca app unregister <app> Permanent purge (same as app delete)

What's next

In Part 2: Adding a Database, you will add PostgreSQL with Spring Data JPA and Flyway migrations, turning this hello-world into a real todo API.