Pandere runs a number of apps that serve millions of users per month, with large spikes at the beginning and end of the month.
The system is built up of several Rails apps running on AWS and a React Native app for iOS. During my tenure, I:
- Updated the infrastructure setup to use Terraform, Ansible and Packer
- Built out the API to serve the iOS app
- Rebuilt the native version of the iOS app in React Native to allow us to iterate faster
- Managed and fixed issues in the existing app
- Built out a CI pipeline that removed the need to manually deploy the applications, and performed blue-green deployments with zero downtime
One of the key changes we made to the system was to move from servers that were provisioned once and updated manually to automated provisioning and the ability to kill any instances and have them rebuilt without downtime. This change enabled us to create an environment where we didn;t need to worry about a specific instance, instead we were able to take instances out of rotation to investigate anomolies, and to rebuild or provision instances as necessary.
We used Ansible with Packer in order to create the AMIs used in our Launch Configurations. These Configuratins along with the Autoscsale Groups, load balancers and other AWS infrastructure was all defined in the Terraform configuration, which meant that any changes to the infrastructure could be reviewed in a PR, then deployed to staging (a totally separate AWS environment) before being pushed into production. This allowed us to test and catch any performance issues or problems with autoscale, load balancing and so on.
iOS and the API
There was a business case for creating an iOS app for the sites, so we contracted an iOS developer and built out a RESTful API to act as the backend. Creating the infrastructure to host and deploy the API was simplified by the work done on the infra automation, and we were able to create the API in a pretty tight timeframe.
Once the iOS app was complete, launched, and getting traction, it became obvious that maintaining and modifying the app was going to be a problem as there wasn’t the work to employ a full time Swift developer, and scheduling in small pieces of work lengthened the develop, test, release cycle too much.
In light of this, we decided to try React Native as a replacement framework. We rebuild the entire app and relaunched, and currently, we have the same short lifecycle for features as the web app.
Part of the development cycle is reviewing and testing the PRs that are submitted. In order to do this efficiently with remote devs, this needs to be integrated with Github in order to show the status of each PR (passing or failing), and as part of the review process, missing tests can be added as necessary. This gives a level of confidence in the state of the app before QA and production deployment.
CI can also be used to deploy, and we set this up for both the iOS app and the web apps.
Fastlane is an excellend suite of tools that allow us to test, build, sign and deploy to Testflight, CodePush and the App Store in an entirely automated way, removing the opportunity for human error to creep in.
Web and API CI
This is a little more standard, using Travis to run the specs, then AWS CodePush to deploy the newly minted app via a blue-green deployment to either production or staging, as appropriate. Integration with Slack keeps everyone in the loop as to the version deployed or any rollbacks and failures.
Matthew is one of the best programmers I've had the fortune to meet.
Jim Neath, MD Pandere Ltd