The website itself is built with hugo and hosted on AWS S3, delivered through Amazon’s CloudFront CDN and uses Amazon’s Certificate Manager infrastructure to deliver all content through https. I used Gandi.net to purchase the domain and AWS Route 53 to handle all DNS queries. There is a staging replica for every feature, database, and API endpoint. Deployment is done using simple bash script that compiles the website with hugo and deploys the result to AWS S3.
All API endpoints and most of the (event-driven) backend is written as Lambda functions using apex.run, a tool that helps developers build, deploy an manage AWS Lambda functions.
AWS Lambda functions cannot be accessed directly from the Internet, therefore, an AWS API Gateway is required to proxy browser requests to Lambda endpoints.
Essentially, your browser sends the images directly to S3 along with a signed policy that allows this particular query to succeed so others can’t upload content without your permission.
Populating the database
When an image is uploaded to S3, AWS generates an event which I wired to an AWS Lambda function. The S3 image itself contains all user input data as metadata, including the style of their choosing and the user contact details. While this is a very useful feature, S3 makes a terrible database when used in this form. This Lambda function takes the file metadata and populates an RDS Database running PostgreSQL.
- Style Transfer Backend
In case of a sudden increase of traffic an AWS EC2 spot p2.xlarge instance is manually launch which runs a Java app. This app connects to the SQL database and processes any artwork requests that haven’t yet been processed.
- Once a preview image has been generated. An S3 file-created-event is fired, which then executes a Lambda function that sends an email to the user with a link to preview the image. This link is uniquely generated and cannot be guessed. To improve the user experience, the pricing page is shown in the user’s preferred currency. This is done by calling a Lambda function which maps the user’s IP to a country which then maps to a currency and a price suggestion. Once the user pays for an artwork using Stripe’s Elements widgets, Stripe calls a public Lambda endpoint (webhook) with the purchase details (artwork sold, user, price, etc). No card details are ever transferred to AWS. This function updates the database and sends an email to the user with a download link to their HD artwork.
- There are a few other Lambda functions for tracking and understanding user behavior and for refreshing S3 tokens
- Style Transfer Backend deployments
A p2.xlarge instance is setup and created an AMI out of it. This AMI runs an initial script that syncs an S3 folder locally and executes another script which eventually downloads the Java app and dependencies that run the style transfer. This guarantees that the AMI is always up to date with the code, models, and styles regardless of when it was created.
For more details visit Rodrigo’s blog on ‘Style Transfer as a Service‘