Run the booking business locally
Get your package running on your computer, with Docker.
For the Full Stack package
Before you start: install and open Docker Desktop, or Docker Engine with Compose.
View requirementsDownload your template
Open My templates and download the ZIP for your package.
Expected result: A file named like
hollina-vacation-rental-full-stack-….zipis in your downloads.Unzip and open the folder
Open a terminal where the ZIP is, extract it and move into the
hollina-vacation-rental-full-stackfolder. On Windows, you can extract it in File Explorer instead, then open a terminal in the folder.Terminalunzip -q hollina-vacation-rental-full-stack-*.zip cd hollina-vacation-rental-full-stackExpected result: The folder lists
Having trouble?admin-dashboard,back-end,storefrontanddocker-compose.yml, besideREADME.md,QUICKSTART.mdandLICENSE.md.Start the apps
Build and start the API, the stays website and the booking dashboard. Nothing has to be configured first. The first start builds three images and fills the database with the demo company, which takes a few minutes; later starts take seconds.
Terminalinhollina-vacation-rental-full-stackdocker compose up --buildA port is already in use?
If the start stops with
A port is already in useports are not available,address already in useorport is already allocated, another program uses 3030, 3031 or 8000. Either stop it, or create a file named.envin thehollina-vacation-rental-full-stackfolder, besidedocker-compose.yml, with the port you need, such asADMIN_PORT=3041(SITE_PORTfor the website,API_PORTfor the API). Rundocker compose up --buildagain and open the app on its new port.Expected result: The three services keep running and the log stops scrolling. Leave this terminal open.
Having trouble?Open the stays website
Open localhost:3030Local. English is at
/enand Arabic at/ar. The website has no accounts: saved stays are kept in the visitor's browser, and a guest finds a booking again with its reference and the email it was made with. Without payment keys the shipped simulator takes every card and PayPal booking, so the whole checkout works; a card number ending in0is declined, to show the failure path.Expected result: The website opens on its home page with the demo stays, their photographs and the destinations.
Having trouble?Sign in to the booking dashboard
Open localhost:3031Local. Sign in with
admin@hollina.exampleand the passwordAdmin@123. For the manager, typemanager@hollina.examplewithManager@123. Change both passwords before the stack is reachable from the internet.Expected result: The dashboard opens on its overview, with this month's occupancy and revenue, today's arrivals and departures, and the latest bookings.
Having trouble?
Take a tour
What the demo company looks like once everything runs.
| Account | Password | |
|---|---|---|
| Super Admin: every page and permission | admin@hollina.example | Admin@123 |
| Manager: the overview, calendar, bookings, stays, inquiries, reviews and the AI assistant; no admins, roles or company settings | manager@hollina.example | Manager@123 |
The seed adds 14 stays (12 published, 2 drafts) with 42 photographs, 6 destinations, 18 amenities, 60 bookings across the year, 8 blocked ranges, 12 guest questions, 24 reviews and 6 home page questions, so every screen opens full. Dates are stored as offsets from the day of the seed, so a fresh database always has arrivals today. These are local demo accounts only.
Stop and start again
Press Ctrl+C in the terminal to stop the apps, or run this from the hollina-vacation-rental-full-stack folder. Your data, the database and the uploads, is kept in the hollina-data volume.
hollina-vacation-rental-full-stackdocker compose downStart again with the same command as step 3. Without --build it reuses the images you already built.
hollina-vacation-rental-full-stackdocker compose upKeep your data
docker compose down -v also deletes the data volume. The next start seeds a fresh copy of the demo company, and everything you created is gone.
Run the stays website
This package is the stays website on its own. It reads everything from the Hollina API, so start the API first. Unless you build it with another address, the website expects the API at http://localhost:8000. The API is a separate package and is not in this download.
Unzip and open the folder
Terminalunzip -q hollina-website-*.zip cd hollina-websiteExpected result: The folder has a
Having trouble?Dockerfileand apackage.json.Build the image
The
NEXT_PUBLIC_*values are compiled into the JavaScript the browser loads, so they are build arguments. Without any, the website uses the API athttp://localhost:8000/apiand calls itselfhttp://localhost:3030. For an API somewhere else, pass its address.Terminalinhollina-websitedocker build -t hollina-website .With your own API and domain:
Terminalinhollina-websitedocker build -t hollina-website --build-arg NEXT_PUBLIC_API_BASE_URL=https://api.your-company.com/api --build-arg NEXT_PUBLIC_SITE_URL=https://www.your-company.com --build-arg NEXT_PUBLIC_MEDIA_HOSTNAME=media.your-company.com .Having trouble?Start it
Inside the container
localhostis the container itself, soAPI_INTERNAL_URLtells the website's own server where to reach the API on your computer, for the page titles, the first render of the home and stay pages, and the sitemap.--add-hostmakeshost.docker.internalwork on Linux; Docker Desktop already has it. If port3030is taken, change the number on the left of-p, for example-p 3041:3030, open that port instead, and addhttp://localhost:3041to the API'sCORS_ORIGIN.Terminalinhollina-websitedocker run -p 3030:3030 -e API_INTERNAL_URL=http://host.docker.internal:8000/api --add-host=host.docker.internal:host-gateway hollina-websiteExpected result: localhost:3030Local opens the website with the stays from your API. English is at
Having trouble?/en, Arabic at/ar.
Run the booking dashboard
This package is the booking dashboard on its own. Every screen reads the Hollina API, so start the API first. Unless you build it with another address, the dashboard expects the API at http://localhost:8000. The API is a separate package and is not in this download.
Unzip and open the folder
Terminalunzip -q hollina-booking-dashboard-*.zip cd hollina-booking-dashboardExpected result: The folder has a
Having trouble?Dockerfileand apackage.json.Build the image
Without build arguments the dashboard uses the API at
http://localhost:8000/api. For an API somewhere else, pass its address, its address without/apifor the live notifications, and the website's address for the "Back to website" link and the stay editor's "View stay".Terminalinhollina-booking-dashboarddocker build -t hollina-dashboard .With your own API:
Terminalinhollina-booking-dashboarddocker build -t hollina-dashboard --build-arg NEXT_PUBLIC_API_BASE_URL=https://api.your-domain.com/api --build-arg NEXT_PUBLIC_WEBSOCKET_BASE_URL=https://api.your-domain.com --build-arg NEXT_PUBLIC_MEDIA_HOSTNAME=api.your-domain.com --build-arg NEXT_PUBLIC_SITE_URL=https://your-domain.com .Having trouble?Start it and sign in
If port
3031is taken, change the number on the left of-p, for example-p 3041:3031, open that port instead, and addhttp://localhost:3041to the API'sCORS_ORIGIN(and set itsFRONTEND_URLto it, the address the live notifications connect from).Terminalinhollina-booking-dashboarddocker run -p 3031:3031 hollina-dashboardExpected result: localhost:3031Local opens the sign-in form. Sign in with
Having trouble?admin@hollina.exampleand the passwordAdmin@123, which a seeded API accepts.
Run the API
This package is the NestJS API on its own, on a SQLite file kept in a Docker volume with the uploads. The stays website and the booking dashboard are separate packages and are not in this download.
Unzip and open the folder
Terminalunzip -q hollina-backend-*.zip cd hollina-backendExpected result: The folder has a
Having trouble?Dockerfile, adocker-entrypoint.shand apackage.json.Start it with the demo company
A new volume gets empty tables and no accounts unless you ask for the demo company, so keep
-e SEED_DEMO_DATA=truefor a first start. Thehollina-api-datavolume keeps the database and the uploads between runs. If port8000is taken, change the number on the left of-p, for example-p 8010:8000, and add-e PUBLIC_MEDIA_URL=http://localhost:8010/mediaso the photograph addresses use it too. Your frontends must then point athttp://localhost:8010/api.Terminalinhollina-backenddocker run -p 8000:8000 -v hollina-api-data:/data -e SEED_DEMO_DATA=true hollina-apiExpected result: localhost:8000/
Having trouble?api/ healthLocal answers with "status":"ok"and"database":"up".
The container accepts the website on http://localhost:3030 and the dashboard on http://localhost:3031. On other addresses, set CORS_ORIGIN (both, comma separated), FRONTEND_URL (the dashboard) and SITE_URL (the website, where a payment processor sends the guest back) with -e. Without payment keys the shipped simulator settles every card and PayPal booking.
To give the container your own keys (Stripe, PayPal, R2, AI, MCP), create .env from .env.example with cp .env.example .env, fill it in, and add --env-file .env -e NODE_ENV=production to docker run:
hollina-backenddocker run -p 8000:8000 -v hollina-api-data:/data -e SEED_DEMO_DATA=true --env-file .env -e NODE_ENV=production hollina-apiA value given with -e wins over the same name in the file, so the container runs in production whatever .env says, and it moves the file's relative paths (SQLITE_DATABASE, MEDIA_UPLOAD_DIR) into the volume. Without a JWT_SECRET of your own, or with the example one, the container generates a secret and keeps it in the volume, so sign-ins survive a restart.