How to Deploy a Vue App

In this post, I’m going to show you what options you’ve got when it comes to deploying a Vue app to a server.

Assuming that you’ve created your app using the Vue CLI, later you can build your app by running npm run build command and then host the contents of the resulting dist/ directory on a traditional Apache or Nginx server. That is the most straightforward strategy that you can adopt as well as this way you’ll only have to upload the build files generated in the /dist directory as opposed to uploading the entire source code to the server.

If you’ve used Vue CLI to generate your application, you should be aware that you already have a way to run your app by issuing npm run serve command. It will spawn a local development server to host your app from a non-public local port such as port 3000. Even though this feature is there to assist us with the development, nothing stops us from manipulating it to make our app publically accessible. You could easily configure a public-facing Apache or Nginx server to act as a reverse-proxy to the app that runs on your local development environment. This approach doesn’t require you to run the build process as you had to do with the earlier method. For some reason, if you can’t run a development server with npm run serve command, you can manually implement similar functionality by installing and configuring npm serve package from the official npm package repository. That will come in handy if you have not used Vue CLI to generate your application.

Instead of relying on a traditional hosting set up such as Apache or Nginx, you can also serve your app through a node-based web application framework such as Express. The procedure is as simple as installing Express, creating a script that configures the server, and adding that script as the start script of your app’s package.json. This strategy requires you to run the build process. Once set up, your server script will run at the end of the build process and start serving your app from the configured port on your localhost. If you do this on a remote server (a machine other than your local pc) and if you’ve configured Express to serve from a publicly accessible port such as port 80, you’ll be able to view your app by visiting http(s)://your_server_ip with your browser. Also, if you’ve configured a domain name for your server, you can access the app by replacing your_server_ip with your domain.

Just as with every other software, there can be times when your server might crash that might result in your app becoming unavailable to its users. When that happens, you have to restart the server. When you serve your app using some NodeJS framework such as Express or reverse-proxying to a local server that runs on vue-cli-service or npm serve, the server functionality breaks as soon as you close your ssh session with the server. The solution for this problem is letting your npm command run in the background enabling it to keep serving the app even when you exit from your ssh session.

But what if the service stops abruptly at some point due to whatever reason? In such a scenario, you have no option but to re-establish an ssh connection to the server and restart the server manually. But this approach is not the best way to do it and will soon become tedious and cumbersome. What we need is a solution that can automatically restart the server when it fails. That way, the app will start working again without having to wait for manual intervention. That is a kind of situation where a solution called pm2 comes to rescue us. PM2 is a daemon process manager that will help you manage and keep your application online at all times. I’ll be covering the use of PM2 in a separate article later.

As an alternative approach to deploying an app on your own server, you can also deploy your app with the cloud application platform known as Heroku. Heroku is a platform as a service (PaaS) that enables developers to build, run and operate applications entirely in the cloud. It does offer a convenient free usage tier that is sufficient for most of the routine development tasks. Here, I am not going to guide you on how to use Heroku for deploying your application. If you are just getting started, Heroku provides documentation that should help you to understand all the basics you’ll ever need to know. Instead, I’d like to explain few interesting points that I thought will be useful for anybody who considers deploying their apps with this option.

First of all, if you want to deploy your Vue app with Heroku, you can do so by using Heroku’s Static CLI plugin. You can learn more about the Heroku Static CLI plugin by referring to the below links:

Alternatively, you don’t have to rely on the Static CLI plugin if you understand the process it takes to serve an app on Heroku. The rest of this article focuses on understanding those internal mechanics.

What is Heroku? Does Heroku provide a built-in web server?
It was an interesting question that I was curious about finding an answer. My point was if Heroku can serve up a static HTML page, then there got to be a web server already. If it can’t serve a static HTML page, it got to be just a barebone machine without a built-in web server.

Based on this assumption, I did some googling with the hope of finding a relevant answer. One of the sources explained; “Heroku only hosts and supports applications and not static pages, hence in order to deploy our untended static HTML page to Heroku, we need to trick Heroku a little into thinking that our website is some form of application, for example, PHP, NodeJS, etc.”

