Deploying Server-Side Swift Apps With Docker on Heroku
- Getting Started
- Building the Docker Image
- Using the Dockerfile
- Building the Image
- Running the Image Locally
- Getting to Know Heroku
- Logging in to the Heroku CLI
- Creating the Heroku App
- Adding the Postgres Add-on
- Configuring Other Environment Variables
- Setting the Heroku App Stack
- Preparing the Vapor App for Deployment
- Configuring Heroku Postgres in the App
- Setting the Database Based on the Environment
- Binding to the Correct Port
- Building and Deploying the App Image
- Container Registry
- Logging in to Heroku’s Container Registry
- Uploading and Releasing the App Image
- Reading Server Logs
- Letting Heroku Build the Image for You
- Creating the heroku.yml File
- Where to Go From Here?
For months, you’ve worked hard on building an API for your app. Now, you want to make it available over the internet. You’re not quite sure what the best option is — or even where to start. Rest assured, this tutorial shows the step-by-step instructions to deploy Server-Side Swift apps with Docker on Heroku.
Most developers with Swift experience come from an iOS or macOS development background, and deploying web apps might not be a trivial task for you. Managing servers, ensuring zero downtime, scaling servers or dealing with other DevOps-related tasks are all hard work. Recognizing this opportunity, some companies package these services and offer them in a developer-friendly way. Heroku is one of these cloud platform providers, and it can help you deploy, manage and scale your web app.
In this tutorial, you’ll learn how to:
- Create a new app in Heroku and set some basic configuration.
- Configure the Postgres database add-on.
- Build a Docker image of your Vapor app, and access the database provided by Heroku.
- Use Heroku’s Container Registry to upload your Docker image, and deploy the container.
- Automate the release process by making Heroku build and release your app’s Docker image on each push to your Git repository.
Start by clicking the Download Materials button at the top or bottom of this page. The materials contain the sample Vapor app you’ll use with this tutorial. It’s a familiar friend from the Server-Side Swift book and video course: the TIL app, a web app and API for searching and adding acronyms.
Unzip the file, and with Xcode or your favorite text editor, open the starter folder. You’ll build and run it soon, but for now, it’s worth familiarizing yourself with the code. The files inside the Controllers, Models and Migrations directories are the backbone of this app. Also very important, and the only Swift file you’ll modify in this tutorial, is the configure.swift file. Look at how it configures the app and also the contents of
Building the Docker Image
Before jumping straight into the deployment and Heroku sections, it’s important to do a quick recap on how to build and run a Docker image, so you can first run your app locally.
Using the Dockerfile
The Dockerfile is the recipe Docker uses to build your app images, which you can later deploy onto containers. If Docker is new to you, refer to Developing and Testing Server-Side Swift with Docker and Vapor, to learn more about it.
The starter sample project already includes a Dockerfile that’s ready for production deployments. This is basically the same file present in Vapor’s official template project.
Building the Image
After opening your preferred terminal application, navigate to the starter project folder. Then, run the command below:
docker build . --tag til-app
A few notes about this command:
- It tells Docker to build an image. The
.character represents the current directory, and it’s where Docker looks for the Dockerfile.
- By default, Docker looks for a file named Dockerfile within that path. If you use a Dockerfile with a different name — as another file for development or testing — the
--fileparameter would be required.
--tagparameter helps Docker to identify this image. Docker uses this tag name when it needs to run a container based on this image.
Once you run this command, Docker starts by pulling the base Swift image. It then runs all the commands described in Dockerfile. This includes downloading the Swift package dependencies, building the app with the Swift compiler and then copying the app binary into a slimmer running image, ideal for deployments.
Running the Image Locally
After a few minutes, Docker will finish building your app image. Now, it’s time to run it locally to make sure everything looks good.
The only service the app needs is a PostgreSQL database available. You don’t have to install Postgres on your machine, create the database and configure access. Docker Compose can do all that. The starter project also provides the docker-compose.yml file, which can download the Postgres image and serve it to the app.
Run this command to make Docker Compose prepare the Postgres container:
docker compose run --rm start_dependencies
This ensures that the database container is up, running and ready to receive connections from the app.
start_dependencies creates a temporary container, which won’t be needed after the database is up. Therefore, you use
--rm to tell Docker to remove it after the command returns.
To start the app container using the image you built in the previous section, run the command below:
docker compose up app
Now, visit http://localhost:8080 in your browser, and you’ll see the TIL home page:
Run the following call to get some server information, which
The response contains three properties:
- Date the server started running.
- Platform — macOS or Linux.
- App environment.
Notice that the app responds with
docker-local as the app environment. When later deploying the app to Heroku, you’ll learn how to change that without the need to modify the app code.
Fantastic! You’ve built and run the image on your local machine. In a later section, you’ll perform some changes to allow deployment. But first, a quick section about Heroku will introduce it to you or refresh your memory.
Getting to Know Heroku
Heroku is one of the most popular PAAS — platform as a service — providers. It also helps remove the need to manage hardware or virtual machines, servers and DNS. Heroku allows developers to deploy and scale web apps using containers. These containers deployed at Heroku are called dynos. You can scale your app to run on any specified number of dynos based on its resource demands.
Besides supplying you with the infrastructure to run your app containers, Heroku also provides add-ons. Add-ons are services that are necessary for your web apps. Web apps might need a PostgreSQL or MongoDB database, a CDN or a Redis cache — maybe even all of them, and more. With Heroku, setting up these resources is a breeze!