cygnal/doc/0.hosting.md

5.5 KiB

Hosting your own

The app is made of two separate parts. A (micro-)server part which is basically just exposing an API on top of the database and a client part (static JS scripts and assets) which is accessing this API.

Updating the app

Whenever new versions are published, here is a quick guide to do the upgrade:

  • fetch the last updated files from the repository
  • ensure the client part build is up to date (yarn install && yarn build)
  • check for required migrations (see below)
  • ensure the server part requirements are up to date (pip install -r requirements.txt) and restart the server

From times to times, the database schema might need to be updated. Migrations (scripts to edit the database schema for you) are provided under the scripts/migrations folder. The scripts in this folder are labelled by versions, meaning that the 0.3.py script handles the migration of the database from the version immediately before 0.3 to the 0.3 version of the app.

If you upgrade through several versions at once, you should run all the migrations scripts for all the intermediate versions, in the ascending order. There are currently no automated way to handle the updates of the database schema.

Note : Versions of the app are listed in the git tags. Current version of the code is also in the src/constants.js file.

Server part

Build setup

# Install Python dependencies
pip install -r requirements.txt

# Start the server
python -m server

It is better to use a dedicated virtualenv if you can, to help manage Python dependencies in a clean way.

API routes are all listed within server/routes.py file, with documentation strings.

Useful environment variables

You can pass a few environment variables to the python -m server command to adapt its behavior:

  • HOST= to specify the host to listen to (defaults to 127.0.0.1 which means localhost only).
  • PORT= to specify the port to listen on (defaults to 8081).
  • DATABASE= to specify a database URL to connect to (defaults to sqlite:///reports.db which means a SQLite database named reports.db in the current working directory).
  • API_TOKEN= to specify a token required to POST data to the API.

Serving in production

You can use the wsgi.py script at the root of the git repository to serve the server side part. You can find some uwsgi and nginx base config files under the support folder.

You might also want to put some rate-limiting in front of the API. This can be done easily when you use nginx as a reverse proxy for instance. This is handled by the limit_req directive in the nginx base config files provided in the support folder. You can then edit the DELAY_BETWEEN_API_BATCH_REQUESTS configuration option in src/constants.js to ensure that requests will be spaced enough when sending a batch of them so that they will not be blocked by your rate-limiting.

Importing OpenData

A few OpenData files can be imported in Cycl'Assist, to import roadworks for instance. All the useful scripts to import OpenData are in the scripts/opendata folder.

You can set up a daily cron task to automatically run the import of opendata every day for instance.

Client part

Build setup

Here are the steps to build the client side assets and scripts.

# Install JS dependencies
yarn install

# Serve with hot reload at localhost:8080
# (For development only)
yarn dev

# Build for production with minification
# Output assets and scripts in the `dist/` folder, ready to be used in
# production.
yarn build

# Build for production and view the bundle analyzer report
# (might be useful for debugging or development)
yarn build --report

To serve the app in production, you have to build the scripts and assets using yarn build. It will output everything under the dist/ folder which you can then serve using any web server (these are just static files to be served).

Useful environment variables

You can pass a few environment variables to the yarn build|dev commands to adapt the behavior to your needs.

  • PUBLIC_PATH=https://.../foobar to serve the app from a subdirectory.
  • API_BASE_URL=https://... to specify the location of the server API (defaults to /). The value should end with a trailing slash.
  • THUNDERFOREST_API_KEY= to pass an API key server to use for Thunderforest tiles (OpenCycleMap, etc).
  • API_TOKEN= to pass a token required to access the server side API (check below in the server part environment variables for more details).

You should also have a look at the build variables under the config/ subdirectory.

Geographical extension

While the frontend could theoretically work in the entire world without much modifications, it is currently written with mainland France in mind, mostly because that is the territory the authors are most familiar with. Additionnally, this limits the volume of geographical data (such as OSM extracts) to handle and makes managing the app easier.

You could of course easily extend it to support other territories. The French-specific parts of the code so far are: