Skip to content

Deploy your Vite App with Docker on Heroku

Posted on:September 30, 2023 at 03:45 PM

Banner

Introduction

Since changing its pricing policy, Heroku has become less popular for providing side projects. However, it’s still a good platform for quick and easy application deployment. In this post, we’ll look at how to deploy a Vue.js application (this also works with React) using Vite and Docker on Heroku.

We won’t use a Node.js server to deploy the static files, but an nginx container.

I’ll use yarn as the package manager. You can also use npm or pnpm.

A link to a sample repository is available end of this post.

Create the Vite project

We need a project that uses Vite. For this, we’ll use the official Vite template.

yarn init vite@latest

Create the Dockerfile

In the project folder, we create a Dockerfile with the following content:

#./Dockerfile
FROM node:20 as build-stage
ARG PORT
WORKDIR /usr/src/app

COPY package*.json ./
COPY yarn.lock ./
COPY public ./public/
COPY index.html ./
COPY src ./src/
COPY *.mjs ./
COPY *.ts ./
COPY tsconfig.json ./
COPY tsconfig.node.json ./


RUN yarn install
RUN yarn run build

FROM nginx:1.25.2-alpine

COPY --from=build-stage /usr/src/app/dist/ /var/www/html/
COPY nginx/default.conf /etc/nginx/conf.d/default.conf

CMD sed -i -e 's/$PORT/'"$PORT"'/g' /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'

There are two stages:

Heroku dynamically binds the port on which the application listens. At build time, the nginx listen PORT is replaced with the port specified by Heroku. This is done in the last line of the Dockerfile. We’ll create the nginx configuration file a few steps later.

Create the heroku.yml file

The application is configured via a file heroku.yml, which is created in the root directory of the project with the following content:

#./heroku.yml
build:
  docker:
    web: Dockerfile

We specify that a “web” process should be created from the Dockerfile file.

Write the nginx configuration

We create an nginx folder and in it a file default.conf in the root directory of the project with the following content:

#./nginx/default.conf
    server {
        include /etc/nginx/mime.types;
        listen $PORT;

        if ($http_x_forwarded_proto != "https") {
            return 301 https://$host$request_uri;
        }

        location / {
            root /var/www/html;
            try_files $uri $uri/ /index.html;
            proxy_redirect     off;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }


        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        root /usr/share/nginx/html;
        }

    }

We configure nginx to listen on the port $PORT (replaced dynamically) and redirect all requests to index.html. We also redirect http requests to https.

Create and push the Heroku app

You can create the application via the website or via the command line interface. I prefer the command line. You may need to install Heroku CLI. To install, follow the instructions here.

heroku login
heroku container:login

heroku create <app-name>
heroku container:push web --app <app-name>
heroku container:release web --app <app-name>

And voila ! The application is deployed.

Deployed App Screenshot

Resources