COMP3900/9900 26T3 notice: This is an optional individual exercise. It does not contribute to the final course mark and there is no submission deadline. Use it to practise the technical skills needed for the team project.
This primer combines basic Docker, Git/GitLab, and Python skills in one mini-project.
You do not need to master these tools before starting.
If any of them are new to you, use these official introductions as needed:
-
Install Docker
Download and install from https://docs.docker.com/get-docker/
Ensure Docker is running whenever you are developing, this has been tested with the latest version of Docker Desktop (4.60.1) -
Clone this repo
If you have not used Git before, refer to the Git primer. -
Use your own GitLab repo for practice
- Create a private repo (e.g.
student-grading-primer) on your GitLab account. Do not fork this repo. - Clone this (course) repo, then point the remote to your repo:
git remote set-url origin git@gitlab.cse.unsw.edu.au:YOUR_USERNAME/YOUR_REPO_NAME.git
- Run
git pushso your repo has the starter code. You will work in this repo for the rest of the exercise.
Note: Do not clone and work on your private repo, all changes should be made from the course primer you have cloned, and pushed remotely to your private repo.
- Create a private repo (e.g.
You must complete the docker-compose.yml file. A mock SQL database has been provided at ./db/init.sql. We need to initialise this in our docker container and mount it to a persistent volume.
Requirements:
- Configure the backend and frontend based on the provided ports in the
running the applicationsection
The backend service is currently a stub. You need to complete it so the backend container builds, runs, and can connect to the database.
- The backend reads connection parameters from environment variables (see
backend/db.pyfor the exact names)
Hint #1:
Running the backend container will depend on the db. Check what environment variables are required to connect to the db, as these will be required when initialising the db.
Hint #2:
The DB_HOST should be "db", the rest of these environment variables should match the credentials for the db service.
The frontend service is currently a stub. Complete it so the frontend builds and runs correctly on the port 8080.
Hint #1:
Check the Frontend dockerfile to see what port the service is running on. You may notice this is different to the expected port 8080. We need to map these ports in the docker compose file.
-
Add the pre-seed script (
./db/init.sql) so the database is initialised on the first-build of the container. This should be mounted to/docker-entrypoint-initdb.d/(PostgreSQL container's initialisation directory) -
Add a volume so the database’s data persists when the container is recreated.
Hint #1:
In our compose file, we can define a volume under the db service and map the pre-seed script to a file in the provided database initialisation directory ie. /docker-entrypoint-initdb.d/init.sql
Hint #2:
To make data persistent, we need to create a named volume for the service and map this volume to the SQL data directory. Refer to the linked resources to see how this is done.
To run the app, execute this command:
docker compose up --buildCheck the links in running the application work, and that the data persists when creating a student and restarting the application
Note: It is normal to see errors in the backend at this stage as the function stubs have not been implemented. On build however after adding the init.sql script you should see this line:
db-1 | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
If you do not see this, you may need to delete the container and re-build as it may have already mounted to the initialisation directory on a prior buid.
Implement the backend from the provided stubs. Each route in backend/app.py is a stub with instructions.
Do not modify backend/db.py. You are provided with abstract methods to fetch and insert data into the DB. ie. get_all_students(), get_student_by_id(id), insert_student(name, course, mark), etc.
The requirement is that all data is persistent. You can utilise additional data structures/methods to achieve this.
You must also add error handling where appropriate. For simplicity all errors will return a 404 code, and success will return 200.
- GET /students — Fetch all students from the database and return as JSON.
- POST /students — Creates a student with
name,course, optionallymark. Return the created student and status 200 - PUT /students/{id} — Update the student details. Return 404 if the id does not exist
- DELETE /students/{id} — Delete the student. Return 404 if student not found.
- GET /stats — Return
count,average,min,maxof all student marks.
The spec is deliberately abstract: you choose validation rules, error messages, and use any additional data structures/methods. Implement each stub so the API is consistent and data is persistent via the db module.
Identify one edge case not fully specified in the primer spec, and document in EDGE_CASE.md how you chose to handle it and why.
- Run:
docker compose up --build - Run the supplied check:
docker compose --profile debug up --build automark - You should see
SANITY CHECK PASSED. - The supplied checks cover only the basic behaviour, so test your validation and error handling separately.
Your friend Eric has volunteered to implement the Frontend for your /stats endpoint. Upon merging his changes, you run into some merge conflicts and discover some unsafe git practices.
Create a new branch named docker_and_backend, and commit and push your changes from Part 1 & Part 2.
Ensure your commit message is meaningful ie. feat: Initialise docker from pre-seed script and implement function stubs
git checkout -b docker_and_backend
... commit and push your changesDo not merge this branch into main. Push your branch to the remote.
If you are unsure about how to do any of these steps, refer to the git primer.
Eric's changes are located on branch eric/stats-feature, merge these changes into the docker_and_backend branch and resolve any merge conflicts.
While you are merging the changes, you notice there are a couple of typos in the frontend as the button says add tutor and the table says tutor rather than students.
You should fix these typos located in frontend/src/App.jsx (Do NOT commit/push your changes at this stage!!)
Note: Upon completion, there should not be any merge conflict markers (<<<<<<<, =======, >>>>>>>).
While merging, you realise that Eric has accidentally merged a .env file containing a secret. You must remove it from the staged changes and ensure it is not commited!
To do so, you first run:
git rm --cached .envCreate a .gitignore file in the project root that excludes .env (and optionally other files like node_modules). Then:
git add .gitignore
git commit -m "chore: Fix typo and remove .env from repo and add .gitignore"Note: You can use a conventional commit style message to increase readibility in your commits.
Push your changes to the remote branch, and open a pull request for both your branches on GitLab.
Do NOT merge the pull request.
Keep it open so you can inspect the proposed changes and ask your tutor for help if needed.
From the project root:
docker compose up --build- Frontend: http://localhost:8080
- Backend: http://localhost:5000
- Health: http://localhost:5000/
- Students: http://localhost:5000/students
- Stats: http://localhost:5000/stats
At any time after Part 2, you can run the public tests:
docker compose --profile debug up --build automark --remove-orphansYou must see SANITY CHECK PASSED. These tests check: backend health, database connectivity, list of students, /stats response shape, and that creating a student persists.
These are only basic checks.
Add your own tests for validation, error handling, and edge cases.