Overview

All right, we're all away from campus, socially distanced and localhost is a little too lonely. How are you going to play a friendly game of fake sports with your friends? How about the world wide web? It would be awesome if you could take things a level up from localhost. And hey! What if we applied that to autocorrect too?

We will be using Heroku in this lab to deploy Autocorrect. Heroku was created in response to complex ecosystems such as AWS or Google Cloud. Instead of managing multiple services, Heroku lets you push to it very much like you push your code to git. You can get your application up and running in a matter of minutes, and all you really need to do is include a couple files that tell Heroku how to run your application. However, there are downsides to this. Heroku is pricier than either AWS or Google Cloud, and its free tier shuts down after 30 minutes of inactivity, resulting in less than instant page loads if the application is inactive. We feel that with Maven and Spark, Heroku is a good platform to deploy your applications on, but we will also list other means of deploying.

Important: This is only one way to deploy your projects, and is not even necessarily the best choice. Please read the final section, What else can you deploy on? and consider your options before selecting a hosting service.

When we refer to your autocorrect code, you can use your code from any frontend based labs. Feel free to choose between deploying your HTML, JavaScript or Canvas lab! Make sure all of your changes are pushed to the master branch first.

Setup

Note: we recommend completing this on a personal laptop or non-department machine, since you may not have appropriate permissions for installing the needed software on department machines.

Making your Heroku account

This lab refers quite a bit to “Deploying Spark on Heroku” from the Spark documentation, which we found to be a very helpful guide.

  1. Click here to create your account.
  2. In the top right, click “Sign Up”.
  3. Fill out your information in the form and go to your e-mail to confirm your account.
    • Under “Role,” select “Student.”
    • Under “Primary Development Language,” select “Java.”

You will also need to install the Heroku CLI. You should follow the instructions here. You should install the CLI and then login with the credentials you created previously using heroku login in your terminal.

Running Autocorrect in the cloud

Now that we have Heroku ready to go in our terminal, we have to make a few edits to our working directory to get our Autocorrect live.

The Procfile

First, create a file called simply Procfile (with no dot extension) at your root directory. The Procfile specfies what commands should be run at the application’s startup. In our case, our Procfile file is only one line, which is:

web: java $JAVA_OPTS -cp target/classes:target/dependency/* edu.brown.cs.<your cs login>.main.Main

Note that if you didn't refactor your packages, you can replace <your cs login> with just student.

If you would like to deploy your final project, simply change the package path to wherever your Main class is. More information on Procfiles are linked here.

We also have to include a settings file to tell Heroku to use Java 11. Create a file called system.properties also at your root directory and add the following line: java.runtime.version=11

Editing The Main Class

There are a few modifications we must make to our Main class in order for Heroku to function properly.

  1. Add this static method to your Main class.
  2.       static int getHerokuAssignedPort() {
            ProcessBuilder processBuilder = new ProcessBuilder();
            if (processBuilder.environment().get("PORT") != null) {
                return Integer.parseInt(processBuilder.environment().get("PORT"));
            }
            return 4567; //return default port if heroku-port isn't set (i.e. on localhost)
         } 
  3. We will have to edit the runSparkServer method so that it uses a Heroku specified port. Your first two lines of runSparkServer should now look like this.
  4.       private static void runSparkServer() {
            Spark.port(getHerokuAssignedPort()); 
  5. Heroku will run whatever is executed by ./run. However, we currently send our GUI to localhost using ./run --gui. Thus, we want to change this to simply ./run. One way to do this is by removing the if (options.has("gui")) clause, so that the code inside the block is always run.
  6. Ensure that now you can mvn package without errors and ./run will start up your GUI.

Updating the pom.xml

We must add a few plugins to the build tag of our pom.xml. Under the build tag, then under the plugins tag, we will now add two new plugins. This portion of your pom.xml should now be of the form...

  <build>
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>3.0.1</version>
        <executions>
          <execution>
              <id>copy-dependencies</id>
              <phase>package</phase>
              <goals><goal>copy-dependencies</goal></goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>com.heroku.sdk</groupId>
        <artifactId>heroku-maven-plugin</artifactId>
        <version>1.1.3</version>
        <configuration>
            <jdkVersion>11.0.1</jdkVersion>
            <appName>autocorrect_test</appName>
            <processTypes>
                <!-- Tell Heroku how to launch your application -->
                <web>java -jar ./target/javalin-heroku-example-1.0-jar-with-dependencies.jar</web>
            </processTypes>
        </configuration>
      </plugin>
    </plugins>
  </build>
  

Uploading Our Application

Before deploying publicly, we should test that we can deploy our application locally through Heroku. Run these two commands in your terminal

    $ mvn clean install
    $ heroku local web

Your autocorrect should now be available at http://localhost:5000/autocorrect.

If this works, we can now deploy publicly! But first, commit and push your code to git as we normally have.

  1. We must first create a domain name provided by Heroku. To do this enter either in your terminal
  2. $ heroku create 

    which will give you a random domain name from Heroku, or

    $ heroku create <your desired app name>

    which will give you a corresponding domain name to the app name you enter, provided that it exists.

  3. Now, we run
  4. git remote -v

    to ensure that we have linked our repo to a remote git repository specifically for Heroku. The output should show that you have a remote called "heroku" that will look something like this:

    heroku  https://git.heroku.com/thawing-inlet-61413.git (fetch)
    heroku  https://git.heroku.com/thawing-inlet-61413.git (push)
  5. Ensure you have committed your latest code to git and run
  6. git push heroku master

    to deploy your code! After running this command, the terminal should list the url of your application. Enter this in your browser at the /autocorrect route, and you should see your Autocorrect online! It may be a little slow but please be patient. Even try the URL on your phone or your friend's computer! More information about uploading through Git can be found here

And... That's it! Show your friends your fun public Autocorrect application!

More information

Deploying your final project

If you are thinking about deploying your final project, you will mostly follow what we have listed above. If you have any concerns, please reach out to a TA!

What else can you deploy on?

There are a plethora of options out there for deploying your applications. We chose Heroku because it allowed us to illustrate the concepts and practices behind deploying an application without requiring you guys to actually pay for server space. Each option has pros and cons, so be sure to do your research.

Google Cloud Platform

The Cloud Platform interface is what we used to use for the deployment lab, but students found it too complicated. The Google Cloud Platform Free tier gives users 12 months and $300 in credit to use any GCP product. You can sign up for an account at this link. At the end of your trial, your account will be paused and you will have the option to upgrade to a paid account, but it will not happen automatically. More information can be found on their here.

Amazon Web Services (AWS)

AWS is used quite prominently in industry. It offers a number of comparable services to Google Cloud, and has some offerings that allow beginners to deploy several services at once to avoid having to configure each to interact with the rest. The pricing is very similar to Google Cloud, and AWS even has a free tier of services that you can use for free (although you will still need to put in your credit card). The downside, though, is that AWS is a rather complex ecosystem of products, and figuring out how everything fits together can be overwhelming. For reference, cs132 has a helpful lab on deployment with AWS.

Containerization

In this lab, we went through a series of steps to set up our Autocorrect application and get it live. What if we had to do it again? Five more times? In situations where rapid deployment, and therefore minimal downtime, of your application is a priority, containerization services are worth a look at. Docker is a service that allows you to package your application in a way that optimizes for space and security, automates environment configuration through special Dockerfiles, and has some major advantages over traditional VMs, as shown here. While deploying your application with Docker requires more work and configuration, definitely look into it if you are interested, as AWS, Google Cloud, and Heroku all have support for Docker (although Heroku's support is in beta).