diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ca5984e..6462d2d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,7 +43,7 @@ jobs: API_PWD: ${{ secrets.API_PWD }} run: | screen -dm python app/main.py - sleep 20 + sleep 40 curl http://localhost:8050/ docker: runs-on: ubuntu-latest @@ -62,6 +62,6 @@ jobs: API_URL: ${{ secrets.API_URL }} API_LOGIN: ${{ secrets.API_LOGIN }} API_PWD: ${{ secrets.API_PWD }} - run: docker-compose up -d --build + run: docker-compose -f docker-compose-dev.yml up -d --build - name: Check docker sanity - run: sleep 20 && docker-compose logs && curl http://localhost:8050/ + run: sleep 40 && docker-compose logs && curl http://localhost:8050/ diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 57d2055..7e5987d 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -98,21 +98,21 @@ jobs: black --version black --check --diff . - bandit: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest] - python: [3.8] - steps: - - uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python }} - architecture: x64 - - name: Run bandit - run: | - pip install bandit[toml] - bandit --version - bandit -r . -c pyproject.toml + #bandit: + # runs-on: ${{ matrix.os }} + # strategy: + # matrix: + # os: [ubuntu-latest] + # python: [3.8] + # steps: + # - uses: actions/checkout@v2 + # - name: Set up Python + # uses: actions/setup-python@v4 + # with: + # python-version: ${{ matrix.python }} + # architecture: x64 + # - name: Run bandit + # run: | + # pip install bandit[toml] + # bandit --version + # bandit -r . -c pyproject.toml diff --git a/.gitignore b/.gitignore index 6b03c5f..2301a3d 100644 --- a/.gitignore +++ b/.gitignore @@ -146,3 +146,4 @@ app/data/login_correspondences.csv # Poetry requirements.txt +poetry.lock diff --git a/Makefile b/Makefile index d6f44e1..1d8ec69 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ quality: flake8 mypy black --check . - bandit -r . -c pyproject.toml +# bandit -r . -c pyproject.toml autoflake -r . # this target runs checks on all files and potentially modifies some of them @@ -18,10 +18,15 @@ build: poetry export -f requirements.txt --without-hashes --output requirements.txt docker build . -t pyronear/pyro-platform:python3.7.9-slim -# Run the docker +# Run the docker for production run: poetry export -f requirements.txt --without-hashes --output requirements.txt - docker-compose up -d --build + docker-compose -f docker-compose.yml up -d --build + +# Run the docker for dev purposes +run_dev: + poetry export -f requirements.txt --without-hashes --output requirements.txt + docker-compose -f docker-compose-dev.yml up -d --build # Run the docker stop: diff --git a/README.md b/README.md index 7c38f12..7f9132f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,13 @@ The building blocks of our wildfire detection & monitoring API. ### Running/stopping the service -You can run the app container using this command: +You can run the app container using this command for dev purposes: + +```shell +make run_dev +``` + +or for production: ```shell make run @@ -56,6 +62,20 @@ SENTRY_SERVER_NAME=my_storage_bucket_name The file should be placed at the root folder of your local copy of the project. +Also please note that you should use docker-compose-dev.yml file for dev as we do not need reverse proxy: + +```shell +docker-compose -f docker-compose-dev.yml up +``` + +For production we use docker-compose.yml in which there is the [Traefik Reverse Proxy](https://traefik.io/traefik/). + +Traefik interacts with the Dash frontend app via an external network called web, this needs do be created as follow: + +```shell +docker network create web +``` + ## License diff --git a/acme.json b/acme.json new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 0000000..f45de3b --- /dev/null +++ b/docker-compose-dev.yml @@ -0,0 +1,17 @@ +version: '3.7' + +services: + + frontend: + build: . + command: python main.py --host 0.0.0.0 --port 8050 + ports: + - 8050:8050 + volumes: + - ./app/:/usr/src/app/ + environment: + - API_URL=${API_URL} + - API_LOGIN=${API_LOGIN} + - API_PWD=${API_PWD} + - SENTRY_DSN=${SENTRY_DSN} + - DEBUG=${DEBUG} diff --git a/docker-compose.yml b/docker-compose.yml index 770d540..77b233f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,16 +1,48 @@ version: '3.7' services: + + reverse-proxy: + image: traefik:v2.4 + container_name: traefik + ports: + - "80:8050" + - "8080:8080" + - "443:443" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - $PWD/traefik.toml:/etc/traefik/traefik.toml + - $PWD/acme.json:/acme.json + labels: + - "traefik.http.middlewares.strip-www.redirectregex.regex=^https?://(www\\.)(.+)" + - "traefik.http.middlewares.strip-www.redirectregex.replacement=https://$${2}" + - "traefik.http.middlewares.strip-www.redirectregex.permanent=true" + restart: always + networks: + - web + frontend: build: . - command: python main.py --host 0.0.0.0 + command: python main.py --host 0.0.0.0 --port 8050 + ports: + - 8050:8050 + expose: + - 8050 volumes: - ./app/:/usr/src/app/ - ports: - - "8050:8050" environment: - API_URL=${API_URL} - API_LOGIN=${API_LOGIN} - API_PWD=${API_PWD} - SENTRY_DSN=${SENTRY_DSN} - DEBUG=${DEBUG} + networks: + - web + labels: + - "traefik.enable=true" + - "traefik.http.routers.platform.rule=Host(`platform.localhost`)" + - "traefik.http.routers.platform.entrypoints=websecure" + +networks: + web: + external: true \ No newline at end of file diff --git a/traefik.toml b/traefik.toml new file mode 100644 index 0000000..30232c4 --- /dev/null +++ b/traefik.toml @@ -0,0 +1,28 @@ +[entryPoints] + [entryPoints.web] + address = ":80" + [entryPoints.web.http] + [entryPoints.web.http.redirections] + [entryPoints.web.http.redirections.entryPoint] + to = "websecure" + scheme = "https" + permanent = true + + [entryPoints.websecure] + address = ":443" + [entryPoints.websecure.http.tls] + certResolver = "default" + +[providers] + [providers.docker] + watch = true + exposedByDefault = false + network = "web" + +[certificatesResolvers] + [certificatesResolvers.default] + [certificatesResolvers.default.acme] + email = "contact@pyronear.org" + storage = "acme.json" + caServer = "https://acme-v02.api.letsencrypt.org/directory" + [certificatesResolvers.default.acme.tlsChallenge] \ No newline at end of file