From 34fd975829b71260b8ee6883bcfdec32aa33b834 Mon Sep 17 00:00:00 2001 From: DavidHenryThoreau Date: Sat, 23 Nov 2024 13:33:19 +0100 Subject: [PATCH 01/14] add docker.yaml in order to automatically build docker container in master --- .github/workflows/docker.yaml | 68 +++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/docker.yaml diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml new file mode 100644 index 000000000..76d96a2f1 --- /dev/null +++ b/.github/workflows/docker.yaml @@ -0,0 +1,68 @@ +name: Create and publish a Docker image + +# Configures this workflow to run every time a change is pushed to the branch called `release`. +on: + push: + branches: ["master"] + tags: ["v*"] + workflow_dispatch: + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + build-and-push-image: + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write + id-token: write + # + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set BUILD_TIME env + run: echo BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") >> ${GITHUB_ENV} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=semver,pattern=release + type=sha + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max + push: true + build-args: | + BUILD_TIME=${{ env.BUILD_TIME }} + GIT_COMMIT=${{ github.sha }} + GIT_REF=${{ github.ref }} + GIT_REF_NAME=${{ github.ref_name }} + GIT_REF_TYPE=${{ github.ref_type }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 7443e6d007abb8b39a24e525551c3787ba939a5f Mon Sep 17 00:00:00 2001 From: DavidHenryThoreau Date: Sat, 23 Nov 2024 13:34:02 +0100 Subject: [PATCH 02/14] feat: add optimized Docker and docker-compose.yaml --- Dockerfile | 52 +++++++++++++++++++++++++++++++---------- docker-compose.yaml | 57 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 docker-compose.yaml diff --git a/Dockerfile b/Dockerfile index aa6df7caf..f643619f2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,50 @@ -FROM python:3.10 +FROM python:3.13-alpine AS BUILDER -# set working directory -RUN mkdir -p /usr/src/app -WORKDIR /usr/src/app +# install dependencies +RUN apk add --no-cache linux-headers gcc musl-dev libffi-dev \ + --virtual=build-dependencies +RUN apk add --no-cache py-pip bash curl # copy source files -COPY . /usr/src/app +RUN LATEST=$(curl -s \ + "https://api.github.com/repos/SamR1/FitTrackee/releases/latest" | \ + grep -i zipball_url | grep -Eo "https://.*[0-9]{1}") && \ + wget "${LATEST}" -O /usr/src/latest.zip +RUN cd /usr/src/ && unzip latest.zip -d /usr/src/app +RUN sync +RUN mv /usr/src/app/*FitTrackee*/* /usr/src/app/ +RUN rm -r /usr/src/app/*FitTrackee*/ +RUN rm -r /usr/src/latest.zip # install requirements +WORKDIR /usr/src/app ENV VIRTUAL_ENV=/opt/venv RUN python3 -m venv $VIRTUAL_ENV ENV PATH="$VIRTUAL_ENV/bin:$PATH" -RUN pip install --upgrade pip -RUN pip install poetry -RUN . $VIRTUAL_ENV/bin/activate && poetry install --no-interaction --quiet +RUN pip install --no-cache-dir --upgrade pip +RUN pip install --no-cache-dir poetry +RUN . $VIRTUAL_ENV/bin/activate && poetry install --no-interaction + + +FROM python:3.13-alpine + +RUN apk add bash + +# create user fittrackee +RUN addgroup -g 1000 -S fittrackee +RUN adduser -u 1000 -S -D -G fittrackee -H -h /usr/src/app -s /bin/bash fittrackee + +COPY --from=BUILDER /opt/venv/ /opt/venv +COPY --from=BUILDER /usr/src/app /usr/src/app + +WORKDIR /usr/src/app +ENV VIRTUAL_ENV=/opt/venv +RUN python3 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +# change owner +RUN chown -R fittrackee:fittrackee /usr/src/app # run fittrackee server -COPY ./docker-entrypoint.sh /docker-entrypoint.sh -COPY ./docker/set-admin.sh /usr/bin/set-admin -RUN chmod +x /usr/bin/set-admin && chmod +x /docker-entrypoint.sh -ENTRYPOINT [ "/docker-entrypoint.sh" ] \ No newline at end of file +USER fittrackee +CMD flask run --with-threads -h 0.0.0.0 diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 000000000..8f524a9d9 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,57 @@ +--- +version: "3.1" +services: + fittrackee: + image: ghcr.io/davidhenrythoreau/fittrackee:master + container_name: fittrackee + environment: + - PUID=1000 + - PGID=1000 + - TZ=Europe/Paris + - FLASK_DEBUG=1 + - FLASK_APP=fittrackee/__main__.py + - FLASK_SKIP_DOTENV=1 + - APP_SETTINGS=fittrackee.config.ProductionConfig + - APP_SECRET_KEY='just for test' + - UPLOAD_FOLDER=/usr/src/app/uploads + - DATABASE_URL=postgresql://fittrackee:fittrackee@fittrackee-db:5432/fittrackee + - DATABASE_TEST_URL=postgresql://fittrackee:fittrackee@fittrackee-db:5432/fittrackee_test + - REDIS_URL=redis://fittrackee-redis:6379 + volumes: + - ./fittrackee-upload:/usr/src/app/uploads/uploads/ + ports: + - 8230:5000 + depends_on: + fittrackee-db: + condition: service_started + fittrackee-redis: + condition: service_started + command: bash -c "cd /usr/src/app && ftcli db upgrade && flask run --with-threads -h 0.0.0.0" + restart: unless-stopped + + fittrackee-db: + image: postgres:17-alpine + container_name: fittrackee-db + environment: + - PUID=70 + - PGID=70 + - TZ=Europe/Paris + - POSTGRES_USER=fittrackee + - POSTGRES_PASSWORD=fittrackee + - POSTGRES_DB=fittrackee + volumes: + - ./fittrackee-db:/var/lib/postgresql/data + ports: + - 5432:5432 + restart: unless-stopped + + fittrackee-redis: + image: redis:latest + container_name: fittrackee-redis + environment: + - PUID=1000 + - PGID=1000 + - TZ=Europe/Paris + ports: + - 6379:6379 + restart: unless-stopped From feecb9e8cbc0611b49606374a54c479c45793aff Mon Sep 17 00:00:00 2001 From: "sam@samr1.net" Date: Thu, 26 Dec 2024 10:02:06 +0100 Subject: [PATCH 03/14] Docker - update files for dev --- .env.docker => .env.docker.dev | 4 ++-- Dockerfile-dev | 22 ++++++++++++++++++++++ Makefile | 7 ++++--- docker-compose-dev.yml | 16 +++++++++++----- docker-entrypoint-dev.sh | 17 +++++++++++++++++ docker/lint-python.sh | 8 -------- docker/set-admin.sh | 7 ------- docker/shell.sh | 7 ------- docker/test-e2e.sh | 3 --- docker/test-python.sh | 7 ------- fittrackee_client/Dockerfile | 4 +--- 11 files changed, 57 insertions(+), 45 deletions(-) rename .env.docker => .env.docker.dev (91%) create mode 100644 Dockerfile-dev create mode 100644 docker-entrypoint-dev.sh delete mode 100755 docker/lint-python.sh delete mode 100755 docker/set-admin.sh delete mode 100755 docker/shell.sh delete mode 100755 docker/test-python.sh diff --git a/.env.docker b/.env.docker.dev similarity index 91% rename from .env.docker rename to .env.docker.dev index 7658d08c5..97f56cf37 100644 --- a/.env.docker +++ b/.env.docker.dev @@ -7,8 +7,8 @@ export FLASK_SKIP_DOTENV=1 export APP_SETTINGS=fittrackee.config.DevelopmentConfig export APP_SECRET_KEY='just for test' # export APP_WORKERS= -export APP_LOG=fittrackee.log -export UPLOAD_FOLDER=/usr/src/app/uploads +export APP_LOG=/usr/src/app/data/logs/fittrackee.log +export UPLOAD_FOLDER=/usr/src/app/data/uploads # PostgreSQL export DATABASE_URL=postgresql://fittrackee:fittrackee@fittrackee-db:5432/fittrackee diff --git a/Dockerfile-dev b/Dockerfile-dev new file mode 100644 index 000000000..62d2226a4 --- /dev/null +++ b/Dockerfile-dev @@ -0,0 +1,22 @@ +FROM python:3.13-slim + +# set working directory +RUN mkdir -p /usr/src/app/data/uploads /usr/src/app/data/logs +WORKDIR /usr/src/app + +# copy source files +COPY . /usr/src/app + +# install requirements +ENV VIRTUAL_ENV=/opt/venv +RUN python3 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" +RUN pip install --upgrade pip +RUN pip install poetry +RUN . $VIRTUAL_ENV/bin/activate && poetry install --no-interaction --quiet + +# run fittrackee server and workers +COPY ./docker-entrypoint-dev.sh /docker-entrypoint.sh +COPY ./docker/set-admin.sh /usr/bin/set-admin +RUN chmod +x /usr/bin/set-admin && chmod +x /docker-entrypoint.sh +ENTRYPOINT [ "/docker-entrypoint.sh" ] \ No newline at end of file diff --git a/Makefile b/Makefile index b19c37597..34d6c1c05 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,8 @@ docker-lint-client: docker compose -f docker-compose-dev.yml exec fittrackee_client $(NPM) type-check docker-lint-python: docker-run - docker compose -f docker-compose-dev.yml exec fittrackee docker/lint-python.sh + docker compose -f docker-compose-dev.yml exec fittrackee mypy fittrackee + docker compose -f docker-compose-dev.yml exec fittrackee ruff check fittrackee e2e docker-logs: docker compose -f docker-compose-dev.yml logs --follow @@ -95,7 +96,7 @@ docker-set-admin: docker compose -f docker-compose-dev.yml exec fittrackee ftcli users update $(USERNAME) --set-admin true docker-shell: - docker compose -f docker-compose-dev.yml exec fittrackee docker/shell.sh + docker compose -f docker-compose-dev.yml exec fittrackee /bin/bash docker-stop: docker compose -f docker-compose-dev.yml stop @@ -114,7 +115,7 @@ docker-test-e2e: docker-run docker compose -f docker-compose-dev.yml exec fittrackee docker/test-e2e.sh $(PYTEST_ARGS) docker-test-python: docker-run - docker compose -f docker-compose-dev.yml exec fittrackee docker/test-python.sh $(PYTEST_ARGS) + docker compose -f docker-compose-dev.yml exec fittrackee pytest fittrackee $(PYTEST_ARGS) docker-type-check: echo 'Running mypy in docker...' diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 3f4dc2ce6..a4550c182 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -1,7 +1,10 @@ +# docker compose for evaluation and development only +# not suitable for production + services: fittrackee-db: container_name: fittrackee-db - image: postgres:13 + image: postgres:17-alpine ports: - "5435:5432" environment: @@ -18,11 +21,13 @@ services: fittrackee: container_name: fittrackee - build: . + build: + context: . + dockerfile: Dockerfile-dev ports: - "5000:5000" env_file: - - .env + - .env.docker.dev depends_on: fittrackee-db: condition: service_healthy @@ -32,7 +37,8 @@ services: condition: service_started volumes: - .:/usr/src/app - - ./data/uploads:/usr/src/app/uploads + - ./data/uploads:/usr/src/app/data/uploads + - ./data/logs:/usr/src/app/data/logs fittrackee_client: container_name: fittrackee_client @@ -54,7 +60,7 @@ services: redis: container_name: fittrackee-redis - image: "redis:latest" + image: "redis:7.4" hostname: redis ports: - "6379:6379" diff --git a/docker-entrypoint-dev.sh b/docker-entrypoint-dev.sh new file mode 100644 index 000000000..69856551c --- /dev/null +++ b/docker-entrypoint-dev.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +# Init database +echo "Initializing database..." +ftcli db upgrade || { echo "Failed to upgrade database!"; exit 1; } + +# Run workers +echo "Starting workers..." +flask worker --processes="${WORKERS_PROCESSES:-1}" >> data/logs/dramatiq.log 2>&1 & + +# Wait for workers to start +sleep 3 + +# Run app +echo "Starting app..." +exec flask run --with-threads --host=0.0.0.0 diff --git a/docker/lint-python.sh b/docker/lint-python.sh deleted file mode 100755 index cbf9435e1..000000000 --- a/docker/lint-python.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -set -e -cd /usr/src/app - -source .env - -mypy fittrackee -ruff check fittrackee e2e \ No newline at end of file diff --git a/docker/set-admin.sh b/docker/set-admin.sh deleted file mode 100755 index 84eeb7c08..000000000 --- a/docker/set-admin.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -set -e -cd /usr/src/app - -source .env - -ftcli users update $1 --set-admin true diff --git a/docker/shell.sh b/docker/shell.sh deleted file mode 100755 index 55fd7607d..000000000 --- a/docker/shell.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -set -e -cd /usr/src/app - -source .env - -/bin/bash \ No newline at end of file diff --git a/docker/test-e2e.sh b/docker/test-e2e.sh index 97e26e0cd..09b549cfa 100755 --- a/docker/test-e2e.sh +++ b/docker/test-e2e.sh @@ -1,8 +1,5 @@ #!/bin/bash set -e -cd /usr/src/app - -source .env export TEST_APP_URL=http://$(hostname --ip-address):5000 pytest e2e --driver Remote --capability browserName firefox --selenium-host selenium --selenium-port 4444 $* \ No newline at end of file diff --git a/docker/test-python.sh b/docker/test-python.sh deleted file mode 100755 index 8058b5041..000000000 --- a/docker/test-python.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -set -e -cd /usr/src/app - -source .env - -pytest fittrackee $* \ No newline at end of file diff --git a/fittrackee_client/Dockerfile b/fittrackee_client/Dockerfile index e1c9e5f3a..8b2d022ad 100644 --- a/fittrackee_client/Dockerfile +++ b/fittrackee_client/Dockerfile @@ -1,6 +1,4 @@ -FROM node:18 - -MAINTAINER SamR1@users.noreply.github.com +FROM node:23-slim # set working directory RUN mkdir /usr/src/app From c90f576d64fedfc78d209698375b181f1a7b53c6 Mon Sep 17 00:00:00 2001 From: "sam@samr1.net" Date: Fri, 27 Dec 2024 09:44:06 +0100 Subject: [PATCH 04/14] Docker - update files for production --- .dockerignore | 6 ++- .env.docker.example | 44 +++++++++++++++++++++ Dockerfile | 66 +++++++++++++------------------ docker-compose.yaml | 57 --------------------------- docker-compose.yml | 92 ++++++++++++++++++++++++++++++++++++++++++++ docker-entrypoint.sh | 28 +++----------- 6 files changed, 172 insertions(+), 121 deletions(-) create mode 100644 .env.docker.example delete mode 100644 docker-compose.yaml create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore index db3149bac..3b52e2738 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,6 +7,10 @@ .coverage .eslintcache docker-compose-dev.yml +docker-compose.yml Makefile.custom.config *.log -data \ No newline at end of file +data + +**/__pycache__/ +**/*.py[cod] diff --git a/.env.docker.example b/.env.docker.example new file mode 100644 index 000000000..fcb494dcd --- /dev/null +++ b/.env.docker.example @@ -0,0 +1,44 @@ +# Custom variables initialisation + +# Docker volumes +# export UPLOAD_DIR= +# export DATABASE_DIR= +# export REDIS_DIR= + +# Application +export FLASK_APP=fittrackee +export FLASK_SKIP_DOTENV=1 +# export APP_PORT=5000 +# export APP_SETTINGS=fittrackee.config.ProductionConfig +export APP_SECRET_KEY='PLEASE CHANGE ME' +export APP_LOG=/usr/src/app/logs/fittrackee.log +export UPLOAD_FOLDER=/usr/src/app/uploads + +# PostgreSQL +export POSTGRES_USER=fittrackee +export POSTGRES_PASSWORD=fittrackee +export POSTGRES_DB=fittrackee +export DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@fittrackee-db:5432/${POSTGRES_DB} +# export DATABASE_DISABLE_POOLING= + +# Redis (required for API rate limits and email sending) +export REDIS_URL=redis://redis:6379 + +# API rate limits +# export API_RATE_LIMITS="300 per 5 minutes" + +# Emails +export UI_URL= +export EMAIL_URL= +export SENDER_EMAIL= + +# Workouts +# export TILE_SERVER_URL= +# export STATICMAP_SUBDOMAINS= +# export MAP_ATTRIBUTION= +# export DEFAULT_STATICMAP=False + +# Weather +# available weather API providers: visualcrossing +# export WEATHER_API_PROVIDER= +# export WEATHER_API_KEY= \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index f643619f2..55d5eb1a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,50 +1,36 @@ -FROM python:3.13-alpine AS BUILDER - -# install dependencies -RUN apk add --no-cache linux-headers gcc musl-dev libffi-dev \ - --virtual=build-dependencies -RUN apk add --no-cache py-pip bash curl - -# copy source files -RUN LATEST=$(curl -s \ - "https://api.github.com/repos/SamR1/FitTrackee/releases/latest" | \ - grep -i zipball_url | grep -Eo "https://.*[0-9]{1}") && \ - wget "${LATEST}" -O /usr/src/latest.zip -RUN cd /usr/src/ && unzip latest.zip -d /usr/src/app -RUN sync -RUN mv /usr/src/app/*FitTrackee*/* /usr/src/app/ -RUN rm -r /usr/src/app/*FitTrackee*/ -RUN rm -r /usr/src/latest.zip - -# install requirements -WORKDIR /usr/src/app -ENV VIRTUAL_ENV=/opt/venv -RUN python3 -m venv $VIRTUAL_ENV -ENV PATH="$VIRTUAL_ENV/bin:$PATH" -RUN pip install --no-cache-dir --upgrade pip -RUN pip install --no-cache-dir poetry -RUN . $VIRTUAL_ENV/bin/activate && poetry install --no-interaction +FROM python:3.13-alpine AS builder + +RUN mkdir -p /usr/src/app/ +WORKDIR /usr/src/app/ + +ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 \ + POETRY_VIRTUALENVS_CREATE=false \ + POETRY_NO_INTERACTION=1 \ + VIRTUAL_ENV=/opt/venv +COPY pyproject.toml poetry.lock README.md /usr/src/app/ +COPY fittrackee/. /usr/src/app/fittrackee/ -FROM python:3.13-alpine +RUN python3 -m venv $VIRTUAL_ENV && pip install --upgrade pip +RUN pip install poetry==1.8.5 && . $VIRTUAL_ENV/bin/activate && poetry install --only main --no-interaction --quiet -RUN apk add bash +FROM python:3.13-alpine AS runtime -# create user fittrackee -RUN addgroup -g 1000 -S fittrackee -RUN adduser -u 1000 -S -D -G fittrackee -H -h /usr/src/app -s /bin/bash fittrackee +RUN apk add --no-cache tini -COPY --from=BUILDER /opt/venv/ /opt/venv -COPY --from=BUILDER /usr/src/app /usr/src/app +RUN addgroup -g 1000 -S fittrackee && \ + adduser -H -D -u 1000 -S fittrackee -G fittrackee WORKDIR /usr/src/app -ENV VIRTUAL_ENV=/opt/venv -RUN python3 -m venv $VIRTUAL_ENV -ENV PATH="$VIRTUAL_ENV/bin:$PATH" -# change owner -RUN chown -R fittrackee:fittrackee /usr/src/app +ENV VIRTUAL_ENV=/opt/venv PATH="/opt/venv/bin:$PATH" + +COPY --chown=fittrackee --from=builder /opt/venv "$VIRTUAL_ENV" +COPY --chown=fittrackee --from=builder /usr/src/app/fittrackee /usr/src/app/fittrackee +COPY --chown=fittrackee docker-entrypoint.sh /usr/src/app/ + +RUN chmod 555 /usr/src/app/docker-entrypoint.sh -# run fittrackee server USER fittrackee -CMD flask run --with-threads -h 0.0.0.0 + +ENTRYPOINT ["/sbin/tini", "--"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml deleted file mode 100644 index 8f524a9d9..000000000 --- a/docker-compose.yaml +++ /dev/null @@ -1,57 +0,0 @@ ---- -version: "3.1" -services: - fittrackee: - image: ghcr.io/davidhenrythoreau/fittrackee:master - container_name: fittrackee - environment: - - PUID=1000 - - PGID=1000 - - TZ=Europe/Paris - - FLASK_DEBUG=1 - - FLASK_APP=fittrackee/__main__.py - - FLASK_SKIP_DOTENV=1 - - APP_SETTINGS=fittrackee.config.ProductionConfig - - APP_SECRET_KEY='just for test' - - UPLOAD_FOLDER=/usr/src/app/uploads - - DATABASE_URL=postgresql://fittrackee:fittrackee@fittrackee-db:5432/fittrackee - - DATABASE_TEST_URL=postgresql://fittrackee:fittrackee@fittrackee-db:5432/fittrackee_test - - REDIS_URL=redis://fittrackee-redis:6379 - volumes: - - ./fittrackee-upload:/usr/src/app/uploads/uploads/ - ports: - - 8230:5000 - depends_on: - fittrackee-db: - condition: service_started - fittrackee-redis: - condition: service_started - command: bash -c "cd /usr/src/app && ftcli db upgrade && flask run --with-threads -h 0.0.0.0" - restart: unless-stopped - - fittrackee-db: - image: postgres:17-alpine - container_name: fittrackee-db - environment: - - PUID=70 - - PGID=70 - - TZ=Europe/Paris - - POSTGRES_USER=fittrackee - - POSTGRES_PASSWORD=fittrackee - - POSTGRES_DB=fittrackee - volumes: - - ./fittrackee-db:/var/lib/postgresql/data - ports: - - 5432:5432 - restart: unless-stopped - - fittrackee-redis: - image: redis:latest - container_name: fittrackee-redis - environment: - - PUID=1000 - - PGID=1000 - - TZ=Europe/Paris - ports: - - 6379:6379 - restart: unless-stopped diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..9a94c1b28 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,92 @@ +# docker compose for production +# +# minimal application (for single user) only needs fittrackee and fittrackee-db containers. +# +# for multi-users application, uncomment the following containers: +# - fittrackee-workers for email sending (EMAIL_URL must be set in .env to enable emails) +# - fittrackee-redis container for API rate limits and email sending + +services: + fittrackee-db: + container_name: fittrackee-db + image: postgres:17-alpine + env_file: + - .env + volumes: + - ${DATABASE_DIR:-./data/db}:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 15s + retries: 3 + networks: + - internal_network + restart: unless-stopped + + fittrackee: + container_name: fittrackee + env_file: + - .env + build: . + volumes: + - ${UPLOAD_DIR:-./data/uploads}:/usr/src/app/uploads + - ${UPLOAD_LOG:-./data/logs}:/usr/src/app/logs + post_start: + - command: chown -R fittrackee:fittrackee /usr/src/app/uploads /usr/src/app/logs + user: root + ports: + - "${APP_PORT:-5000}:5000" + command: 'sh docker-entrypoint.sh' + depends_on: + fittrackee-db: + condition: service_healthy +# Uncomment the following lines for API rate limit and email sending +# fittrackee-redis: +# condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget --spider http://127.0.0.1:5000/api/ping || exit 1"] + interval: 5s + timeout: 15s + retries: 3 + networks: + - external_network + - internal_network + restart: unless-stopped + +# Uncomment the following lines for email sending +# fittrackee-workers: +# container_name: fittrackee-workers +# env_file: +# - .env +# build: . +# volumes: +# - ${UPLOAD_LOG:-./data/logs}:/usr/src/app/logs +# post_start: +# - command: chown -R fittrackee:fittrackee /usr/src/app/logs +# user: root +# command: "flask worker --processes 2 >> /usr/src/app/logs/dramatiq.log 2>&1" +# depends_on: +# fittrackee: +# condition: service_healthy +# networks: +# - internal_network +# - external_network +# restart: unless-stopped + +# Uncomment the following lines for API rate limit and email sending +# fittrackee-redis: +# image: "redis:7.4" +# container_name: fittrackee-redis +# hostname: redis +# volumes: +# - ${REDIS_DIR:-./data/redis}:/data +# healthcheck: +# test: ['CMD', 'redis-cli', 'ping'] +# networks: +# - internal_network +# restart: unless-stopped + +networks: + external_network: + internal_network: + internal: true \ No newline at end of file diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 3fe02e0e2..3ba387392 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,28 +1,10 @@ #!/bin/bash set -e -# Change to the application directory -cd /usr/src/app || exit 1 - -# Check if the .env file exists and source it -if [[ -f .env ]]; then - source .env -else - echo ".env file not found!" - exit 1 -fi - -# Init database -echo "Initializing database..." +# Upgrade database +echo "Upgrading database..." ftcli db upgrade || { echo "Failed to upgrade database!"; exit 1; } -# Run workers -echo "Initializing workers..." -flask worker --processes="${WORKERS_PROCESSES:-1}" >> dramatiq.log 2>&1 & - -# Wait for workers to start -sleep 3 - -# Run app -echo "Initializing app..." -exec flask run --with-threads --host=0.0.0.0 +# Run app w/ gunicorn +echo "Running app..." +exec gunicorn -b 0.0.0.0:5000 "fittrackee:create_app()" --error-logfile /usr/src/app/logs/gunicorn.log From e876c95ba73cdd8dd9e5a2de5290fac212d699a4 Mon Sep 17 00:00:00 2001 From: "sam@samr1.net" Date: Thu, 26 Dec 2024 18:44:59 +0100 Subject: [PATCH 05/14] Docker - build client files --- Dockerfile | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 55d5eb1a0..902a26a15 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,17 @@ -FROM python:3.13-alpine AS builder +FROM node:23-alpine AS node-builder + +RUN mkdir -p /usr/src/app/fittrackee_client /usr/src/app/fittrackee +WORKDIR /usr/src/app/fittrackee_client + +ENV PATH /usr/src/app/fittrackee_client/node_modules/.bin:$PATH +COPY fittrackee_client/package.json /usr/src/app/fittrackee_client/package.json +COPY fittrackee_client/yarn.lock /usr/src/app/fittrackee_client/yarn.lock +RUN yarn install --silent --network-timeout 300000 + +COPY fittrackee_client/. /usr/src/app/fittrackee_client +RUN yarn build + +FROM python:3.13-alpine AS python-builder RUN mkdir -p /usr/src/app/ WORKDIR /usr/src/app/ @@ -25,8 +38,9 @@ WORKDIR /usr/src/app ENV VIRTUAL_ENV=/opt/venv PATH="/opt/venv/bin:$PATH" -COPY --chown=fittrackee --from=builder /opt/venv "$VIRTUAL_ENV" -COPY --chown=fittrackee --from=builder /usr/src/app/fittrackee /usr/src/app/fittrackee +COPY --chown=fittrackee --from=python-builder /opt/venv "$VIRTUAL_ENV" +COPY --chown=fittrackee --from=python-builder /usr/src/app/fittrackee /usr/src/app/fittrackee +COPY --chown=fittrackee --from=node-builder /usr/src/app/fittrackee/dist /usr/src/app/fittrackee/dist COPY --chown=fittrackee docker-entrypoint.sh /usr/src/app/ RUN chmod 555 /usr/src/app/docker-entrypoint.sh From aa2182b52372b7c960c70bf7483782a65dd2aa4c Mon Sep 17 00:00:00 2001 From: "sam@samr1.net" Date: Fri, 27 Dec 2024 09:50:18 +0100 Subject: [PATCH 06/14] Docker - update workflow for image push to GitHub registry --- .github/workflows/.publish-docker-image.yml | 57 +++++++++++++++++ .github/workflows/docker.yaml | 68 --------------------- 2 files changed, 57 insertions(+), 68 deletions(-) create mode 100644 .github/workflows/.publish-docker-image.yml delete mode 100644 .github/workflows/docker.yaml diff --git a/.github/workflows/.publish-docker-image.yml b/.github/workflows/.publish-docker-image.yml new file mode 100644 index 000000000..f8ad3340f --- /dev/null +++ b/.github/workflows/.publish-docker-image.yml @@ -0,0 +1,57 @@ +name: Create and publish a Docker image + +on: + push: + tags: ["v*"] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v2 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml deleted file mode 100644 index 76d96a2f1..000000000 --- a/.github/workflows/docker.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: Create and publish a Docker image - -# Configures this workflow to run every time a change is pushed to the branch called `release`. -on: - push: - branches: ["master"] - tags: ["v*"] - workflow_dispatch: - -# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - -# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. -jobs: - build-and-push-image: - runs-on: ubuntu-latest - # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. - permissions: - contents: read - packages: write - id-token: write - # - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Set BUILD_TIME env - run: echo BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") >> ${GITHUB_ENV} - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Log in to the Container registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=semver,pattern=release - type=sha - - name: Build and push Docker image - uses: docker/build-push-action@v6 - with: - context: . - platforms: linux/amd64,linux/arm64 - cache-from: type=gha - cache-to: type=gha,mode=max - push: true - build-args: | - BUILD_TIME=${{ env.BUILD_TIME }} - GIT_COMMIT=${{ github.sha }} - GIT_REF=${{ github.ref }} - GIT_REF_NAME=${{ github.ref_name }} - GIT_REF_TYPE=${{ github.ref_type }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} From 35f0b3816da546fbaa217e6113635e101c0b3364 Mon Sep 17 00:00:00 2001 From: "sam@samr1.net" Date: Fri, 27 Dec 2024 10:48:04 +0100 Subject: [PATCH 07/14] Docker - push image to Docker hub --- ...ker-image.yml => .publish-docker-images.yml} | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) rename .github/workflows/{.publish-docker-image.yml => .publish-docker-images.yml} (75%) diff --git a/.github/workflows/.publish-docker-image.yml b/.github/workflows/.publish-docker-images.yml similarity index 75% rename from .github/workflows/.publish-docker-image.yml rename to .github/workflows/.publish-docker-images.yml index f8ad3340f..6586b28ca 100644 --- a/.github/workflows/.publish-docker-image.yml +++ b/.github/workflows/.publish-docker-images.yml @@ -9,7 +9,8 @@ env: IMAGE_NAME: ${{ github.repository }} jobs: - build-and-push-image: + push_to_registries: + name: Push Docker image to multiple registries runs-on: ubuntu-latest permissions: contents: read @@ -26,6 +27,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: @@ -37,11 +44,13 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + images: | + fittrackee/fittrackee + ghcr.io/${{ env.IMAGE_NAME}} - - name: Build and push Docker image + - name: Build and push Docker images id: push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64,linux/arm64 From ecb045e444a7281d09592fd94f3ac65c3e3ac7fd Mon Sep 17 00:00:00 2001 From: "sam@samr1.net" Date: Fri, 27 Dec 2024 10:48:39 +0100 Subject: [PATCH 08/14] Docker - update Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 902a26a15..2d92f6196 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM node:23-alpine AS node-builder RUN mkdir -p /usr/src/app/fittrackee_client /usr/src/app/fittrackee WORKDIR /usr/src/app/fittrackee_client -ENV PATH /usr/src/app/fittrackee_client/node_modules/.bin:$PATH +ENV PATH=/usr/src/app/fittrackee_client/node_modules/.bin:$PATH COPY fittrackee_client/package.json /usr/src/app/fittrackee_client/package.json COPY fittrackee_client/yarn.lock /usr/src/app/fittrackee_client/yarn.lock RUN yarn install --silent --network-timeout 300000 From 6fd538a0c72f37d34dbeebd14c5177b55ad8880b Mon Sep 17 00:00:00 2001 From: "sam@samr1.net" Date: Fri, 27 Dec 2024 11:16:11 +0100 Subject: [PATCH 09/14] Docker - add image from docker hub in docker-compose.yml (WIP) --- docker-compose.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 9a94c1b28..8e53ef952 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,6 +27,8 @@ services: container_name: fittrackee env_file: - .env +# TODO: to update on next release +# image: fittrackee/fittrackee:v0.8.13 build: . volumes: - ${UPLOAD_DIR:-./data/uploads}:/usr/src/app/uploads @@ -58,6 +60,8 @@ services: # container_name: fittrackee-workers # env_file: # - .env +## TODO: to update on next release +## image: fittrackee/fittrackee:v0.8.13 # build: . # volumes: # - ${UPLOAD_LOG:-./data/logs}:/usr/src/app/logs From 4eb54f9fd641d809da575825b2450c8f5cdd501d Mon Sep 17 00:00:00 2001 From: "sam@samr1.net" Date: Fri, 27 Dec 2024 16:30:20 +0100 Subject: [PATCH 10/14] Docker - remove unneeded directory --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 2d92f6196..bd48973a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,6 +23,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 \ COPY pyproject.toml poetry.lock README.md /usr/src/app/ COPY fittrackee/. /usr/src/app/fittrackee/ +RUN rm -rf /usr/src/app/fittrackee/tests RUN python3 -m venv $VIRTUAL_ENV && pip install --upgrade pip RUN pip install poetry==1.8.5 && . $VIRTUAL_ENV/bin/activate && poetry install --only main --no-interaction --quiet From e71f0fd9c385c122b91736af659b6d6eba6cb263 Mon Sep 17 00:00:00 2001 From: "sam@samr1.net" Date: Fri, 27 Dec 2024 17:49:07 +0100 Subject: [PATCH 11/14] Docker - update documentation --- .env.docker.example | 1 - docker-compose.yml | 1 + docsrc/source/installation.rst | 46 ++++++++++++++++++++++++---------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/.env.docker.example b/.env.docker.example index fcb494dcd..ba3bc9597 100644 --- a/.env.docker.example +++ b/.env.docker.example @@ -9,7 +9,6 @@ export FLASK_APP=fittrackee export FLASK_SKIP_DOTENV=1 # export APP_PORT=5000 -# export APP_SETTINGS=fittrackee.config.ProductionConfig export APP_SECRET_KEY='PLEASE CHANGE ME' export APP_LOG=/usr/src/app/logs/fittrackee.log export UPLOAD_FOLDER=/usr/src/app/uploads diff --git a/docker-compose.yml b/docker-compose.yml index 8e53ef952..b2034d2a6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,5 @@ # docker compose for production +# (minimal version: Docker Compose version 2.30.0) # # minimal application (for single user) only needs fittrackee and fittrackee-db containers. # diff --git a/docsrc/source/installation.rst b/docsrc/source/installation.rst index 33a2cc03e..2e34af9e6 100644 --- a/docsrc/source/installation.rst +++ b/docsrc/source/installation.rst @@ -834,15 +834,42 @@ Examples: Docker ~~~~~~ -Installation -^^^^^^^^^^^^ - .. versionadded:: 0.4.4 +.. versionchanged:: 0.5.0 add client application for development +.. versionchanged:: 0.8.13 add docker image for production -For **evaluation** purposes, docker files are available, installing **FitTrackee** from **sources**. -.. warning:: - Docker files are not suitable for production installation. +Production +^^^^^^^^^^ + +An image is available on `DockerHub `_ or `Github registry `_. + +- create a ``docker-compose.yml`` file as needed (see the example in the repository): + + - the minimal set up requires at least the database and the web application. + - to activate the rate limit, redis is required. + - to send e-mails, redis and workers are required and EMAIL_URL must be set in ``.env``. + +.. note:: + The same image is used by the web application and workers. + +- create ``.env`` from example (``.env.docker.example``) and update it (see `Environment variables `__). + +- to start the application: + +.. code:: bash + + $ docker compose up -d + +- to run a CLI command, for instance to give admin rights: + +.. code:: bash + + $ docker compose exec fittrackee ftcli users update --set-admin true + + +Development +^^^^^^^^^^^ - To install and run **FitTrackee**: @@ -850,7 +877,6 @@ For **evaluation** purposes, docker files are available, installing **FitTrackee $ git clone https://github.com/SamR1/FitTrackee.git $ cd FitTrackee - $ cp .env.docker .env $ make docker-run - Open http://localhost:5000 and register. @@ -878,12 +904,6 @@ Open http://localhost:8025 to access `MailHog interface Date: Sat, 28 Dec 2024 10:58:18 +0100 Subject: [PATCH 12/14] Docker - fix db health check --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index b2034d2a6..d03274aed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,7 @@ services: volumes: - ${DATABASE_DIR:-./data/db}:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 15s retries: 3 From 54da32eb80273ea5b43bc667b02d624033ea7181 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 28 Dec 2024 10:58:27 +0100 Subject: [PATCH 13/14] Docker - minor workflow change --- .github/workflows/.publish-docker-images.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/.publish-docker-images.yml b/.github/workflows/.publish-docker-images.yml index 6586b28ca..4fba846f1 100644 --- a/.github/workflows/.publish-docker-images.yml +++ b/.github/workflows/.publish-docker-images.yml @@ -5,8 +5,8 @@ on: tags: ["v*"] env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} + GITHUB_REGISTRY: ghcr.io + GITHUB_IMAGE_NAME: ${{ github.repository }} jobs: push_to_registries: @@ -36,7 +36,7 @@ jobs: - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: - registry: ghcr.io + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} @@ -46,7 +46,7 @@ jobs: with: images: | fittrackee/fittrackee - ghcr.io/${{ env.IMAGE_NAME}} + ${{ env.GITHUB_REGISTRY }}/${{ env.GITHUB_IMAGE_NAME}} - name: Build and push Docker images id: push @@ -61,6 +61,6 @@ jobs: - name: Generate artifact attestation uses: actions/attest-build-provenance@v2 with: - subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-name: ${{ env.GITHUB_REGISTRY }}/${{ env.GITHUB_IMAGE_NAME}} subject-digest: ${{ steps.push.outputs.digest }} push-to-registry: true From b572908472c6254031f17d9a656e911bad1cfaa8 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 28 Dec 2024 11:06:14 +0100 Subject: [PATCH 14/14] Docker - update documentation --- .env.docker.example | 3 +- docsrc/source/installation.rst | 58 +++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/.env.docker.example b/.env.docker.example index ba3bc9597..59f76453f 100644 --- a/.env.docker.example +++ b/.env.docker.example @@ -2,6 +2,7 @@ # Docker volumes # export UPLOAD_DIR= +# export LOG_DIR= # export DATABASE_DIR= # export REDIS_DIR= @@ -15,7 +16,7 @@ export UPLOAD_FOLDER=/usr/src/app/uploads # PostgreSQL export POSTGRES_USER=fittrackee -export POSTGRES_PASSWORD=fittrackee +export POSTGRES_PASSWORD= export POSTGRES_DB=fittrackee export DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@fittrackee-db:5432/${POSTGRES_DB} # export DATABASE_DISABLE_POOLING= diff --git a/docsrc/source/installation.rst b/docsrc/source/installation.rst index 2e34af9e6..18458ac15 100644 --- a/docsrc/source/installation.rst +++ b/docsrc/source/installation.rst @@ -260,6 +260,48 @@ deployment method. .. versionchanged:: 0.7.26 ⚠️ replaces ``VUE_APP_API_URL`` + **FitTrackee** API URL, only needed in dev environment. + +Docker +^^^^^^ + +.. versionadded:: 0.8.13 + +Environment variables for ``docker-compose.yml`` + +.. envvar:: DATABASE_DIR + + Host directory for PostgreSQL data volume + + +.. envvar:: POSTGRES_USER + + User for PostgreSQL database + + +.. envvar:: POSTGRES_PASSWORD + + Password for PostgreSQL user + + +.. envvar:: POSTGRES_DB + + Database name for FitTrackee application + + +.. envvar:: REDIS_DIR + + Host directory for redis data volume + + +.. envvar:: LOG_DIR + + Host directory for logs volume + + +.. envvar:: UPLOAD_DIR + + Host directory for uploaded files volume Emails @@ -842,13 +884,17 @@ Docker Production ^^^^^^^^^^ -An image is available on `DockerHub `_ or `Github registry `_. +Images are available on `DockerHub `_ or `Github registry `_. + +.. note:: + + Images are available for ``linux/amd64`` and ``linux/arm64`` platforms. Only ``linux/amd64`` image has been tested. - create a ``docker-compose.yml`` file as needed (see the example in the repository): - - the minimal set up requires at least the database and the web application. - - to activate the rate limit, redis is required. - - to send e-mails, redis and workers are required and EMAIL_URL must be set in ``.env``. + - the minimal set up requires at least the database and the web application + - to activate the rate limit, redis is required + - to send e-mails, redis and workers are required and a valid ``EMAIL_URL`` variable must be set in ``.env`` .. note:: The same image is used by the web application and workers. @@ -861,6 +907,10 @@ An image is available on `DockerHub