Skip to the article
Aniq-UI

TicketoryRun Ticketory locally

Run Ticketory 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 requirements
  1. Download your template

    Open My templates and download the ZIP for your package.

    Expected result: A file named like ticketory-full-stack-….zip is in your downloads.

  2. Unzip and open the folder

    Open a terminal where the ZIP is, extract it and move into the ticketory-full-stack folder. On Windows, you can extract it in File Explorer instead, then open a terminal in the folder.

    Terminal
    unzip -q ticketory-full-stack-*.zip
    cd ticketory-full-stack
    ls

    Expected result: The folder lists admin-dashboard, back-end, storefront and docker-compose.yml, beside README.md, QUICKSTART.md and LICENSE.md.

    Having trouble?
  3. Start the apps

    Build and start the API, the public website and the organiser dashboard. Nothing has to be configured first. The first start builds three images and fills the database with the sample organisers and their events, which takes a few minutes; later starts take seconds.

    Terminalin ticketory-full-stack
    docker compose up --build

    A port is already in use?

    If the start stops with ports are not available, address already in use or port is already allocated, another program uses 3030, 3031 or 8000. Either stop it, or create a file named .env in the ticketory-full-stack folder, beside docker-compose.yml, with the port you need, such as ADMIN_PORT=3041 (SITE_PORT for the website, API_PORT for the API). Run docker compose up --build again and open the app on its new port.

    A port is already in use

    Expected result: The three services keep running and the log stops scrolling. Leave this terminal open.

    Having trouble?
  4. Open the public website

    Open localhost:3030Local. English is at /en and Arabic at /ar. Anyone can buy without an account; to see an attendee's tickets, orders and saved events, sign in with attendee@example.test and the password DemoOnly!2026.

    Expected result: The website opens on its home page with the sample events and their pictures.

    Having trouble?
  5. Sign in to the organiser dashboard

    Open localhost:3031Local. Sign in with owner@example.test and the password DemoOnly!2026. Every seeded account uses that password; change them before the stack is reachable from the internet.

    Expected result: The dashboard opens on its overview, with the ticket sales, the live door and the next events.

    Having trouble?

Take a tour

What the sample organisers look like once everything runs.

AccountEmailWhere
Owner: everything, including refunds, the team, roles and settingsowner@example.testDashboard
Manager: events, venues, check-in, reports, inquiries, the studio and the assistant; orders read onlymanager@example.testDashboard
Finance: the overview, orders, refunds, ticket reissue and void, and reportsfinance@example.testDashboard
Check-in: the door only, for the sessions assigned to itcheckin@example.testDashboard
Attendee Taylor Morgan: eight orders and four saved eventsattendee@example.testWebsite

Every account signs in with the password DemoOnly!2026. These are local demo accounts only.

The seed adds four organisers, each a workspace of its own that the Owner switches between from the dashboard's top bar: Northline Events, Kiln & Co., Mill Street Talks and Meadow Days. Between them they have 9 venues, 36 events (22 on the website, 3 of them on now, 9 already over, 1 called off and 4 drafts), 1,145 orders and 14 staff accounts, so every screen opens full.

Stop and start again

Press Ctrl+C in the terminal to stop the apps, or run this from the ticketory-full-stack folder. Your data, the database, the uploads and the CSV exports, is kept in the ticketory-data volume.

Terminalin ticketory-full-stack
docker compose down

Start again with the same command as step 3. Without --build it reuses the images you already built.

Terminalin ticketory-full-stack
docker compose up

Keep your data

docker compose down -v also deletes the data volume. The next start seeds a fresh copy of the sample organisers, and everything you created is gone.

Run the public website

