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:
- The first involves installing the dependencies and building the application.
- The second involves copying the static files to the nginx container.
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.