Crown-Commercial-Service / digitalmarketplace-router

Digital Marketplace nginx router app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Digital Marketplace PaaS Router

This is an Nginx application which acts as a proxy for all Digital Marketplace PaaS applications.

Requests are routed to the correct location based on the hostname:

Hostname Destination app
api.* API
search-api.* Search API
antivirus-api.* Antivirus API
www.* Front end apps
assets.* S3 resources (or the front end apps, depending on the path)

The router app also handles:

  • Forwarding request headers
  • Adding the Basic Auth header to frontend app requests (these apps' URLs cannot be accessed directly, and must go via the router app)
  • IP restrictions for /admin pages
  • Serving the robots.txt static page
  • Rate limiting
  • 'Maintenance' mode (routing all requests to a static page)
  • gzip settings for CSS and Javascript files

The app-level nginx configurations can be found in the Docker base repo.

Variables

Configuration variables, such as those controlling IP restrictions and rate limiting, are extracted from the environment by the render_template.py script before being injected into the relevant template. These DM_ environment variables are supplied by the manifest for the router PaaS app - see the DM AWS repo. View them with cf env router.

The PaaS manifests are generated by the AWS Makefile using the appropriate set of encrypted vars, so ultimately these variables are coming from the credentials repo.

IP safelist variables

The router uses three sets of IPs to restrict access to certain areas of the Digital Marketplace:

  • DM_ADMIN_USER_IPS: allowed access to the Admin Frontend app (for all environments)
  • DM_USER_IPS: allowed access to Preview and Staging environments
  • DM_DEV_USER_IPS: allowed direct access to the three API apps (auth required)

Testing nginx changes locally

There are two ways to test changes to the nginx configuration:

make test-nginx

Assuming you have Docker installed:

Running make test-nginx does the following:

  • builds a new Docker image from your local repo (using the Dockerfile)

  • starts running a container based on that image, using dummy environment variables

  • starts up nginx inside the image (this takes a few seconds)

  • runs nginx -t to check the config:

      nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
      nginx: configuration file /etc/nginx/nginx.conf test is successful
    

If the config test is successful, the container is stopped and removed. If there is a failure, the container is preserved for investigation.

You can use docker exec -i -t digitalmarketplacerouter_test /bin/bash to look inside the container.

docker-compose

This method uses Docker and docker-compose to build the router image.

Assuming you have Docker and docker-compose installed:

  1. Make your changes. For example, in templates/www.j2:
location /my-location {
    not_a_real_directive oh_dear;
}
  1. Build your new Docker image version from your local changes (tag it with a sensible name if you like)
$docker build -t digitalmarketplace/router:exciting_new_nginx_changes .
  1. Copy the example docker-compose.yml.example settings file to docker-compose.yml in your local directory. Update the settings with your local port(s) and the name of your new docker image version:
version: '2'
services:
  router:
    image: "digitalmarketplace/router:exciting_new_nginx_changes"
    ports:
      - "80:80"
    ...
  1. Run docker-compose up to start the container for the image. Any errors or warnings will appear on the docker compose output:
$ docker-compose up
Creating network "digitalmarketplacerouter_default" with the default driver
Creating digitalmarketplacerouter_router_exciting_new_nginx_changes ...
Creating digitalmarketplacerouter_router_exciting_new_nginx_changes ... done
Attaching to digitalmarketplacerouter_router_exciting_new_nginx_changes
router_1  | 2018-01-05 14:51:24,769 CRIT Supervisor running as root (no user in config file)
router_1  | 2018-01-05 14:51:24,771 INFO supervisord started with pid 1
router_1  | 2018-01-05 14:51:25,776 INFO spawned: 'nginx' with pid 14
router_1  | 2018-01-05 14:51:25,778 INFO spawned: 'awslogs' with pid 15
router_1  | Compiling api
router_1  | Compiling assets
router_1  | Compiling www
router_1  | Compiling healthcheck
2018/01/05 14:51:26 [emerg] 14#14: unknown directive "not_a_real_directive" in /etc/nginx/sites-enabled/www.conf:20
  1. Once the container has started successfully, nginx should be listening on the URL and port you configured, e.g. http://localhost:80/robots.txt should show a static page.

  2. Once you're done, clean up the image and container with docker-compose down. To stop the container without removing it, use docker-compose stop.

Caveat: This method is not ideal for locally testing frontend app routing. In production, PaaS handles this automagically as the frontend apps are all on the same host - more info about this is available on the DM manual).

More info on docker-compose commands: https://docs.docker.com/compose/reference/overview/

Licence

Unless stated otherwise, the codebase is released under the MIT License. This covers both the codebase and any sample code in the documentation.

The documentation is © Crown copyright and available under the terms of the Open Government 3.0 licence.

About

Digital Marketplace nginx router app

License:MIT License


Languages

Language:HTML 73.5%Language:Jinja 12.8%Language:Python 9.0%Language:Makefile 2.8%Language:Dockerfile 1.0%Language:Shell 0.9%