Background
Iβve been using AWS Elastic Beanstalk for five years to host my hobby app. The application is dockerized and I have two environments: testing and production. Iβve been running it with t2.small
instances since anything smaller cannot handle building Docker containers.
Iβve been deploying new releases using EB CLI. I would say eb deploy prod
and the new version is deployed. Elastic Beanstalkβs Docker Platform would then pick Dockerfile
from the project root and everything just worked.
I need Application Load Balancer (ALB) for SSL/HTTPS. ALBs are quite expensive for hobby projects and since I had two environments, I needed two. Later it became possible to share Application Load Balancer amongst multiple Elastic Beanstalk environments so only one was required. Before this, I dabbled with providing SSL with Letβs Encrypt so I would not need load balancers at all. Cost wise this was effective, but managing it turned out to be too work-intensive and wouldβve required a complete rewrite to support Amazon Linux 2. So I was stuck with one ALB which would hog around 30% of operating costs.
Then came the new service AWS App Runner with the following sales pitch:
App Runner builds and deploys the web application automatically, load balances traffic with encryption, and scales to meet your traffic needs
Sounds good to me, letβs give it a try!
Getting started
The first step was to figure out how to roll out a new App Runner service. Luckily there are plenty of great guides to do this. I followed this one.
I want to deploy from my GitHub repository so as instructed I installed AWS Connector for GitHub to my GitHub organization. Then everything else was a breeze: choose repository and branch and toggle automatic deployments when the repository changes. No need to run manual eb deploy
anymore!
The service can be configured via user interface or apprunner.yaml
file. Iβll continue with the user interface but will most likely change to the config file once everything is working.
Then comes the first interesting part: I have to add commands for building and starting the app. Elastic Beanstalk did not require these, it just picked the Dockerfile
which had all steps defined. Seems like I wonβt be using my Dockerfile
but the scripts the Dockerfile
was using. This means I cannot define the base image or control how the container OS is built. This might be an issue at some point.
I have to choose container build runtime. I happen to use Nodejs 14 which is available, but there is a possibility that you might be using something thatβs not.
Adding environment variables is similar to Elastic Beanstalk, just filling key-value fields. Iβll leave the remaining configs as defaults. Then I hit βCreate serviceβ and ~5 minutes later I have a running application! Or almost.
Turns out my build command needed changing but updates were rolled back automatically. How do I debug this? App Runnerβs user interface doesnβt show much. Took me a moment to find the link to CloudWatch and from there I was able to find the relevant logs.
Turns out I was only installing prod dependencies but required dev dependencies as well. After fixing this, I had a running app and it only took me a couple of hours!
Iβll have to redo these steps to add a second service for my second environment.
Custom domain
App Runner provides me with a domain like foobar.eu-west-1.awsapprunner.com
. The last thing was to add a custom domain like example.com
.
Adding a custom domain is straightforward. App Runnerβs user interface gives me DNS CNAME records for certificate validation and a CNAME record pointing to the App Runner domain. Copy these to DNS settings and wait for DNS settings to propagate.
I have two domains, example.com
and test.example.com
. Iβm using Route 53 as a DNS provider.
Then I found this:
If you're using Amazon Route 53 as your DNS provider, you can add a subdomain, but support for adding a root domain isn't available at this time.
Thatβs a bummer. So example.com
will not work. I moved the test environment with domain test.example.com
to App Runner but I have to change my DNS provider to get the production domain to work. Hopefully, this will get fixed in the future.
Conclusion
I wanted to move my dockerized app running in Elastic Beanstalk to App Runner. Getting started with App Runner took me maybe an hour, then another hour fiddling with settings, and a third one to figure out custom domains. Not bad!
Liked:
- The getting started experience was great.
- Configuring auto-deployment on GitHub repository change was a checkbox. No need to add anything to my CI pipeline!
Didnβt like:
- Silently failing deployments. Took me a while to figure out where the relevant logs are. They were in CloudWatch.
- Not being able to use root domain as custom domain when using Route 53. This forces me to change my DNS provider.
Overall the feeling with App Runner is pretty similar to Elastic Beanstalk. It just does a better job at abstracting the infrastructure away and there are no separate costs for running different services like a load balancer. I have a feeling there will be more constraints I havenβt faced yet, but for now Iβm happy with the result!
Top comments (0)