Frontend
Setup & Configuration
The frontend is a Vue.js / Vuetify 3 application built with Vite. The build process is fully managed by Ansible — the source code is cloned on the staging server, built into a Docker image, and that image is transferred to production.
The Docker image bundles an nginx web server that serves the compiled static files directly. There is no mounted dist folder on the host — everything is self-contained in the image.
nginx configuration
The nginx.conf is baked into the Docker image at build time. It adds no-cache headers to HTML and service worker files to ensure immediate refresh on new deployments, while static assets (JS/CSS bundles) are cached aggressively with a 1-year expiry:
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, must-revalidate" always;
}
location = /sw.js {
add_header Cache-Control "no-cache";
try_files $uri =404;
}
location /assets/ {
expires 1y;
}Environment Variables
WARNING
In order to be picked up properly by the Vite build process, variable names must start with VITE_
Frontend environment variables are injected by Ansible at build time and compiled into the JavaScript bundle. They are not stored on the server. The values come from Ansible Vault (group_vars/klhhh/vault.yml) and vars.yml.
INFO
Because VITE_ variables are baked into the JS bundle at build time, a new Docker image must be built and deployed for any variable change to take effect. Runtime injection is not possible for these variables.
| Variable | Purpose |
|---|---|
VITE_BACKEND_PATH | URI of the backend (Strapi) API |
VITE_GOOGLE_MAPS_API_KEY | Google Maps API key for run site maps |
VITE_PIWIGO_PATH | Path to the Piwigo image gallery |
VITE_PIWIGO_USERNAME | Piwigo API username |
VITE_PIWIGO_PASSWORD | Piwigo API password |
VITE_WEEKS_TO_SHOW | Number of run cards shown in the run gallery |
VITE_CONTACT_PHONE | WhatsApp contact number on the "Run with us" page |
VITE_CONTACT_EMAIL | Contact email address |
VITE_API_TOKEN | Authentication token for the Strapi API |
VITE_ENV | Environment type (staging / production), steers internal functionality |
VITE_FEATURE_EXPENSES | Feature flag for the expenses module |
VITE_TURNSTILE_SITE_KEY | Cloudflare Turnstile key |
VITE_TURNSTILE_VERIFICATION_URL | Relative path to the Cloudflare Worker for Turnstile token verification |
Sensitive values (VITE_GOOGLE_MAPS_API_KEY, VITE_PIWIGO_PASSWORD, VITE_API_TOKEN) are stored in Ansible Vault. Non-sensitive values are in group_vars/klhhh/vars.yml, with staging overrides in group_vars/staging/vars.yml.
Deployment
Deployment is fully managed by Ansible. See Deployment for the full workflow.
In summary, deploy.yml handles:
- Cloning/updating the frontend repository on staging
- Injecting
VITE_environment variables into a.envfile - Building the Docker image (runs
yarn install+vite buildinside the build stage) - Restarting the container on staging (if
target=staging) - Transferring the image to production (if
target=prod) - On prod, the container is restarted manually after the transfer
# Deploy to staging
ansible-playbook playbooks/deploy.yml -e target=staging --tags frontend
# Deploy to production
ansible-playbook playbooks/deploy.yml -e target=prod --tags frontend
# then restart manually on prod:
# docker compose -f ~/docker/frontend/docker-compose.yml up -dDANGER
It is strongly recommended purging the Cloudflare cache after every deployment to avoid stale content being served to users.
INFO
Besides the GitHub repository, no further backup is required for the frontend component — all build artefacts can be recreated from source.
