Skip to content

Instantly share code, notes, and snippets.

@YazzyYaz
Forked from ArjunBhuptani/etc-deployment.md
Created May 28, 2020 00:06
Show Gist options
  • Save YazzyYaz/7c49d16949d75c5f472282e7b0cd4357 to your computer and use it in GitHub Desktop.
Save YazzyYaz/7c49d16949d75c5f472282e7b0cd4357 to your computer and use it in GitHub Desktop.
ETC Deployment Guide

ETC Deployment Guide

This guide is pieced together from docs available at https://github.com/connextproject/indra

Deploy an Indra node to production

Lets say you want to deploy an Indra payment node to https://indra.example.com (we'll call this url $DOMAINNAME)

First step: get a server via AWS or DigitalOcean or whichever cloud provider is your favorite. For best results, use the most recent LTS version of Ubuntu. Note this new server's IP address (we'll call it $SERVER_IP). Make sure it's able to connect to the internet via ports 80, 443, 4222, and 4223 (no action required on DigitalOcean, Security Group config needs to be setup properly on AWS).

Set up DNS so that $DOMAINNAME points to this server's IP address.

Every Indra node needs access to a hot wallet, you should generate a fresh mnemonic for your node's wallet that isn't used anywhere else. You can generate a new mnemonic from a node console with ethers by doing something like this: require('ethers').Wallet.createRandom().

Save this mnemonic somewhere safe, copy it to your clipboard, and then run:

SSH_KEY=$HOME/.ssh/id_rsa bash ops/setup-ubuntu.sh $SERVER_IP

If this is a fresh Ubuntu server from DigitalOcean or AWS then the above script should:

- configure an "ubuntu" user and disable root login (if enabled)
- give an additional ssh public key login access if provided (useful for CD/auto-deployment)
- install docker & make & other dependencies
- upgrade everything to the latest version
- save your mnemonic in a docker secret called `indra_mnemonic
- reboot

Note: this script is idempotent aka you can run it over and over again w/out causing any problems. In fact, re-running it every month or so will help keep things up-to-date (you can skip inputting the mnemonic on subsequent runs).

For convenience sake, we recommend adding an entry to your ssh config to easily access this server. Add something that looks like the following to $HOME/.ssh/config:

  Host new-indra
  Hostname $SERVER_IP
  User ubuntu
  IdentityFile ~/.ssh/id_rsa
  ServerAliveInterval 120

Now you can login to this server with just ssh new-indra. Once the server wakes up again after rebooting at the end of ops/setup-ubuntu, login to finish setup.

First step: clone the git repo on your prod server:

ssh new-indra git clone https://github.com/ConnextProject/indra.git

If you're using a custom address book, upload it to your prod server (you probably wont need this for now because we've predeployed all of the contracts):

scp address-book.json new-indra:~/indra/

We need to add a couple env vars before launching our indra node. ~/.bashrc is a good place to add them as they'll be loaded automatically every time you login to the server.

Open ~/.bashrc on your prod server in a text editor and add these required env vars:

export INDRA_DOMAINNAME="$DOMAINNAME"
export INDRA_ETH_PROVIDER="https://www.ethercluster.com/etc"

Optionally, add any of the following env vars to enable extra features:

export INDRA_MODE="release" # "release": deploy latest release (more stable), "staging": run code at current commit (easier to hotfix)
export INDRA_EMAIL="noreply@gmail.com" # To recieve alerts if https certs fail to auto-renew
export INDRA_AWS_ACCESS_KEY_ID="" # creds to access AWS S3 storage, db will send perodic backups here if provided.
export INDRA_AWS_SECRET_ACCESS_KEY="" # see above, both of these must be provided for remote db backups
export INDRA_LOGDNA_KEY="abc123" # if provided, all node logs will be sent to LogDNA for further analysis
export INDRA_ADMIN_TOKEN="cxt1234" # To control access to admin functions on the dashboard.

Once your env vars are setup, load them into your current session (source ~/.bashrc) and we're ready to roll.

Login to your prod server then run the following to launch your Indra node:

cd indra
make restart-prod

The above will download & run docker images associated with the commit/release you have checked out. If you want to launch a specific version of indra, checkout that version's tag & restart:

git checkout indra-4.1.0 && make restart-prod

Setting up CI/CD

All auto-deployment config can be found in .github/workflows/. See GitHub Actions Documentation for docs.

The auto-deployer needs an ssh key so it can login to the prod server, we should use a fresh one instead of re-using existing ssh keys. Run this command to generate a new ssh key pair: ssh-keygen -t rsa -b 4096 -C "autodeployer" -m pem -f .ssh/autodeployer. The ops/setup-ubuntu.sh script will look for a public key called $HOME/.ssh/autodeployer.pub and try to add it to the server's ~/.ssh/authorized_keys. If we ever change the autodeployer's ssh key, we can add the new keys to our servers by re-running bash ops/setup-ubuntu.sh $SERVER_IP.

Env vars controlling CD are store in: GitHub -> Indra Repo -> Settings -> Secrets. The following env vars are used:

`DOCKER_USER` & `DOCKER_PASSWORD`: Login credentials for someone with push access to the docker repository specified by the registry vars at the top of the Makefile & ops/start-prod.sh.
`INDRA_ADMIN_TOKEN`: an admin token for controlling access to sensitive parts of the dashboard. This can be anything for now -- dashboard is still being worked on.
`INDRA_AWS_ACCESS_KEY_ID` & `INDRA_AWS_SECRET_ACCESS_KEY`: Login credentials for an AWS storage repo, if provided the database will automatically send DB snapshots to AWS.
`INDRA_LOGDNA_KEY`: Credentials for LogDNA. If provided, all logs will be sent to this service for further analysis.
`MAINNET_ETH_PROVIDER` & `RINKEBY_ETH_PROVIDER`: Ethercluster RPC URLs. *note* For now it's probably ok to map Kotti to rinkeby and we can figure out a way to make this more extensible in the future.
`SSH_KEY`: The autodeployer private ssh key

(Re)Deploying Contracts

If you're using Mainnet or Kotti, contracts have already been deployed for everyone to use. You'll find addresses for all the contracts powering our state channel platform here: modules/contracts/address-book.json.

At some point in the future (in the event that we push a new major release but ETC/Kotti contracts are out of date), you may want to redeploy contracts. To do this, delete their addresses from the address book & run the below deployment script.

You'll first need to retrieve the mnemonic for an account that has enough funds to pay the gas fees. Copy that mnemonic to your clipboard & then run:

bash ops/deploy-contracts.sh https://www.ethercluster.com/etc

This will update the address-book to include new addresses for either the new contracts or new network you're deploying to.

If you want to share these updates with everyone, then commit the new address-book & submit a PR. If these updates are specific to your situation/organization then add a copy of the updated address-book to the project root:

cp modules/contracts/address-book.json ./address-book.json

An address-book in the project root will take precedence over one in the contracts module. It's also added to the git-ignore so you can pull updates to the rest of the code without worrying about your addresses getting overwritten. If you're deploying an Indra node to prod, then keep this custom address-book safe, we'll need to give it to the prod-server too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment