Skip to content

Django + React Fullstack

Full-stack todo application with a Django/DRF API and React/Vite frontend, demonstrating static file collection and build targets.

Overview

Tech Stack Python / Django / DRF (backend) + React / Vite (frontend)
Services 2 (backend + frontend)
Database PostgreSQL
Pattern Multi-container, static collection, build targets

The appmecca.yaml

containers:
  - name: backend
    dockerfile: backend/Dockerfile
    context: backend/
    target: production

deploy:
  - name: backend
    container: backend
    port: 8000
    path: /api
    health_check:
      path: /api/health

  - name: frontend
    primary: true
    type: static
    static_site:
      build_command: "cd frontend && npm install --no-audit --no-fund && npm run build"
      output_dir: frontend/dist
      spa_fallback: true
      index_document: index.html
    environment:
      VITE_API_URL: "${service:backend}"

database:
  enabled: true

Note there is only one containers[] entry. The frontend service is type: static, so it never becomes a Docker image — AppMecca runs its build_command and publishes the bundle to the edge cache.

Static assets are collected at build time — see the collectstatic step in this app's Dockerfile. The top-level static: block was removed in FEATURES #347 (it was read by nothing) and is now refused.

Key Concepts

Build Targets (containers[].target)

The target: production field tells AppMecca to build only up to the named stage in the multi-stage Dockerfile. This is useful when you have multiple stages (e.g., base, test, production) and want to build a specific one.

Static File Collection (static)

The static section configures Django's collectstatic to run during deployment, gathering static files from all installed apps into STATIC_ROOT for serving.

static: is top-level; static_site: is per-service

static: sits at the root of appmecca.yaml and applies to the app as a whole — it collects Django's assets alongside the containerised backend. Putting it inside a deploy[] entry silently does nothing, because AppMecca ignores unrecognised keys without warning.

static_site: is a different feature: it goes on the service and replaces the container outright. Here frontend uses it, backend does not.

spa_fallback: true makes error_document irrelevant

With spa_fallback: true, any path that is not a real file returns index.html with status 200, so error_document is never consulted. Set error_document only when spa_fallback is false.

Django REST Framework

The backend uses DRF's ModelViewSet for CRUD operations, providing a standard REST API with minimal code.

Step-by-Step Deployment

1. Register the app

mecca register git@gitlab.com:appmecca-sample-apps/django-react-fullstack.git \
  -e dev

2. Build the containers

mecca build trigger \
  -e dev \
  -g git@gitlab.com:appmecca-sample-apps/django-react-fullstack.git

3. Deploy

mecca app deploy -e dev django-react-fullstack

4. Verify

mecca queue status takes the action ID printed by the deploy. To look up the app and its exact URLs for your group:

mecca app show django-react-fullstack -e dev
curl https://django-react-fullstack-backend.dev.appmecca.net/api/health
open https://django-react-fullstack-frontend.dev.appmecca.net

What's Next