Search code examples
reactjsnginxherokubuildvite

Deploying Vite react project to Heroku using Nginx


I'm currently facing a challenge while trying to deploy my frontend web application to Heroku. This application is built using React and Vite. Initially, I encountered problems when attempting to build it using the latest Heroku stack (stack 22), which led me to switch back to Heroku stack 20 and utilize the heroku/nodejs buildpack in combination with the Heroku static buildpack from this repository: Heroku Buildpack Static.

This setup worked perfectly for several months, but now, I'm in a situation where I must upgrade to Heroku stack 22, and i was following the steps provided in this other thread, but it didnt work.

It seems that I'm still missing something, as the deployment process itself appears to be successful. However, when I access the deployed app, all I'm presented with is a 404 Not Found error page: enter image description here

I tried many different solutions already provided here at SO, to no success.

I removed all previous buildpacks and changed to https://github.com/heroku/heroku-buildpack-nginx. Then i updated my static.json file to this:

{
  "root": "./dist",
  "clean_urls": true,
  "routes": {
    "/**": "index.html"
  }
}

If i understood it correctly, it points to my root/dist folder. Then i run the "vite build" command to generate a new dist folder, which contains my built project source code.

Then i created the Procfile file on my root folder and added this line: web: bin/start-nginx-solo

Then i ran heroku run bash command to generate my nginx config file, which is:

daemon off;
# Heroku dynos have at least 4 cores.
worker_processes <%= ENV['NGINX_WORKERS'] || 4 %>;

events {
    use epoll;
    accept_mutex on;
    worker_connections <%= ENV['NGINX_WORKER_CONNECTIONS'] || 1024 %>;
}

http {
    gzip on;
    gzip_comp_level 2;
    gzip_min_length 512;
    gzip_proxied any; # Heroku router sends Via header

    server_tokens off;

    log_format l2met 'measure#nginx.service=$request_time request_id=$http_x_request_id';
    access_log <%= ENV['NGINX_ACCESS_LOG_PATH'] || 'logs/nginx/access.log' %> l2met;
    error_log <%= ENV['NGINX_ERROR_LOG_PATH'] || 'logs/nginx/error.log' %>;

    include mime.types;
    default_type application/octet-stream;
    sendfile on;

    # Must read the body in 5 seconds.
    client_body_timeout 5;

    upstream app_server {
        server unix:/tmp/nginx.socket fail_timeout=0;
    }

    server {
        listen <%= ENV["PORT"] %>;
        server_name _;
        keepalive_timeout 5;
        root /dist;

        location = /index.html {
            add_header Cache-Control "no-store, no-cache";
            try_files $uri $uri/ =404;
        }

        location / {
            add_header 'Cache-Control' "public, max-age=3600";
            try_files $uri $uri/ /index.html;
        }
    }
}

Then I created a config folder and added this config file inside, named it nginx.conf.erb, as instructed here.

My project folder structure looks like this:

enter image description here

Then i commited and pushed my changes to my github repository, which is connected to Heroku and automatically deploys my project if theres new commits. However, when i open the app, i only get the 404 error.

I think that the error is happening because heroku cant find my build folder with my index.html file, however, i already specified the path at static.json and on the nginx config file, so i dont know what else am i doing wrong.


Solution

  • I fixed it. Just in case someone else might need some help, those steps are correct, but I had to rebuild my project again with vite build and redeploy it. Also, I had the dist folder listed in my .gitignore file, so I removed it, and everything went well. Stupid mistake.