That was an okay answer. But I needed to find out more. Next, I came up with Heroku’s own documentation that probably explained it best on what’s going on out there. It said, “On Heroku, apps are completely self-contained and do not rely on runtime injection of a webserver into the execution environment to create a web-facing service. This is typically implemented by using dependency declaration to add a web server library to the app, such as Tornado for Python, Unicorn for Ruby, or Jetty for Java and other JVM-based languages.”

Based on those two explanations, now we know that Heroku doesn’t provide its own web server. Instead, we must integrate some form of web server implementation within our app so that it will be able to serve the app when deployed on a Heroku instance. If you have an app based on NodeJS, Python, Ruby, or Java, then that is the way to do it. However, for PHP apps, Heroku automatically launches an Apache webserver with built-in PHP support to serve your application. It is understandable because you can’t just ship Apache and PHP as libraries of your PHP application. There’s no way to do that.

Next, I wanted to find whether we can configure the port used to serve an app from Heroku. The below excerpt from StackOverflow seems to provide an answer.

“Heroku treats web apps just like any other app and doesn’t allow you to assign listening ports directly. Your web server will be assigned a dynamic port by Heroku but to ACCESS it, you will need to use the default port (80).”

There you go. That brings us to the conclusion that any app deployed on Heroku will be serving from port 80 regardless of which port we set in our web app’s configuration. It’s the platform that decides from which port to run the app. And we don’t have any control over that.

With all that understanding, it’s time to learn how to prepare an app so that Heroku can serve it properly when deployed. We’ve learned that Heroku doesn’t provide a built-in web server. The webserver must be a part of our app itself and, it should be able to serve from Heroku’s default port. A potential solution must satisfy all of those requirements. For our convenience, Heroku provides a sample app that we can use to learn how this whole thing works. If you could open below git repository and take a look at the script section of its package.json:

https://github.com/heroku/node-js-getting-started.git

You should see there is a start script to execute ‘node index.js‘ command.
That is an instruction to the npm build process to run index.js when the build process is completed. The index.js script is used to configure and start the webserver that will be serving our app. Typically and in this case, it is utilizing a popular NodeJS web application framework called Express.

Let’s go through the index.js functionality to understand what it does.

  • Line 1: Requires NodeJS ‘express‘ module. Express is a fast, and minimalist web framework that can serve our application.
  • Line 2: Requires NodeJS ‘path‘ module. That helps with resolving directory paths.
  • Line 3: Sets the PORT constant. That is how the server finds from which port to serve our application. process.env means the script is reading the PORT value from Heroku’s environment variables.
  • Line 5: express() initializes the express server instance
  • Line 6: The .use(express.static(path.join(__dirname, 'public'))) statements tell the server to serve static assets such as images, CSS, and Javascript files from a directory named public. If you go back to the repository you should see there is a directory named public. In it, there are some static assets such as images and stylesheets.
    Refer to: https://expressjs.com/en/starter/static-files.html
  • Line 7: The .set('views', path.join(__dirname, 'views')) statement sets where to find the templates. In this case, it’s a directory called views. If you go back to view the repository you could see the views directory exists.
  • Line 8: The .set('view engine', 'ejs') statement sets ‘ejs‘ as the template engine to use for the views.
    Refer to: https://expressjs.com/en/guide/using-template-engines.html
  • Line 9: The .get('/', (req, res) => res.render('pages/index')) statements tell the server to serve pages/index as the default route.
  • Line 10: In this final line the .listen(PORT, () => console.log(Listening on ${ PORT })) statement starts the server to listen on the PORT that was set in Line 3.

Additionally, there’s a Heroku specific configuration file named ‘Procfile‘ to configure the commands that will need to run once the build process is completed. If you open that file, you should see it contains commands similar to the start script of your package.json. However, it is not mandatory to have this file as long as you have correctly set the start script in your package.json.

This example repository confirms that we’ve got to integrate Express or some other similar web framework to serve our NodeJS application. Otherwise, there’s no built-in server in Heroku that can serve the app to the public. You can treat this sample repository as a starting point to integrate web serving capability into your apps.

That’s all there to it. I hope that the knowledge you’ve gained from this article will help you with your own projects.

Thanks for reading! 👋👋👋

Was this helpful?
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0