Home iOS & Swift Books Server-Side Swift with Vapor

32
Deploying with Heroku Written by Logan Wright

Heroku is a popular hosting solution that simplifies deployment of web and cloud applications. It supports a number of popular languages and database options. In this chapter, you’ll learn how to deploy a Vapor web app with a PostgreSQL database on Heroku.

Setting up Heroku

If you don’t already have a Heroku account, sign up for one now. Heroku offers free options and setting up an account is painless. Simply visit https://signup.heroku.com/ and follow the instructions to create an account.

Installing CLI

Now that you have your Heroku account, install the Heroku CLI tool. The easiest way to install on macOS is through Homebrew. In Terminal, enter:

brew install heroku/brew/heroku

Logging in

With the Heroku CLI installed, you need to log in to your account. In Terminal, enter:

heroku login
heroku auth:whoami

Create an application

Visit heroku.com in your browser to create a new application. Heroku.com should redirect you to dashboard.heroku.com. If it doesn’t, make sure you’re logged in and try again. Once at the dashboard, in the upper right hand corner, there’s a button that says New. Click it and select Create new app.

Enter application name

At the next screen, choose the deployment region and a unique app name. If you don’t want to choose your app’s name, leave the field blank and Heroku automatically generates a unique slug to identify the application for you. Whether you create a name, or Heroku assigns you one, make note of it; you’ll use it later when configuring your app.

Add PostgreSQL database

After creating your application, Heroku redirects you to your application’s page. Near the top, under your application’s name, there is a row of tabs. Select Resources.

Setting up your Vapor app locally

Your application is now setup with Heroku; the next step is to configure the Vapor app locally. Download and open the project associated with this chapter. If you’ve been following along with the book, it should look like the TIL project you’ve been working on. You’re free to use your own project instead.

Git

Heroku uses Git to deploy your app, so you’ll need to put your project into a Git repository, if it isn’t already.

git rev-parse --is-inside-work-tree

Initialize Git

If you need to add Git to your project, enter the following command in Terminal:

git init
git add .
git commit -m "Initial commit"

Branch

Heroku deploys the main branch. Make sure you are on this branch and have merged any changes you wish to deploy.

git branch
* main
  commander
  other-branches
git checkout main
git checkout master
git branch -m main

Commit changes

Make sure all changes are in your main branch and committed. You can verify by entering the following command. If you see any output, it means you have uncommitted changes.

git status --porcelain
git add .
git commit -m "a description of the changes I made"

Connect with Heroku

Heroku needs to configure another remote on your Git repository. Enter the following command in Terminal, substituting your app’s Heroku name:

heroku git:remote -a your-apps-name-here

Set Buildpack

Heroku uses something called a Buildpack to provide the recipe for building your app when you deploy it. The Vapor Community currently provides a Buildpack designed for Vapor apps. To set the Buildpack for your application, enter the following in Terminal:

heroku buildpacks:set \
  https://github.com/vapor-community/heroku-buildpack

Enable Test Discovery

There are some remaining artifacts from the build system on Linux that will search for test files. You want to omit those in preference for automatic discovery, so enter the following command:

heroku config:set SWIFT_BUILD_FLAGS="--enable-test-discovery"

Swift version file

Now that your Buildpack is set, Heroku needs a couple of configuration files. The first of these is .swift-version. This is used by the Buildpack to determine which version of Swift to install for the project. Enter the following command in Terminal:

echo "5.3" > .swift-version

Procfile

Once the app is built on Heroku, Heroku needs to know what type of process to run and how to run it. To determine this, it utilizes a special file named Procfile. Enter the following command to create your Procfile:

echo "web: Run serve --env production" \
  "--hostname 0.0.0.0 --port \$PORT" > Procfile
web: Run serve --env production --hostname 0.0.0.0 --port $PORT

Commit changes

As mentioned earlier, Heroku uses Git and the main branch to deploy applications. Since you configured Git earlier, you’ve added two files: Procfile and .swift-version. These need to be committed before deploying or Heroku won’t be able to properly build the application. Enter the following commands in Terminal:

git add .
git commit -m "adding heroku build files"

Configure the database

There’s one more thing to do before you deploy your app: You must configure the database within your app. Start by listing the configuration variables for your app.

heroku config
=== today-i-learned-vapor Config Vars
DATABASE_URL: postgres://cybntsgadydqzm:2d9dc7f6d964f4750da1518ad71hag2ba729cd4527d4a18c70e024b11cfa8f4b@ec2-54-221-192-231.compute-1.amazonaws.com:5432/dfr89mvoo550b4
postgres://cybntsgadydqzm:2d9dc7f6d964f4750da1518ad71hag2ba729cd4527d4a18c70e024b11cfa8f4b@ec2-54-221-192-231.compute-1.amazonaws.com:5432/dfr89mvoo550b4
app.databases.use(.postgres(
  hostname: Environment.get("DATABASE_HOST") ?? "localhost",
  port: databasePort,
  username: Environment.get("DATABASE_USERNAME") ?? 
    "vapor_username",
  password: Environment.get("DATABASE_PASSWORD") ?? 
    "vapor_password",
  database: Environment.get("DATABASE_NAME") ?? databaseName
), as: .psql)
if var config = Environment.get("DATABASE_URL")
    .flatMap(URL.init)
    .flatMap(PostgresConfiguration.init) {
  config.tlsConfiguration = .forClient(
    certificateVerification: .none)
  app.databases.use(.postgres(
    configuration: config
  ), as: .psql)
} else {
  app.databases.use(
    .postgres(
      hostname: Environment.get("DATABASE_HOST") ??
        "localhost",
      port: databasePort,
      username: Environment.get("DATABASE_USERNAME") ??
        "vapor_username",
      password: Environment.get("DATABASE_PASSWORD") ??
        "vapor_password",
      database: Environment.get("DATABASE_NAME") ??
        databaseName),
    as: .psql)
}
git add .
git commit -m "configured heroku database"

Configure Google environment variables

If you completed Chapter 22, “Google Authentication” and are using that as your project here, you must configure the same Google environment variables you used there.

heroku config:set \
  GOOGLE_CALLBACK_URL=https://<YOUR_HEROKU_URL>/oauth/google

heroku config:set GOOGLE_CLIENT_ID=<YOUR_CLIENT_ID>

heroku config:set GOOGLE_CLIENT_SECRET=<YOUR_CLIENT_SECRET>

Configure GitHub environment variables

If you completed Chapter 23, “GitHub Authentication” and are using that as your project here, you must configure the same GitHub environment variables you used there.

heroku config:set \
  GITHUB_CALLBACK_URL=https://<YOUR_HEROKU_URL>/oauth/github

heroku config:set GITHUB_CLIENT_ID=<YOUR_CLIENT_ID>

heroku config:set GITHUB_CLIENT_SECRET=<YOUR_CLIENT_SECRET>

Deploy to Heroku

You’re now ready to deploy your app to Heroku. Push your main branch to your Heroku remote and wait for everything to build. This can take a while, particularly on a large application.

git push heroku main
heroku ps:scale web=1
heroku open

Where to go from here?

In this chapter, you learned how to set up the app in the Heroku dashboard, configure your Git repository, add the necessary configuration files to your project, and deploy your app. Explore your dashboard and the Heroku Help to learn even more options!

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2021 Razeware LLC

You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.