For bbnavi, we run several instances of digitransit-ui
, one per *.bbnavi.de
subdomain.
Even though digitransit-ui
is mainly a client-side front-end application, it also has a server side (which serves its configuration and proxies some requests). As our continuous integration (CI) and continuous deployment (CD) process, we lint & test the code, build a Docker image from it and deploy that to TPWD's infrastructure, which is a Docker Swarm cluster provided and managed by Planetary Quantum.
We develop using one development branch (release/int/development
) and one main branch (bbnavi
). We deploy an instance by pushing an accordingly named Git tag – e.g. release_angermuende_2022_04_13
to deploy angermuende.bbnavi.de
. Thus, the deployed digitransit-ui
instances only differ in two possible ways:
- different states of development –
angermuende.bbnavi.de
might have been deployed via a tag on a more recent commit of thebbnavi
branch than e.g.herzberg-elster.bbnavi.de
- configured environment variables, which in turn might toggle feature flags in the code
A CONFIG
environment variable is used to determine which instance-specific configuration to use; For example, CONFIG=bbnavi-angermuende
will make it load app/configurations/config.bbnavi-angermuende.js
. Because we develop from one main branch, almost all differences between the instances lead back to a different config.bbnavi-*.js
file being used because of a different $CONFIG
value.
lint-test-deploy.yml
defines all steps to be run by the GitHub Actions CI service:
- On a push to any branch, the CI system will
a. lint, build & test the code by running the respective
yarn run …
commands b. build a Docker image, but only cache the image's layers (to speed up subsequent builds) without pushing it - When Git tag named
release_<instance>_<date>
orrelease_<instance>_<date>_<i>
is pushed, the CI system will- lint, build & test the code, as described above
- build a Docker image tagged with
- the Git tag, e.g.
release_frankfurt-oder_2023-02-06_2
- a "stable" tag used to permanently identify one deployment, consisting of the date+time and the Git commit's hash, e.g.
2023-02-06T09.10.12-abcdefgh
- the Git tag, e.g.
- push this Docker image to the Container Registry
- deploy that Docker image to our infrastructure, using
- Docker Compose to compile both general as well as instance-specific configuration parameters & secrets into a "flat" Docker Swarm stack
- Quantum CLI, a command-line interface to Planetary Quantum
Because artifacts (e.g. node_modules
, intermediate Docker image layers) needed for the CI process are being cached, deploying the same Git commiut to many instances avoids re-doing the time-consuming (full) Docker image build (with some notable exceptions).
Also, because each deployment is represented as a Git tag, we have transparency over what has been deployed where and when.
Assuming an instance name bbnavi-foo
available at bar.bbnavi.de
, and an already existing MATOMO-Container for the new instance, follow these steps below. Note: in most cases, bar.bbnavi.de
will be equal to foo.bbnavi.de
, but other domain names (e.g. mitfahrenbb.de
) may be chosen also.
- Create a new configuration
app/configurations/config.bbnavi-foo.js
, e.g. by copyingapp/configurations/config.bbnavi-bad-belzig.js
, and customize it:- Adapt the
CONFIG
,APP_TITLE
,HEADER_TITLE
variables - For MATOMO_URL, specify the URL of the monitoring container, e.g. 'https://nutzung.bbnavi.de/js/container_XXXXXX.js', where XXXX is instance specific. If no tracking is intended, remove all references to MATOMO.
- for
searchParams
anddefaultEndpoint
, choose the center location of the choosen regions, e.g. figured out via https://osm.org
- Adapt the
- Copy the styles customizations from an existing instance, e.g. via
cp -r sass/themes/bbnavi-{bad-belzig,foo}
- Test your customizations locally by running the local dev environment with
CONFIG=bbnavi-foo
. For more information, see the installation documentation - Create a new deployment file
deployments/stack.foo.yml
by copying and adapting e.g.deployments/stack.bad-belzig.yml
. Make sure to setCONFIG=bbnavi-foo
and to configuretraefik.frontend.rule: Host:bar.bbnavi.de
. This file partially overrides/extendsdeployments/stack.yml
. - Optional: if the instance should be accessible only with basic authentication, configure
traefik.frontend.auth.basic.users
indeployments/stack.foo.yml
like e.g. for the Bernau instance. The password can be encrypted viahtpasswd
(see traefik docs for details) - Push your changes to GitHub, either into a separate branch, or into
bbnavi
. Wait for the CI to lint and test your code. After an initial test deployment, we usually merge the changes intobbnavi
. - Create a Git tag
release_foo_<year>-<month>-<date>
, e.g. by runninggit tag release_foo_2023-04-05
, and push it viagit push --no-verify origin release_foo_2023-04-05
. A resulting CI workflow run (see the workflows list) should now lint and test the code, and then deploy the instance by creating a new service in the Docker Swarm cluster. - Soon after, your instance should be available at
https://bar.bbnavi.de
.