Industrial ecommerce MVP split into:
frontendV1/- primary storefront UIFrontend/- older standalone storefront UIBackend/- Django Oscar APIs, admin, catalog, search, recommendations
cd Backend
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe manage.py migrate
.\.venv\Scripts\python.exe manage.py runserverBackend runs on http://127.0.0.1:8000
cd Frontend
npm install
npm run devFrontend runs on http://127.0.0.1:5173
Primary storefront V1:
cd frontendV1
npm install
npm run devFrontend V1 runs on http://127.0.0.1:5174
GET /api/v1/catalog/categories/GET /api/v1/catalog/products/GET /api/v1/catalog/products/<id>/POST /api/v1/quotes/GET /api/v1/search/POST /api/v1/search/image/GET /api/v1/recommendations/
- CORS is enabled in backend settings for:
http://127.0.0.1:5173http://localhost:5173
- Frontend API host is configured by
Frontend/.envusing:VITE_API_BASE_URL=http://127.0.0.1:8000
The root docker-compose.yml runs the full stack:
- Django backend with Gunicorn
- Celery worker and Celery beat
- PostgreSQL
- Redis
- OpenSearch
- Vite storefront served by Nginx
- Nuxt dashboard generated as static files and served by Nginx
- Caddy reverse proxy with automatic HTTPS
cp .env.production.example .env.productionEdit .env.production and set real values for:
POSTGRES_PASSWORDDJANGO_SECRET_KEYSTOREFRONT_DOMAINDASHBOARD_DOMAINAPI_DOMAINDJANGO_ALLOWED_HOSTSCORS_ALLOWED_ORIGINSCSRF_TRUSTED_ORIGINS- payment, email, and ERPNext credentials as needed
For local Docker testing on Windows, use:
Copy-Item .env.docker.local.example .env.docker.local
docker compose --env-file .env.docker.local configThe local Docker env uses:
http://localhost:5174 -> storefront direct container port
http://localhost:3000 -> dashboard direct container port
http://localhost:8000 -> backend API direct container port
The Caddy proxy also serves http://localhost for the storefront. The direct ports are simpler on Windows because they do not require editing the hosts file for api.localhost and dashboard.localhost.
Recommended domain layout:
vortexus.example.com -> storefront
admin.vortexus.example.com -> dashboard
api.vortexus.example.com -> Django API/admin/static/media
docker compose --env-file .env.production build
docker compose --env-file .env.production up -d postgres redis opensearchdocker compose --env-file .env.production run --rm backend python manage.py migrate
docker compose --env-file .env.production run --rm backend python manage.py collectstatic --noinput
docker compose --env-file .env.production run --rm backend python manage.py bootstrap_search_indices
docker compose --env-file .env.production run --rm backend python manage.py createsuperuserOptional seed/index commands:
docker compose --env-file .env.production run --rm backend python manage.py bootstrap_demo_data
docker compose --env-file .env.production run --rm backend python manage.py reindex_search_data
docker compose --env-file .env.production run --rm backend python manage.py backfill_image_embeddings --syncdocker compose --env-file .env.production up -dUseful checks:
docker compose ps
docker compose logs -f backend
docker compose logs -f celery-workerBackend health endpoints:
https://api.vortexus.example.com/api/v1/health/live/
https://api.vortexus.example.com/api/v1/health/ready/
- Point the three DNS records to the VPS before starting Caddy for real HTTPS.
- Open ports
80and443on the VPS firewall. - OpenSearch commonly needs
vm.max_map_count=262144on Linux hosts. - OpenSearch and CLIP/PyTorch are memory-hungry. A 4 GB RAM VPS is the practical minimum; 8 GB is safer.
- Keep
.env.productionout of git. It is intentionally ignored.
For a stable public preview URL from a local Docker stack, use the optional cloudflared compose profile. Cloudflare terminates public HTTPS, and the local Caddy container routes plain HTTP traffic inside Docker.
- In Cloudflare Zero Trust, create a tunnel and add three public hostnames:
vortexus.example.com->http://caddy:80admin.vortexus.example.com->http://caddy:80api.vortexus.example.com->http://caddy:80
- Copy
.env.cloudflare.exampleto.env.cloudflare. - Copy
.env.cloudflare.app.exampleto.env.cloudflare.app. - Set the real
STOREFRONT_DOMAIN,DASHBOARD_DOMAIN,API_DOMAIN,VITE_API_BASE_URL, andNUXT_PUBLIC_API_BASEin.env.cloudflare. - Set the matching
DJANGO_ALLOWED_HOSTS,CORS_ALLOWED_ORIGINS,CSRF_TRUSTED_ORIGINS, payment callbacks, and app secrets in.env.cloudflare.app. - Paste the connector token into
CLOUDFLARE_TUNNEL_TOKENin.env.cloudflare. - Start the stack:
docker compose -f docker-compose.yml -f docker-compose.cloudflare.yml --env-file .env.cloudflare --profile tunnel up -d --buildThe tunnel is outbound-only, so your local IP can change without changing the public URLs.
If you run Caddy without the Cloudflare override file and ports 80 or 443 are already in use, set alternate host ports in your env file:
CADDY_HTTP_PORT=8080
CADDY_HTTPS_PORT=8443