-
Notifications
You must be signed in to change notification settings - Fork 0
Deployment
-
Launch an EC2 instance running Ubuntu (e.g. Ubuntu 18.04)
-
Make sure the security group for the EC2 instance has port 3000 open
-
SSH into the instance
-
Install Docker (Linux)
sudo apt-get -y install docker-engine sudo usermod -aG docker $USER sudo reboot
-
Export the test/production Neo4j endpoint as the environment variable
DB_ENDPOINT
.
Be sure it references a current neo4j instance. E.g.export DB_ENDPOINT=ec2-01-234-56-789.us-west-2.compute.amazonaws.com
To remove the the environment variable (for example when switching back to a dev environment), unset it
unset DB_ENDPOINT
-
Run the production Docker-Compose. This will launch 3 containers: the UI, the api server and the nginx webserver.
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
AWS runs these scripts when a deployment is triggered. The main job of these scripts is to run docker-compose to create the staging or production environment from scratch. Much of the extra scripting in these files is to set up SSL.
Nginx
Nginx is web server software that receives and responds to HTTP/HTTPS requests. Documentation for nginx can be found under the folder "nginx_proxy".
Nginx is web server software that receives and responds to HTTP/HTTPS requests.
We have two instances of nginx running at the same time. There is the proxy, which is configured per the configuration files located in this folder. The proxy is the "edge" instance that forwards traffic to and from the UI and API containers to web browsers over the Internet. The UI container runs a different instance of nginx to serve static content in the production environment. In a local dev environment, a temporary web server is set up by by create-react-app which serves the content dynamically for development purposes.
The API container, rather than using nginx, uses the node process to serve content dynamically using the web server package called Express. These responses are first sent through the proxy before reaching the client.
The nginx proxy does the following:
- encrypts responses using SSL cert files
- serves HTTP content to prove the server's identity to LetsEncrypt
- forwards data compression added either by UI's nginx or API's Express
- adds Cache-
The SSL cert files need to exist at the location where nginx looks for them when it starts up, and as long as the cert is valid the site will use SSL. Letsencrypt is a free certificate authority that issues SSL certs, and those certs enable HTTPS and prevent browsers from showing a warning screen. Letsencrypt certs last 90 days. There is a limit to 5 reissuances of a cert per week, and there is no way to extend this limitation. Since we use docker, we re-create the server during every deployment, and thus certs need to be created from scratch (aka, "re-issued"). Currently, each deploy to prod and/or staging causes a reissue. After the 5th in a week, the browser warning will come back since our setup falls back to a temporary cert if the reissue fails. Requesting a cert requires the ability to prove ownership of the site, and in order to do this nginx needs to be up and running and able to serve HTTP with files automatically created by the certbot docker image; since nginx is configured for SSL, a temporary cert (also referred to as a "dummy" cert) is needed as a placeholder to prevent nginx from crashing. The docker-compose script loads a small certbot docker image that attempts to renew the cert every 12 hours. Renewing a cert in this manner does not cause it to be reissued, so this does not count toward the limit. Also in the docker-compose script, the nginx docker image runs a command to restart itself every 6 hours. This is needed in order to load a renewed cert, which inevitably becomes necessary.
SSL Cert Implementation Details
Certbot is a command line tool used to manage Let's Encrypt certs (https://certbot.eff.org/) It is possible to persist the certs on AWS S3 and copy to/from, which is the only way to work around the limitation of 5 issuances. Right now, we attempt to copy the certs to AWS, but this is being done only for testing and debugging at this time. The limitation is mainly an issue at times when we have a permanent staging site, since that gets re-deployed often when code changes are merged to certain branches, triggering CI. Note that if the server is up and running for more than 90 days, the copied certs would be expired and reissuing would be necessary. Let's Encrypt staging environment details can be found here: https://letsencrypt.org/docs/staging-environment/
Note: this documentation is a work in progress