This package is the public website on its own. It reads everything from the Ticketory 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.

  1. Download your template

    Open My templates and download the Ticketing Website ZIP.

  2. Unzip and open the folder

    Terminal
    unzip -q ticketory-website-*.zip
    cd ticketory-website
    ls

    Expected result: The folder has a Dockerfile and a package.json.

    Having trouble?
  3. 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 at http://localhost:8000/api, calls itself http://localhost:3030 and sends organisers to the dashboard at http://localhost:3031. For an API somewhere else, pass its address.

    Terminalin ticketory-website
    docker build -t ticketory-website .

    With your own API and domains:

    Terminalin ticketory-website
    docker build -t ticketory-website --build-arg NEXT_PUBLIC_API_BASE_URL=https://api.your-domain.com/api --build-arg NEXT_PUBLIC_SITE_URL=https://www.your-domain.com --build-arg NEXT_PUBLIC_DASHBOARD_URL=https://dashboard.your-domain.com .
    Having trouble?
  4. Start it

    Inside the container localhost is the container itself, so API_INTERNAL_URL tells the website's own server where to reach the API on your computer, for event page titles, the first render of the home, event, venue and organiser pages, and the sitemap. --add-host makes host.docker.internal work on Linux; Docker Desktop already has it. If port 3030 is taken, change the number on the left of -p, for example -p 3040:3030, open that port instead, add http://localhost:3040 to the API's CORS_ORIGIN and set it as the API's STOREFRONT_URL.

    Terminalin ticketory-website
    docker run -p 3030:3030 -e API_INTERNAL_URL=http://host.docker.internal:8000/api --add-host=host.docker.internal:host-gateway ticketory-website

    Expected result: localhost:3030Local opens the website with the events from your API. English is at /en, Arabic at /ar.

    Having trouble?

To let the API refresh the event, venue and organiser pages the moment they change, add -e REVALIDATE_SECRET= followed by the same value as REVALIDATE_SECRET in the API's .env. Without it those pages refresh on their own within an hour.

Run the organiser dashboard

This package is the organiser dashboard on its own. Every screen reads the Ticketory 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.

  1. Download your template

    Open My templates and download the Organiser Dashboard ZIP.

  2. Unzip and open the folder

    Terminal
    unzip -q ticketory-dashboard-*.zip
    cd ticketory-dashboard
    ls

    Expected result: The folder has a Dockerfile and a package.json.

    Having trouble?
  3. 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 /api for the live notifications, the host serving its pictures, and the website's address for the "View website" link.

    Terminalin ticketory-dashboard
    docker build -t ticketory-dashboard .

    With your own API:

    Terminalin ticketory-dashboard
    docker build -t ticketory-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?
  4. Start it and sign in

    If port 3031 is taken, change the number on the left of -p, for example -p 3041:3031, open that port instead, add http://localhost:3041 to the API's CORS_ORIGIN and set its FRONTEND_URL to it (the address the live notifications connect from), then restart the API.

    Terminalin ticketory-dashboard
    docker run -p 3031:3031 ticketory-dashboard

    Expected result: localhost:3031Local opens the sign-in form. Sign in with owner@example.test and the password DemoOnly!2026, which a seeded API accepts.

    Having trouble?

Run the API

This package is the NestJS API on its own, on a SQLite file kept in a Docker volume with the uploads and the CSV exports. The public website and the organiser dashboard are separate packages and are not in this download.

  1. Download your template

    Open My templates and download the Backend API ZIP.

  2. Unzip and open the folder

    Terminal
    unzip -q ticketory-backend-*.zip
    cd ticketory-backend
    ls

    Expected result: The folder has a Dockerfile, a docker-entrypoint.sh and a package.json.

    Having trouble?
  3. Build the image

    Terminalin ticketory-backend
    docker build -t ticketory-api .
    Having trouble?
  4. Start it with the sample data

    A new volume gets empty tables and no accounts unless you ask for the sample organisers, so keep -e SEED_DEMO_DATA=true for a first start. The ticketory-api-data volume keeps the database, the uploads and the CSV exports between runs. If port 8000 is taken, change the number on the left of -p, for example -p 8010:8000, and add -e PUBLIC_MEDIA_URL=http://localhost:8010/media and -e PUBLIC_API_URL=http://localhost:8010 so the picture addresses and the ticket download links use it too. Your frontends must then point at http://localhost:8010/api.

    Terminalin ticketory-backend
    docker run -p 8000:8000 -v ticketory-api-data:/data -e SEED_DEMO_DATA=true ticketory-api

    Expected result: localhost:8000/api/healthLocal answers with "status":"ok" and "database":"up".

    Having trouble?

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 STOREFRONT_URL (the website) with -e.

To give the container your own keys (payments, mail, AI, R2, 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:

Terminalin ticketory-backend
docker run -p 8000:8000 -v ticketory-api-data:/data -e SEED_DEMO_DATA=true --env-file .env -e NODE_ENV=production ticketory-api

A 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, EXPORT_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.

Next

Stuck on a step?

Find a fix before you start over.

Troubleshooting

Cookie Preferences

We use cookies to enhance your browsing experience, analyze site traffic, and personalize content. By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising.