diff --git a/README.md b/README.md index 29633cd..12e7c02 100644 --- a/README.md +++ b/README.md @@ -129,3 +129,7 @@ short, it was used for: Where AI contributed directly to a piece of code, there is a comment saying so, for example in [frontend/app/api/types/index.ts](frontend/app/api/types/index.ts) and [frontend/app/root.tsx](frontend/app/root.tsx). + +## Deployment + +For more details on deploying the solution on a VM, see the [deployment documentation](/docs/deployment.md). diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000..cfa5567 --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,167 @@ +# Deployment + +## Install dependencies + +Start by installing our dependencies: + +- Install [node 24](https://nodejs.org/en/download) +- Install [pnpm](https://pnpm.io/installation) +- Install [PostgreSQL 18](https://www.postgresql.org/download/) +- Install [pm2](https://pm2.keymetrics.io/) + +The binaries provided by PostgreSQL may not be added to path automatically. +If the commands `pg_ctl` and `initdb` fail, do the following: + +```sh +cd ~ +touch .profile +nano .profile +# And add the following line: PATH=$PATH:/usr/lib/postgresql/18/bin/ + +# Apply the changes +source .profile +``` + +## Clone the project and set it up + +Clone the project: + +```sh +git clone https://git.ntnu.no/IT2810-H26/T37-Project-2.git +cd T37-Project-2 +``` + +### Environment variables + +This step needs to be done only whenever environment variables are updated (`.env`). + +Set the correct environment values for the frontend: + +```sh +cd frontend +cp .env.example .env +nano .env # and change the VITE_API_URL +``` + +And do the same for the backend: + +```sh +cd backend +cp .env.example .env +nano .env # and change variables if needed +``` + +### Build the frontend + +Build the frontend, remove the old version and move the new content: + +```sh +cd frontend +pnpm build +sudo rm -rf /var/www/html/project2 +sudo cp -r build/client/ /var/www/html/project2 +``` + +> [!CAUTION] +> We only move the `client/` folder from the build! +> We do not use React Router's server-side functionality, because our frontend does not use server-side rendering (SSR). +> See [react-router.config.ts](./frontend/react-router.config.ts) + +The move must be executed as sudo because the `/var` folders are owned by `root`. + +### Building the backend + +Build the backend like so: + +```sh +cd backend +pnpm build +``` + +### Prepare the database + +We need the seed book data file. +For more details, please check the [backend README.md](./backend/README.md). + +Let's download the dataset, unzip and place it in the correct folder: + +```sh +curl -L -o comprehensive-literary-greats-dataset.zip https://www.kaggle.com/api/v1/datasets/download/thedevastator/comprehensive-literary-greats-dataset +unzip comprehensive-literary-greats-dataset.zip +# After unzipping, a file named "books_1.Best_Books_Ever.csv" will be placed +# in the current working directory. + +mv books_1.Best_Books_Ever.csv ./backend/src/db/seed/book-data.csv +rm comprehensive-literary-greats-dataset.zip +``` + +Set up the database as usual: + +```sh +cd backend +pnpm db:setup +``` + +> [!NOTE] +> If you receive permission errors, add your user to the `postgres` group by running the following command: +> `sudo usermod -aG postgres $USER` + +## Running the project + +The frontend is already handling by the Apache web server by being placed in `/var/www/html/project2`. + +In order to run the backend, we use `pm2`. + +The first time project is run: + +```sh +cd backend +pm2 start --name "backend" --interpreter="/bin/bash" pnpm -- start +``` + +Afterwards, after changing the backend and building it, it's enough to restart it: + +```sh +# This command can be done in any directory on the machine! +pm2 restart backend +``` + +## Our VM setup + +This is what is set up on our VM (`it2810-37.idi.ntnu.no`, Ubuntu 26.04). +Apache was already installed and running. + +### Installed packages + +```sh +# Node 24 from NodeSource +curl -fsSL https://deb.nodesource.com/setup_24.x | sudo bash - +sudo apt install -y nodejs + +# pnpm, installed globally +sudo npm install -g pnpm@12 + +# PostgreSQL 18 +sudo apt install -y postgresql +``` + +### Apache config for client-side routes + +React Router handles routes like `/project2/book/5` in the browser. Without +this config, opening such a URL directly or reloading the page gives a 404, +because Apache looks for a file with that path. `FallbackResource` makes +Apache serve `index.html` instead, so the app can load and show the right page. +It only applies to the `project2` folder. + +```sh +sudo tee /etc/apache2/conf-available/project2.conf > /dev/null <<'CONF' + + FallbackResource /project2/index.html + +CONF +sudo a2enconf project2 +sudo apache2ctl configtest # should print "Syntax OK" +sudo systemctl reload apache2 +``` + +This was only done once, and should only need to be run once. diff --git a/frontend/.env.example b/frontend/.env.example new file mode 100644 index 0000000..019061c --- /dev/null +++ b/frontend/.env.example @@ -0,0 +1,2 @@ +# Must be changed to http://it2810-37.idi.ntnu.no:3001/ for production +VITE_API_URL = http://localhost:3001 diff --git a/frontend/app/root.tsx b/frontend/app/root.tsx index 4a24668..90cdb98 100644 --- a/frontend/app/root.tsx +++ b/frontend/app/root.tsx @@ -18,7 +18,9 @@ import { TooltipProvider } from "~/components/ui/Tooltip"; // Created outside the component tree so the cache survives re-renders. const apolloClient = new ApolloClient({ - link: new HttpLink({ uri: "http://localhost:3001/" }), + link: new HttpLink({ + uri: (import.meta.env.VITE_API_URL as string) || "http://localhost:3001/", + }), cache: new InMemoryCache(), }); @@ -36,21 +38,24 @@ export function Layout({ children }: { children: React.ReactNode }) { + -