Express + Svelte Fullstack¶
Full-stack todo application with a Node.js/Express API and SvelteKit frontend with SPA runtime config injection.
Overview¶
| Tech Stack | Node.js / Express (backend) + SvelteKit (frontend) |
| Services | 2 (backend + frontend) |
| Database | PostgreSQL |
| Pattern | Multi-container, SPA config injection |
The appmecca.yaml¶
containers:
- name: backend
dockerfile: backend/Dockerfile
context: backend/
- name: frontend
dockerfile: frontend/Dockerfile
context: frontend/
args:
VITE_API_URL: placeholder
deploy:
- name: backend
container: backend
port: 3000
path: /api
health_check:
path: /api/health
- name: frontend
container: frontend
type: spa
command: 'nginx -g "daemon off;"' # serves the built bundle from a container
spa_root: /usr/share/nginx/html
port: 80
health_check:
path: /health
environment:
PUBLIC_API_URL: "${service:backend}"
database:
enabled: true
Key Concepts¶
SPA Runtime Config (type: spa)¶
The type: spa and spa_root fields enable runtime configuration injection for static frontends. Instead of baking environment variables at build time, AppMecca writes a __appmecca_config.js file into the spa_root directory at deploy time. The SvelteKit code reads from window.__APPMECCA_CONFIG__ at runtime.
This means the same Docker image can be deployed to different environments with different API URLs -- no rebuild required.
SvelteKit Static Adapter¶
The frontend uses @sveltejs/adapter-static to compile SvelteKit into a pure static SPA. The built files are served by nginx with SPA routing (try_files $uri /index.html).
You may not need the nginx container at all
This app keeps the frontend in a container so it can use runtime config injection. If you
are happy to bake the API URL in at build time, drop the container and make the service
type: static with a static_site: block instead — AppMecca then builds the bundle and
serves it from the edge cache, with no Dockerfile, no nginx config, no health endpoint and
no host memory. See Flask + Vue Fullstack for that shape.
type: spa must be unambiguous
A type: spa service needs either command: (container form, as here) or a
static_site: block (edge-served form). With neither, the config is rejected — the platform
cannot tell which you intended.
Step-by-Step Deployment¶
1. Register the app¶
2. Build the containers¶
3. Deploy¶
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:
curl https://express-svelte-fullstack-backend.dev.appmecca.net/api/health
open https://express-svelte-fullstack-frontend.dev.appmecca.net
What's Next¶
- React Frontend -- Simpler SPA without backend
- Spring + React Fullstack -- Java version with build args
- Inter-Service Communication -- How service URL templates work