-
Node.js: Install the latest version of Node.js (v22.x recommended).
-
Docker: Required for containerization (optional if running locally or directly).
-
Firebase: Set up a Firebase project, enabling Firestore and Firebase Authentication.
$ git clone <repository-url>
$ cd <project-folder>
Create a .env file for both backend and frontend to store sensitive data.
Backend .env:
# General
NODE_ENV=development
PORT=3001
CORS_ORIGIN=http://localhost:3000
# SSL Certificates
SSL_KEY_PATH=
SSL_CERT_PATH=
# Firebase Admin SDK (see docs for more info)
TYPE=
PROJECT_ID=
PRIVATE_KEY_ID=
PRIVATE_KEY=
CLIENT_EMAIL=
CLIENT_ID=
AUTH_URI=
TOKEN_URI=
AUTH_PROVIDER_X509_CERT_URL=
CLIENT_X509_CERT_URL=
UNIVERSE_DOMAIN=
General
NODE_ENV
--> production or developmentPORT
--> whatever port you're running the backend server onCORS_ORIGIN
--> whitelisting who can call the API
In development env, you can leave the ssl paths blank.
Firebase Admin SDK:
- Generate a service account key for Firebase access via Firebase Admin SDK
- Go to your Firebase Project Settings
- Navigate to the
Service accounts
tab - Click
Generate new private key
- This should download a JSON file containing the service account key
- Copy all of the information to the env file
Frontend .env:
VITE_APP_BACKEND_SERVER_URL=http://localhost:3001
VITE_APP_FIREBASE_AUTH_API_KEY=
VITE_APP_FIREBASE_AUTH_DOMAIN=
VITE_APP_FIREBASE_AUTH_PROJECT_ID=
VITE_APP_FIREBASE_AUTH_STORAGE_BUCKET=
VITE_APP_FIREBASE_AUTH_MESSAGING_SENDER_ID=
VITE_APP_FIREBASE_AUTH_APP_ID=
VITE_APP_FIREBASE_AUTH_MEASUREMENT_ID=
VITE_APP_BACKEND_SERVER_URL
--> the url for the backend server. Used to send API requests to the backend from the frontend.- The rest can be found by going to your Firebase Project settings:
- Navigate to
SDK setup and configuration
- Clicking the
Config
radio button. - Copy the values from the firebaseConfig object to the .env file
- Navigate to
Backend
$ cd backend
$ npm install
$ dotenvx run -- npm start
Frontend/Client
$ cd client
$ npm install
$ npm start
The repository contains Dockerfiles for both client and backend.
- AWS EC2 instance or whatever you're deploying on
- A custom domain
- Clone the repo on the host server
- Basic Docker Knowledge
- Basic vim knowledge. Here's a good cheat sheet
Connecting to your EC2 instance
Once you create your EC2 instance, you need to SSH into it in order to access the VM's terminal remotely:
- Open Windows Powershell
- Type
ssh
to verify ssh command exists. If it doesn't then you need to install an SSH client like OpenSSH or use WSL - Go to your EC2 instance on amazon. Select it and click
connect
. Navigate to theSSH client
screen. - Copy the script in the
example
.
Some Debugging:
-
If you run into any issues in this process, this might help.
-
You might need to add an Inbound rule on your EC2 instance on Port 22. Do one for your own IP address and then another two for the ones with "instance-connect" in the "prefixes list". So three rules total.
-
I ran into permission issues regarding the
.pem
file. I found this StackExchange post from 13 years ago to be helpful.
Install Docker and Docker Compose
Follow this to install Docker on Linux.
Follow this to install Docker Compose.
Make sure you're installing docker compose
and not docker-compose
as in, when you type the command, it should look like "docker compose" and not "docker-compose".
Clone the Repository
$ git clone <repository-url>
$ cd <project-folder>
Basic Setup - Enviornment Variables
This guide assumes that you have bought your domain, but have not set up SSL to enable HTTPS. We'll be walking through that process later in the guide. Just make sure to have that URL ready as we're going to use it in the enviornment variables
The enviornment variables that would be traditionally (in a local enviornment) be an .env
are in the compose.yaml
file under args
. I've created a compose.yaml
. Fill in your details.
The setup is similar to the setup previously described in the local enviornment variables setup except:
- You're going to be using the http version of your domain (and no port number) instead of localhost:port.
HTTP Setup - Backend Server
In order to have HTTPS, we need to get an SSL certificate. We can't do that unless we have HTTP running properly. The code is different for HTTP and HTTPS and the current code is for HTTPS, not HTTP.
- Set the enviornment in compose.yaml in the backend to
development
this will enable HTTP.
HTTP Setup - Nginx Configuration
The current configuration is for HTTPS, which is on PORT 443 by default. However, port 80, which is the default for HTTP is what we need to use.
- Go to
client/nginx.conf
- Delete everything
- Replace it what is in
documentation/pre-ssl-cert-gen/client/nginx.conf
- ! Important ! - Replace my
server_name
with yours
Basically the nginx configuration is acting as a router, telling all requests on port 80 to go where they need to go.
HTTP Setup - Docker Configuration
- Go to
client/Dockerfile
and delete theCOPY certbot_renew /etc/crontabs/root
line. We'll add that back after we add the SSL certification. - Go to
compose.yaml
in the root directory. - Change
https
tohttp
in theargs
for bothCORS_ORIGIN
andVITE_APP_BACKEND_SERVER_URL
HTTP Setup - Build and Start Docker Images
$ docker compose up --build -d
Verify Containers are Running
There should be two containers running.
$ docker ps
If there aren't, then there was an error. You need to check the logs:
docker logs [container-name]
Verify Inbound Rules on EC2 Instance Make sure you have an inbound rule for the AWS EC2 instance for HTTP on port 80 from anywhere (we're going to a request from the Let's Encrypt CA for SSL certification, so don't do it only for your IP)
Point your domain name to your EC2 instance
If you're using Cloudflare (you can use anything) you can follow these steps:
- Go to your custom domain
- Navigate to
DNS
- Click
Add Record
- Add an
A
record with the@
for a root domain (ex. @ for ajitm.com) or the actual subdomain (ex. wonderquest for wonderquest.ajitm.com) - Enter in the public IPv4 address of your EC2 instance
- Disable the proxy (for now, you should be able to enable it later).
Verify HTTP website
Go to the HTTP version of your domain (ex. http://wonderquest.ajitm.com vs https://wonderquest.ajitm.com). If you've done this multiple times now, the browser might have cached your website, so you might want to try clearing cache or using incognito mode.
Test all functionality (using dummy data). Make sure both frontend and backend are working. You can do this while inspecting the console and the network tab for any errors.
Errors will likely be due to due a misconfiguration in the nginx config, compose.yaml, or ec2 inbound rules. If everything works fine, move onto the next step.
Get the SSL Certificate
At this point, both of your containers should be running fine. If they're not you need to get them running.
Once both are running and you've verified that the domain is up. Type the following in the command line:
$ docker exec -it [FRONTEND CONTAINER NAME] certbot --nginx -d [YOUR DOMAIN] --non-interactive --agree-tos -m [YOUR EMAIL]
Your frontend container name should be: auto_kanban-frontend-1
, but just double check you're using the command on the frontend docker.
You should not get any errors. If you do, fix that first before moving on.
Verify SSL Certificate
The SSL certificate should exist on the EC2 instance itself. Exit the docker container's command line by typing exit
and cd to the following directory.
$ cd ~
$ cd ../../etc/letsencrypt
$ sudo -s
$ cd live
$ ls
$ exit
You should see your domain name as a folder. If that exists, you're good, everything worked properly. Now we're going to enable the configuration for https
HTTPS Setup - Backend Server
Now that we have an SSL certification, we can run HTTPS. Let's set that up.
- Navigate back to your project directory
- Run
docker compose down
- Change the compose.yaml node enviornment to
production
- Remember to change the domain to https: your domain in the compose yaml file.
HTTPS Setup - Nginx Configuration
The current configuration is for HTTPS, which is on PORT 443 by default. However, port 80, which is the default for HTTP is what we need to use.
- Go to
client/nginx.conf
- Delete everything
- Replace it with what it was originally. You can find that on the GitHub repo
- ! Important ! - Replace all of the [YOUR-DOMAIN] with your domain.
Basically the nginx configuration is acting as a router. It's telling all requests on port 80 (except the SSL challenge) to redirect to HTTPS (port 443). On port 443, redirect to respective places with https.
HTTPS Setup - Docker Configuration
- Go to
client/Dockerfile
and add theCOPY certbot_renew /etc/crontabs/root
line back in. - Go to
compose.yaml
in the root directory. - Change
http
tohttps
in theargs
for bothCORS_ORIGIN
andBACKEND_SERVER_URL
HTTPS Setup - Build and Start Docker Images
$ docker compose up --build -d
Verify Containers are Running
$ docker ps
There should be two containers running. If there aren't, then there was an error. You need to check the logs:
docker logs [container-name]
Verify Inbound Rules on EC2 Instance
Make sure you have an inbound rule for HTTP on port 443 from anywhere.
Verify HTTPS website
Go to the HTTPS version of your domain. If you've done this multiple times now, the browser might have cached your website, so you might want to try clearing cache or using incognito mode. Test all functionality (using dummy data). Make sure both frontend and backend are working. You can do this while inspecting the console and the network tab for any errors.
Errors will likely be due to due a misconfiguration in the nginx config, compose.yaml, or ec2 inbound rules. If everything works fine, move onto the next step.
Firebase Auth Issues
If Google Sign-In isn't working, that's an issue with Firebase Authentication:
- Go to your
Firebase Authentication
- Navigate to
Settings
- Click the
Authorized Domains
tab - Add your domain to this list. You can also add your public server IP address too, if you want.