Skip to content

Commit 44fdbde

Browse files
authored
House keeping (#16)
* update frontend dependencies. Update eslint and tsconfig * update backend dependencies * add ruff and mypy * fix some ruff issues (sorting) * fix ruff issues * update config * fix mypy errors * fix mypy issues * fix frontend lint issues * fix security issue with fast-api-sso * add pre-commit config file * remove facebook sso * remove deprecated Grid component. Use Grid2 instead * fix tests by changing testing api url * update node and mongodb versions in tests workflow * make black use pyproject.toml in github actions * Add config to black * change working dir for python lint * refactor docker-compose setup. Update traefik to v3.2 * add docker watch for frontend container * add node_modules ignore to docker watch * refactor config to use root level .env file * update docker doc in README
1 parent 12461de commit 44fdbde

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+3249
-5376
lines changed

.env

+22-19
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,44 @@
1+
### Domain name for the app
12
DOMAIN=localhost
23

4+
### Environment: development, test, production
5+
ENVIRONMENT=development
6+
7+
### Project name and stack name
8+
PROJECT_NAME=farm-docker
39
STACK_NAME=farm-docker
410

5-
TRAEFIK_PUBLIC_NETWORK=traefik-public
6-
TRAEFIK_TAG=farm-docker
7-
TRAEFIK_PUBLIC_TAG=traefik-public
8-
TRAEFIK_PUBLIC_NETWORK_IS_EXTERNAL=false
11+
### Email adress used by traefik to obtain Let's Encrypt certificates
912
TRAEFIK_TLS_EMAIL=[email protected]
1013

14+
### Docker package registry and images
1115
DOCKER_IMAGE_BACKEND=farmd-backend
1216
DOCKER_IMAGE_FRONTEND=farmd-frontend
1317
DOCKER_PACKAGE_REPOSITORY=ghcr.io/jonasrenault
1418

15-
# Backend
16-
BACKEND_CORS_ORIGINS=["http://localhost", "http://localhost:5173", "http://localhost:3000", "http://localhost:8080", "https://localhost", "https://localhost:5173", "https://localhost:3000", "https://localhost:8080", "http://dev.farm-docker.com", "https://stag.farm-docker.com", "https://farm-docker.com"]
17-
PROJECT_NAME=farm-docker
19+
### Backend variables
20+
BACKEND_CORS_ORIGINS=["http://localhost", "http://localhost:5173", "https://localhost", "https://localhost:5173"]
1821
SECRET_KEY=98153798f1616ba9e65c2cbcdb3fd3e3a6297b2002f6936b72823fd21ce609d9
1922
FIRST_SUPERUSER=[email protected]
2023
FIRST_SUPERUSER_PASSWORD=admin
2124

25+
### SSO variables
2226
GOOGLE_CLIENT_ID=
2327
GOOGLE_CLIENT_SECRET=
24-
FACEBOOK_CLIENT_ID=
25-
FACEBOOK_CLIENT_SECRET=
26-
# HOSTNAME used to build google redirect uri. Should point to backend
27-
SSO_CALLBACK_HOSTNAME=http://localhost
28-
# Callback URL we redirect to after google login. Should point to frontend/sso-login-callback
29-
SSO_LOGIN_CALLBACK_URL=http://localhost/sso-login-callback
30-
31-
# Frontend
28+
### HOSTNAME used to build google redirect uri. Should point to backend
29+
SSO_CALLBACK_HOSTNAME=http://localhost:8000
30+
### Callback URL we redirect to after google login. Should point to frontend/sso-login-callback
31+
SSO_LOGIN_CALLBACK_URL=http://localhost:5173/sso-login-callback
32+
33+
### Frontend variables
3234
VITE_BACKEND_API_URL=http://localhost/api/v1/
3335
VITE_PWD_SIGNUP_ENABLED=true
3436
VITE_GA_TRACKING_ID=
3537

36-
# MongoDB
37-
MONGO_HOST=db
38+
### MongoDB variables
39+
MONGO_HOST=localhost
3840
MONGO_DB=farmd
3941
MONGO_PORT=27017
40-
MONGO_USER=mongodbadmin
41-
MONGO_PASSWORD=wpnimdabdognom
42+
# uncomment following lines to set mongodb user and password
43+
# MONGO_USER=mongodbadmin
44+
# MONGO_PASSWORD=wpnimdabdognom

.github/workflows/test.yml

+7-5
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ on:
1313
- main
1414

1515
env: # environment variables (available in any part of the action)
16-
NODE_VERSION: 20
17-
PYTHON_VERSION: 3.11
18-
MONGODB_VERSION: 6.0
16+
NODE_VERSION: 21
17+
PYTHON_VERSION: 3.12
18+
MONGODB_VERSION: 8.0
1919

2020
jobs:
2121
run-js-linters:
@@ -33,7 +33,7 @@ jobs:
3333
uses: actions/setup-node@v4
3434
with:
3535
node-version: ${{ env.NODE_VERSION }}
36-
cache: 'npm'
36+
cache: "npm"
3737
cache-dependency-path: frontend/package-lock.json
3838

3939
- name: Install Node.js dependencies
@@ -55,6 +55,8 @@ jobs:
5555

5656
- name: Run black
5757
uses: psf/black@stable
58+
with:
59+
options: "--config backend/pyproject.toml"
5860

5961
test-backend:
6062
name: Run backend unit tests
@@ -75,7 +77,7 @@ jobs:
7577
uses: actions/setup-python@v4
7678
with:
7779
python-version: ${{ env.PYTHON_VERSION }}
78-
cache: 'poetry'
80+
cache: "poetry"
7981

8082
- name: Start MongoDB
8183
uses: supercharge/[email protected]

.pre-commit-config.yaml

+39-25
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,40 @@
1+
default_language_version:
2+
python: python3.12
3+
14
repos:
2-
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v4.3.0
4-
hooks:
5-
- id: trailing-whitespace
6-
- id: end-of-file-fixer
7-
- id: check-yaml
8-
- id: debug-statements
9-
- repo: https://github.com/psf/black
10-
rev: 23.10.1
11-
hooks:
12-
- id: black
13-
# It is recommended to specify the latest version of Python
14-
# supported by your project here, or alternatively use
15-
# pre-commit's default_language_version, see
16-
# https://pre-commit.com/#top_level-default_language_version
17-
language_version: python3.11
18-
- repo: https://github.com/python-poetry/poetry
19-
rev: '1.5.1'
20-
hooks:
21-
- id: poetry-check
22-
args: ["--directory", "backend"]
23-
- id: poetry-lock
24-
args: ["--directory", "backend"]
25-
- id: poetry-export
26-
args: ["-f", "requirements.txt", "-o", "backend/requirements.txt", "--directory", "backend", "--with", "dev"]
5+
- repo: https://github.com/pre-commit/pre-commit-hooks
6+
rev: v4.6.0
7+
hooks:
8+
- id: check-added-large-files
9+
- id: check-toml
10+
- id: check-yaml
11+
args: [--allow-multiple-documents]
12+
- id: end-of-file-fixer
13+
- id: trailing-whitespace
14+
15+
- repo: https://github.com/psf/black
16+
rev: 24.8.0
17+
hooks:
18+
- id: black
19+
name: black
20+
args:
21+
- "--config"
22+
- "./backend/pyproject.toml"
23+
24+
- repo: https://github.com/astral-sh/ruff-pre-commit
25+
rev: v0.6.9
26+
hooks:
27+
# Run the linter.
28+
- id: ruff
29+
# Run the formatter.
30+
- id: ruff-format
31+
32+
- repo: https://github.com/pre-commit/mirrors-mypy
33+
rev: v1.11.2
34+
hooks:
35+
- id: mypy
36+
name: mypy
37+
args:
38+
- "--config"
39+
- "./backend/pyproject.toml"
40+
- "--ignore-missing-imports"

README.md

+10-28
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ To run the application manually in a terminal, see both the [backend](backend/RE
3030

3131
## Running the application with Docker
3232

33-
The project contains Docker configuration files to run the application with Docker compose. Two docker-compose files are provided with configuration for `dev` and for `production` environments. The Docker configuration is largely adapted from Tiangolo's [Full stack FastAPI cookiecutter](https://github.com/tiangolo/full-stack-fastapi-postgresql) project.
33+
The project contains Docker configuration files to run the application with Docker compose. Two docker-compose files are provided with configuration for `dev` and for `production` environments. The Docker configuration is largely adapted from Tiangolo's [Full stack FastAPI template](https://github.com/fastapi/full-stack-fastapi-template) project.
3434

3535
### Local development with Docker
3636

@@ -39,16 +39,14 @@ The local development file for docker is [docker-compose.yml](./docker-compose.y
3939
Start the stack with Docker Compose:
4040

4141
```bash
42-
docker compose up -d --build
42+
docker compose watch
4343
```
4444

45-
The `--build` arg can be omitted after the images have been built at least once.
46-
47-
Now you can open your browser and interact with these URLs:
45+
You can then open your browser and interact with these URLs:
4846

4947
* Frontend, served with vite with hot reload of code: http://localhost
5048

51-
* Backend, JSON based web API based on OpenAPI, with hot code reloading: http://localhost/api/
49+
* Backend, JSON based web API based on OpenAPI, with hot code reloading: http://localhost/api/v1
5250

5351
* Automatic interactive documentation with Swagger UI (from the OpenAPI backend): http://localhost/docs
5452

@@ -68,30 +66,12 @@ To check the logs of a specific service, add the name of the service, e.g.:
6866
docker compose logs backend
6967
```
7068

71-
### Docker Compose settings for development
72-
73-
When running the application with docker in development, both the frontend and backend directories are mounted as volumes to their corresponding docker containers to enable hot reload of code changes. This allows you to test your changes right away, without having to build the Docker image again. It should only be done during development, for production you should build the Docker image with a recent and stable version of the code.
74-
75-
For the backend, there is a command override that runs `/start-reload.sh` (included in the base image) instead of the default `/start.sh` (also included in the base image). It starts a single server process (instead of multiple, as would be for production) and reloads the process whenever the code changes. Have in mind that if you have a syntax error and save the Python file, it will break and exit, and the container will stop. After that, you can restart the container by fixing the error and running the `docker-compose up -d` command again. The backend [Dockerfile](backend/Dockerfile) is in the backend directory.
76-
77-
For the frontend, when in development, the frontend docker container starts with the `npm run dev -- --host` command, while in production the frontend app is built into static files and the app is served by an nginx server. The [nginx configuration file](frontend/nginx.conf) is in the frontend dir.
78-
79-
### Accessing the containers
80-
81-
To get inside a container with a `bash` session you can start the stack with:
82-
83-
```console
84-
$ docker compose up -d
85-
```
86-
87-
and then `exec` inside the running container:
69+
To get access to a bash session inside a container (e.g. the `backend`):
8870

8971
```console
9072
$ docker compose exec backend bash
9173
```
9274

93-
This will give you access to a bash session in the `backend` container. Change the name of the container to the one you want to access.
94-
9575

9676
### Docker Compose settings for production
9777

@@ -103,13 +83,15 @@ docker compose -f docker-compose.prod.yml up -d
10383

10484
**Note:** This will not work out of the box, mainly because the `docker-compose-prod.yml` configures a traefik proxy with ssl enabled that will try to fetch ssl certificates from Let's Encrypt, which will not work unless you specify a valid hostname accessible on the internet. However, to deploy the application in production on a server, you only need to set the required env variables in the [.env](./.env) file.
10585

86+
When using the production configuration, the frontend app is built into static files and the app is served by an nginx server. The [nginx configuration file](frontend/nginx.conf) is in the frontend dir.
87+
10688
### Docker Compose files and env vars
10789

10890
Both the [docker-compose.yml](./docker-compose.yml) and [docker-compose-prod.yml](./docker-compose.prod.yml) files use the [.env](./.env) file containing configurations to be injected as environment variables in the containers.
10991

110-
The docker-compose files are designed to support several environments (i.e. development, building, testing, production) simply by setting the appropriate variable values in the `.env` file.
92+
The docker-compose files are designed to support several environments (i.e. development, testing, production) simply by setting the appropriate variable values in the `.env` file.
11193

112-
The [.env](./.env) file contains all the configuration variables. The values set in the `.env` file will override those that are set in the frontend and backend `.env` files for local development. For exemple, the backend app also has a [.env.dev](backend/.env.dev) file which is read to populate the backend's [config](backend/app/config/config.py) module. When the application is run with docker though, the env variables in the projet root's [.env](./.env) file will override the env variables set in the backend and frontend's respective .env files. In order to be able to keep working both with docker and manually, you only have to make sure that the required variables are set both in the root `.env` file, and in the backend and frontend `.env` files.
94+
The [.env](./.env) file contains all the configuration variables. The values set in the `.env` file will override those that are set in the frontend `.env` files for local development.
11395

11496
The `.env` file that is commited to the github repository contains example values which are ok to use for testing and development, but which should be changed when running the application in production (admin passwords, secret keys, client ids, etc.). During deployment in production, the .env file is replaced with one containing the appropriate values.
11597

@@ -119,7 +101,7 @@ To setup SSO and enable the `Sign-In with Google` button, you must first obtain
119101

120102
Create a new project, and from the `APIs & Services` menu, first create an `OAuth consent screen` for you application, then add an `OAuth 2.0 Client Id` in the `Credentials` menu. Select `Web application` as the application type. In the `Authorized redirect URIs`, add your hostname with the `api/v1/login/google/callback` endpoint. For instance, if testing locally while running the backend app with `uvicorn`, add `http://localhost:8000/api/v1/login/google/callback` (use `http://localhost/api/v1/login/google/callback` if running the application in dev with docker). If your application is hosted on a domain name, add it to the list of URIs (remember to update `http` to `https` when using SSL).
121103

122-
Once you've create a client-id and token in your Google cloud console, copy those into your `.env` file's (either directly in the backend [.env](./backend/.env.dev) or in the root [.env](./.env) if using docker) `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` variables.
104+
Once you've create a client-id and token in your Google cloud console, copy those into your `.env` file's `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` variables.
123105

124106
## Setting up automatic build of the docker images in github
125107

backend/.dockerignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Python
2+
__pycache__
3+
app.egg-info
4+
*.pyc
5+
.mypy_cache
6+
.pytest_cache
7+
.ruff_cache
8+
.coverage
9+
htmlcov
10+
.venv

backend/.env.dev

-25
This file was deleted.

backend/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,5 @@ cython_debug/
158158
# and can be added to the global gitignore or merged into this file. For a more nuclear
159159
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
160160
#.idea/
161+
162+
.ruff_cache

backend/Dockerfile

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
FROM tiangolo/uvicorn-gunicorn-fastapi:latest
1+
FROM python:3.12-slim
2+
23
ENV PYTHONUNBUFFERED=true
4+
35
WORKDIR /app
46

5-
ENV POETRY_HOME=/opt/poetry
6-
# ENV POETRY_VIRTUALENVS_IN_PROJECT=true
7-
ENV PATH="$POETRY_HOME/bin:$PATH"
8-
RUN curl -sSL https://install.python-poetry.org | python3 -
9-
RUN poetry config virtualenvs.create false
10-
# Copy poetry.lock* in case it doesn't exist in the repo
11-
COPY ./pyproject.toml ./poetry.lock* /app/
7+
### install poetry
8+
RUN pip install poetry && poetry config virtualenvs.in-project true
9+
10+
### install dependencies and project
11+
ADD pyproject.toml README.md ./
12+
ADD app /app/app
13+
RUN poetry install --no-interaction --no-ansi
1214

13-
# Allow installing dev dependencies to run tests
14-
ARG INSTALL_DEV=false
15-
RUN bash -c "if [ $INSTALL_DEV == 'true' ] ; then poetry install --no-root ; else poetry install --no-root --no-dev ; fi"
15+
### add executables to path
16+
ENV PATH="/app/.venv/bin:$PATH"
1617

17-
COPY . /app
18-
ENV PYTHONPATH=/app
18+
### default cmd: run fastapi with 4 workers
19+
CMD ["fastapi", "run", "--workers", "4", "app/main.py"]

backend/README.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@ This directory contains the backend API app. It is built with [FastAPI](https://
99

1010
## Install
1111

12-
The project uses poetry to manage dependencies. You can use your own environment, or use poetry to manage the virtuel env and the project depencencies.
12+
The project uses poetry to manage dependencies and run the backend application. You can use an other tool to manage your virtual environment, such as `pip` or [uv](https://docs.astral.sh/uv/), but you'll need to extract the dependencies from the [pyproject.toml](./pyproject.toml) file.
1313

1414
If using poetry, for convenience, run `poetry config virtualenvs.in-project true` before installing depencies. This will install the dependencies in the project directory and make it easier to manage in vscode.
1515

1616
You can then install the dependencies with `poetry install --with dev`.
1717

18-
To activate the virtual env, use `poetry shell`.
19-
2018
## Running the server
2119

22-
Run this command to start a development server :
20+
To start a development server, run
2321

2422
```console
25-
uvicorn app.main:app --reload
23+
poetry run fastapi dev app/main.py
2624
```
2725

26+
from the `backend` directory (remove the `poetry run` prefix if using another dependency management tool).
27+
2828
This will start a server running on `http://127.0.0.1:8000`. The API will be available on the API's base prefix, which by default is `/api/v1`.
2929

3030
Navigate to `http://localhost:8000/api/v1/` to access the root API path.
@@ -36,10 +36,10 @@ Navigate to `http://localhost:8000/redoc` to access the API's alternative doc bu
3636
Run
3737

3838
```console
39-
pytest
39+
poetry run pytest
4040
```
4141

42-
to run the unit test for the backend app.
42+
to run the unit tests for the backend app.
4343

4444
## Configuration
4545

0 commit comments

Comments
 (0)