Local Development
The following description of the development setup is mainly applicable for Mac / Linux platforms. Should you use Windows for development, we highly recommend using WSL / WSL2 (Windows Subsystem for Linux) to be able to run the same commands.
- Clone the
https://github.com/uzh-bf/klicker-uzh
repository and checkout the development branch (currentlyv3
). - Install Doppler (https://docs.doppler.com/docs/install-cli) and create a new project/dev environment.
- Once the Doppler environment has been set up, use
doppler login
to connect your local environment.
- Once the Doppler environment has been set up, use
- Preferably: Install Volta (https://volta.sh/) for automated Node.js and NPM/PNPM package management
- Linux/Mac/WSL: When using Volta, add
VOLTA_FEATURE_PNPM=1
to your.bashrc
or.zshrc
- Alternatively: Manually install Node.js 20 (https://nodejs.org/en/download) and PNPM 8 (https://pnpm.io/installation)
- Linux/Mac/WSL: When using Volta, add
- Install either Docker (https://docs.docker.com/get-docker/) or Rancher Desktop (https://github.com/rancher-sandbox/rancher-desktop)
- Docker is preferable if licensing allows (e.g., for student projects)
- Rancher Desktop works well as an alternative to Docker (on MacOS:
brew install --cask rancher
,brew install docker docker-compose docker-credential-helper
). If prompted, disable Kubernetes (not used in local development) and enable docker. - When using Rancher on a Windows machine, install it directly on Windows and expose it through the corresponding setting to your WSL.
- Podman also works, but is more complicated in terms of setup (port forwarding)
- Install PNPM for package management (https://pnpm.io/installation)
- Install Bun (https://bun.sh/docs/installation)
- Install Azure Function Tools (https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local)
- Install Azurite in, e.g., VS Code (https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio)
- Create an Azure Service Bus Queue (https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-queues-topics-subscriptions)
The KlickerUZH runs on domains in local development (using localhost or IPs will cause many random issues with, e.g., Edu-ID log-in or cookie authentication). These domains need to be added to /etc/hosts
such that they refer to the local machine and are not resolved through the internet.
- Linux/Mac: Add local domain entries to
/etc/hosts
127.0.0.1 api.klicker.com
127.0.0.1 pwa.klicker.com
127.0.0.1 manage.klicker.com
127.0.0.1 control.klicker.com
127.0.0.1 auth.klicker.com
127.0.0.1 func-responses.klicker.com
127.0.0.1 func-response-processor.klicker.com
Because of the intricacies of this setup step (it can, e.g., break with OS upgrades), we recommend using Docker and/or Rancher Desktop, if possible.
To enable all the KlickerUZH services to be reachable in parallel, we access them through a Traefik proxy running in a container (see docker-compose.yml
). The proxy expects traffic on port 80 (Docker) or 8088 (Podman) on the localhost. The situation with Podman is not optimal, as we want to use manage.klicker.com
to access a site, not manage.klicker.com:8088
. Therefore, port forwarding is being set-up from port 80 to port 8088 on localhost.
- Mac: Create a file at
/etc/pf.anchors/com.klicker.pf
# Forward port 80 to 8088 for local domains
rdr pass on lo0 inet proto tcp from any to self port 80 -> 127.0.0.1 port 8088
rdr pass on en0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8088
rdr pass on en1 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8088
- Mac: Add the following lines to
/etc/pf.conf
rdr-anchor "port80"
load anchor "port80" from "/etc/pf.anchors/com.klicker"
- Mac: Run
sudo pfctl -ef /etc/pf.conf
The steps for Linux/Windows are WIP, as there are currently no developments being done on these operating systems.
- In
apps/backend-docker
: Copy.env.template
to.env
- In
apps/func-incoming-responses
andapps/func-response-processor
: Copylocal.settings.template
tolocal.settings.json
and fill in any missing values - Add required secrets as listed below to the Doppler environment (Add Secret > Import Secrets)
API_DOMAIN="api.klicker.com"
APP_SECRET="abcd"
AZUREWEBJOBSFEATUREFLAGS="EnableWorkerIndexing"
AZUREWEBJOBSSTORAGE="UseDevelopmentStorage=true"
COOKIE_DOMAIN=".klicker.com"
CRON_TOKEN="abcd"
DATABASE_URL="postgres://klicker:klicker@localhost:5432/klicker"
FUNCTIONS_EXTENSION_VERSION="~4"
FUNCTIONS_WORKER_PROCESS_COUNT="10"
FUNCTIONS_WORKER_RUNTIME="node"
NODE_ENV="development"
REDIS_CACHE_HOST="localhost"
REDIS_CACHE_PORT="6379"
REDIS_HOST="localhost"
REDIS_PORT="6379"
SERVICE_BUS_CONNECTION_STRING="<FILL_IN>"
SERVICE_BUS_QUEUE_NAME="<FILL_IN>"
SHADOW_DATABASE_URL="postgres://klicker:klicker@localhost:5432/shadow"
- Run the database and other required services using the
_run_app_dependencies.sh
(Docker/Rancher) script. - Install dependencies with PNPM using
pnpm install
in the root of the repository. - Prepare the database schema and seed with initial data using
pnpm run prisma:setup
. Ideally, open a separate terminal in thepackages/prisma
folder to run this command and continue using this terminal for database-related actions. - If you are setting up KlickerUZH for the first time, run
pnpm run build
on the top level to make sure that all packages are available. - For development of azure functions only: Start the Azurite emulator (e.g., in VSCode using the
Azurite: Start
command, or using theazurite
CLI). - Start the application in development mode using
pnpm run dev
(will start everything and requires internet access and an Azure Service Bus configuration) orpnpm run dev:offline
(will skip Azure functions and thus not require internet access or Azure Service Bus -> live quiz will not be able to process responses). - To visualize the database content during development, use
pnpm run prisma:studio
in thepackages/prisma
folder (available atlocalhost:5555
)
The applications should then be accessible on the configured local domains (e.g., manage.klicker.com
- see list above). If any issues occur, ensure the relevant preparations as described have been made. You can also check the Traefik proxy web interface for any errors on localhost:8080
, or check whether an IP-based access returns any results (e.g., to http://127.0.0.1:3002/
).