diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 51dc3fe..dead87c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,7 +28,7 @@ black: build_api_development: stage: build script: - - docker login ${CI_REGISTRY} -u gitlab-ci-token -p ${CI_BUILD_TOKEN} + - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin - docker build --target development -t ${CI_REGISTRY_IMAGE}:api-dev ./api - docker push ${CI_REGISTRY_IMAGE}:api-dev only: @@ -42,7 +42,7 @@ build_api_development: build_api_production: stage: build script: - - docker login ${CI_REGISTRY} -u gitlab-ci-token -p ${CI_BUILD_TOKEN} + - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin - docker build --target production -t ${CI_REGISTRY_IMAGE}:api-latest ./api - docker push ${CI_REGISTRY_IMAGE}:api-latest only: @@ -57,7 +57,7 @@ build_api_production: build_frontend_development: stage: build script: - - docker login ${CI_REGISTRY} -u gitlab-ci-token -p ${CI_BUILD_TOKEN} + - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin - docker build --target development -t ${CI_REGISTRY_IMAGE}:frontend-dev ./frontend - docker push ${CI_REGISTRY_IMAGE}:frontend-dev only: @@ -71,7 +71,7 @@ build_frontend_development: build_frontend_production: stage: build script: - - docker login ${CI_REGISTRY} -u gitlab-ci-token -p ${CI_BUILD_TOKEN} + - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin - docker build --target production -t ${CI_REGISTRY_IMAGE}:frontend-latest ./frontend - docker push ${CI_REGISTRY_IMAGE}:frontend-latest only: @@ -83,6 +83,21 @@ build_frontend_production: tags: - NSCICDDOCKER +build_keycloak: + stage: build + image: + name: gcr.io/kaniko-project/executor:v1.9.0-debug + entrypoint: [""] + script: + - /kaniko/executor --context "${CI_PROJECT_DIR}/keycloak" --dockerfile "${CI_PROJECT_DIR}/keycloak/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:keycloak-${CI_COMMIT_REF_NAME}" + tags: + - NSCICDK8S + rules: + - if: '$CI_COMMIT_REF_NAME =~ /^(main|dev)$/ && $CI_PIPELINE_SOURCE == "push"' + changes: + - keycloak/**/* + - if: '$build_keycloak' + test_api: stage: test script: diff --git a/api/Pipfile.lock b/api/Pipfile.lock index 10b1fe7..f95751e 100644 --- a/api/Pipfile.lock +++ b/api/Pipfile.lock @@ -1025,4 +1025,4 @@ "version": "==4.7.1" } } -} +} \ No newline at end of file diff --git a/api/src/main.py b/api/src/main.py index 9bf8d4d..31cecdc 100644 --- a/api/src/main.py +++ b/api/src/main.py @@ -40,6 +40,6 @@ def on_startup(): init_bucket() - is_demo_instance = (os.environ.get("DEMO_INSTANCE", None) == "True") + is_demo_instance = os.environ.get("DEMO_INSTANCE", None) == "True" if is_demo_instance: init_db() diff --git a/docker/.env.sample b/docker/.env.sample index 7934113..0b84edc 100644 --- a/docker/.env.sample +++ b/docker/.env.sample @@ -15,6 +15,7 @@ APP_USER=admin APP_PASSWORD=password # Database credentials +DB_IMAGE=postgres:14-alpine DB_USER=dbuser DB_PASSWORD=dbpassword DB_NAME=annotation @@ -28,6 +29,7 @@ MINIO_BUCKET_NAME=miniobucket MINIO_IMAGE=minio/minio:RELEASE.2023-08-23T10-07-06Z IMPORT_VARSUBSTITUTION_ENABLED=true +KEYCLOAK_IMAGE=registry.gitlab.com/natural-solutions/geonature/annotation:keycloak-dev KEYCLOAK_REALM_ID=${PROJECT_NAME} KEYCLOAK_CLIENT_ID=${PROJECT_NAME} KEYCLOAK_TOKEN_URI=${CANONICAL_URL}/auth/realms/${KEYCLOAK_REALM_ID}/protocol/openid-connect/token diff --git a/docker/docker-compose.override.yml b/docker/docker-compose.override.yml index 4f9e9db..6705a29 100644 --- a/docker/docker-compose.override.yml +++ b/docker/docker-compose.override.yml @@ -8,8 +8,8 @@ services: - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:80 ports: - - ${TRAEFIK_PORT-8889}:80 - - ${TRAEFIK_DASHBOARD_PORT-8890}:8080 + - ${TRAEFIK_PORT:-8889}:80 + - ${TRAEFIK_DASHBOARD_PORT:-8890}:8080 api: build: diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml index 6f56cf4..34f673c 100644 --- a/docker/docker-compose.prod.yml +++ b/docker/docker-compose.prod.yml @@ -53,7 +53,7 @@ services: minio: labels: - traefik.enable=true - - traefik.http.routers.minio.rule=Host(`${DOMAIN-my.domain.com}`) && PathPrefix(`/${MINIO_BUCKET_NAME-miniobucket}`) + - traefik.http.routers.minio.rule=Host(`${DOMAIN:-my.domain.com}`) && PathPrefix(`/${MINIO_BUCKET_NAME:-miniobucket}`) - traefik.http.routers.minio.entrypoints=websecure - traefik.http.routers.minio.tls=true - traefik.http.routers.minio.tls.certresolver=le diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 6a49487..193c657 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -12,7 +12,7 @@ x-project-defaults: &project_defaults services: traefik: <<: *project_defaults - image: ${TRAEFIK_IMAGE-traefik:v2.6} + image: ${TRAEFIK_IMAGE:-traefik:v2.6} depends_on: frontend: condition: service_healthy @@ -21,7 +21,7 @@ services: api: <<: *project_defaults - image: ${API_IMAGE-registry.gitlab.com/natural-solutions/geonature/annotation:api-dev} + image: ${API_IMAGE:-registry.gitlab.com/natural-solutions/geonature/annotation:api-dev} build: context: ../api dockerfile: Dockerfile @@ -37,35 +37,34 @@ services: condition: service_healthy minio: condition: service_healthy - keycloak: + keycloak: condition: service_healthy labels: - traefik.enable=true - - traefik.http.routers.api.rule=${TRAEFIK_ROUTER_RULE_API-PathPrefix(`/api/v1`)} + - traefik.http.routers.api.rule=${TRAEFIK_ROUTER_RULE_API:-PathPrefix(`/api/v1`)} - traefik.http.routers.api.entrypoints=web - traefik.http.routers.api.middlewares=api-stripprefix - - traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=${API_ROOT_PATH-/api/v1} + - traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=${API_ROOT_PATH:-/api/v1} environment: - KEYCLOAK_ADMIN_CLIENT_SECRET=${KEYCLOAK_ADMIN_CLIENT_SECRET} - - KEYCLOAK_CALLBACK_URI=${KEYCLOAK_CALLBACK_URI-http://api:8000/callback} - - KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID-geonature-annotation} + - KEYCLOAK_CALLBACK_URI=${KEYCLOAK_CALLBACK_URI:-http://api:8000/callback} + - KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID:-geonature-annotation} - KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET} - - KEYCLOAK_REALM=${KEYCLOAK_REALM-geonature-annotation} - - KEYCLOAK_SERVER_URL=${KEYCLOAK_SERVER_URL-http://keycloak:8080/auth} + - KEYCLOAK_REALM=${KEYCLOAK_REALM:-geonature-annotation} + - KEYCLOAK_SERVER_URL=${KEYCLOAK_SERVER_URL:-http://keycloak:8080/auth} - KEYCLOAK_TOKEN_URI=${KEYCLOAK_TOKEN_URI} taxapi: <<: *project_defaults - image: ${TAXAPI_IMAGE-registry.gitlab.com/natural-solutions/geonature/taxapi:taxapi-latest} + image: ${TAXAPI_IMAGE:-registry.gitlab.com/natural-solutions/geonature/taxapi:taxapi-latest} labels: - traefik.enable=true - - traefik.http.routers.taxapi.rule=${TRAEFIK_ROUTER_RULE_TAXAPI-PathPrefix(`/taxapi`)} + - traefik.http.routers.taxapi.rule=${TRAEFIK_ROUTER_RULE_TAXAPI:-PathPrefix(`/taxapi`)} - traefik.http.routers.taxapi.entrypoints=web - - traefik.http.middlewares.add-foo.addprefix.prefix=${TAXAPI_ROOT_PATH-/taxapi} environment: - - TAXREF_FILE=${TAXAPI_TAXREF_FILE-TAXREF_v16_2022.zip} + - TAXREF_FILE=${TAXAPI_TAXREF_FILE:-TAXREF_v16_2022.zip} healthcheck: - test: [ "CMD", "curl", "-f", "http://localhost:5666/taxapi/V1/healthcheck" ] + test: ["CMD", "curl", "-f", "http://localhost:5666/taxapi/V1/healthcheck"] interval: 10s timeout: 30s retries: 5 @@ -73,7 +72,7 @@ services: frontend: <<: *project_defaults - image: ${FRONTEND_IMAGE-registry.gitlab.com/natural-solutions/geonature/annotation:frontend-dev} + image: ${FRONTEND_IMAGE:-registry.gitlab.com/natural-solutions/geonature/annotation:frontend-dev} build: context: ../frontend dockerfile: Dockerfile @@ -88,7 +87,7 @@ services: start_period: 60s labels: - traefik.enable=true - - traefik.http.routers.frontend.rule=${TRAEFIK_ROUTER_RULE_FRONTEND-PathPrefix(`/`)} + - traefik.http.routers.frontend.rule=${TRAEFIK_ROUTER_RULE_FRONTEND:-PathPrefix(`/`)} - traefik.http.routers.frontend.entrypoints=web environment: - REACT_APP_KEYCLOAK_CLIENT_URL=${KEYCLOAK_CLIENT_URL:-http://localhost:8888/auth} @@ -97,28 +96,33 @@ services: db: <<: *project_defaults - image: postgres:14-alpine - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${DB_USER-dbuser} -d ${DB_NAME-annotation} -h 127.0.0.1"] - interval: 10s - timeout: 5s - retries: 3 + image: ${DB_IMAGE:-postgres:14-alpine} + healthcheck: + test: + [ + "CMD-SHELL", + "pg_isready -U ${DB_USER-dbuser} -d ${DB_NAME-annotation} -h 127.0.0.1", + ] + interval: 10s + timeout: 5s + retries: 3 start_period: 60s volumes: - db_data:/var/lib/postgresql/data environment: - POSTGRES_PASSWORD: ${DB_PASSWORD-dbpassword} - POSTGRES_DB: ${DB_NAME-annotation} - POSTGRES_USER: ${DB_USER-dbuser} + POSTGRES_PASSWORD: ${DB_PASSWORD:-dbpassword} + POSTGRES_DB: ${DB_NAME:-annotation} + POSTGRES_USER: ${DB_USER:-dbuser} keycloak: <<: *project_defaults - image: fastcam-keycloak-dev + image: ${KEYCLOAK_IMAGE:-registry.gitlab.com/natural-solutions/geonature/annotation:keycloak-dev} build: context: ../keycloak - command: start-dev --import-realm + command: start-dev --import-realm healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8080/auth"] + # https://github.com/keycloak/keycloak/issues/17273#issuecomment-1693549331 + test: cat /proc/net/tcp | grep '00000000:1F90 00000000:0000' || exit 1 interval: 10s timeout: 5s retries: 10 @@ -128,23 +132,23 @@ services: condition: service_healthy labels: - traefik.enable=true - - traefik.http.routers.keycloak.rule=${TRAEFIK_ROUTER_RULE_KEYCLOAK-PathPrefix(`/auth`)} + - traefik.http.routers.keycloak.rule=${TRAEFIK_ROUTER_RULE_KEYCLOAK:-PathPrefix(`/auth`)} - traefik.http.routers.keycloak.entrypoints=web minio: <<: *project_defaults - image: ${MINIO_IMAGE-minio/minio:RELEASE.2023-08-23T10-07-06Z} + image: ${MINIO_IMAGE:-minio/minio:RELEASE.2023-08-23T10-07-06Z} volumes: - minio_data:/data - healthcheck: + healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] - interval: 30s - timeout: 20s + interval: 30s + timeout: 20s retries: 3 command: server --console-address :9001 /data labels: - traefik.enable=true - - traefik.http.routers.minio.rule=${TRAEFIK_ROUTER_RULE_MINIO-PathPrefix(`/miniobucket`)} + - traefik.http.routers.minio.rule=${TRAEFIK_ROUTER_RULE_MINIO:-PathPrefix(`/miniobucket`)} volumes: db_data: diff --git a/frontend/Dockerfile b/frontend/Dockerfile index d61cd6f..6167729 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -20,6 +20,11 @@ USER node COPY --chown=node:node --from=deps /app/node_modules ./node_modules COPY --chown=node:node . . +ARG REACT_APP_KEYCLOAK_CLIENT_URL +ARG REACT_APP_KEYCLOAK_CLIENT_REALM +ARG REACT_APP_KEYCLOAK_CLIENT_CLIENT_ID +ARG REACT_APP_API_PATH + RUN npm run build EXPOSE 3000 diff --git a/frontend/public/assets/geocam-logo-dark.png b/frontend/public/assets/geocam-logo-dark.png new file mode 100644 index 0000000..ca63937 Binary files /dev/null and b/frontend/public/assets/geocam-logo-dark.png differ diff --git a/frontend/public/assets/geocam-logo-icon.png b/frontend/public/assets/geocam-logo-icon.png new file mode 100644 index 0000000..2e3805f Binary files /dev/null and b/frontend/public/assets/geocam-logo-icon.png differ diff --git a/frontend/public/assets/geocam-logo-light.png b/frontend/public/assets/geocam-logo-light.png new file mode 100644 index 0000000..d5a5ddd Binary files /dev/null and b/frontend/public/assets/geocam-logo-light.png differ diff --git a/frontend/src/components/deviceMenu/deviceModal.tsx b/frontend/src/components/deviceMenu/deviceModal.tsx index aaaa4fb..5741f26 100644 --- a/frontend/src/components/deviceMenu/deviceModal.tsx +++ b/frontend/src/components/deviceMenu/deviceModal.tsx @@ -193,4 +193,4 @@ export default function DeviceModal() { ); -} +} \ No newline at end of file diff --git a/frontend/src/components/importForm.tsx b/frontend/src/components/importForm.tsx index f6de756..d26fa9d 100644 --- a/frontend/src/components/importForm.tsx +++ b/frontend/src/components/importForm.tsx @@ -5,6 +5,7 @@ import { useMainContext } from "../contexts/mainContext"; import { DeploymentForProjectSheet, ProjectsService, ProjectWithDeployment } from "../client"; import { useParams } from "react-router-dom"; import { useTranslation } from "react-i18next"; +import ButtonInteract from "./common/buttonInteract"; const ImportForm = ( diff --git a/keycloak/Dockerfile b/keycloak/Dockerfile index 7cfc756..6d6c418 100644 --- a/keycloak/Dockerfile +++ b/keycloak/Dockerfile @@ -1,10 +1,5 @@ -FROM registry.access.redhat.com/ubi9 AS ubi-micro-build -RUN mkdir -p /mnt/rootfs -RUN dnf install --installroot /mnt/rootfs curl --releasever 9 --setopt install_weak_deps=false --nodocs -y; dnf --installroot /mnt/rootfs clean all - FROM quay.io/keycloak/keycloak:21.1.0 -COPY --from=ubi-micro-build /mnt/rootfs / COPY ./realm.json /opt/keycloak/data/import/realm.json COPY ./theme/customtheme /opt/keycloak/themes/customtheme diff --git a/scripts/docker.sh b/scripts/docker.sh index d3bcace..7bc6fb3 100755 --- a/scripts/docker.sh +++ b/scripts/docker.sh @@ -10,8 +10,18 @@ fi PROJECT_NAME="geonature-annotation" +DOCKER_VERSION=$(docker version --format '{{.Server.Version}}') +VERSION_PARTS=(${DOCKER_VERSION//./ }) + +if ((${VERSION_PARTS[0]} < 24 || (${VERSION_PARTS[0]} == 0 && ${VERSION_PARTS[1]} < 0))); then + COMPOSE_COMMAND='docker-compose' +else + COMPOSE_COMMAND='docker compose' +fi + + if [ "$ENV" == "production" ]; then - docker-compose --project-name=${PROJECT_NAME} -f ./docker/docker-compose.yml -f ./docker/docker-compose.prod.yml "$@" + $COMPOSE_COMMAND --project-name=${PROJECT_NAME} -f ./docker/docker-compose.yml -f ./docker/docker-compose.prod.yml "$@" else - docker-compose --project-name=${PROJECT_NAME} --project-directory=./docker "$@" + $COMPOSE_COMMAND --project-name=${PROJECT_NAME} --project-directory=./docker "$@" fi