From 3b9913febafe1db12e1a43235b649fa841818497 Mon Sep 17 00:00:00 2001 From: ReLoia Date: Wed, 10 Jun 2026 12:51:48 +0200 Subject: [PATCH 1/8] update CORS configuration to support multiple allowed origins --- common/Cors.cc | 76 ++++++++++++++++++++++++++++++++++++++++++++------ config.json | 4 +-- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/common/Cors.cc b/common/Cors.cc index 6d1fc33..45881c5 100644 --- a/common/Cors.cc +++ b/common/Cors.cc @@ -6,33 +6,91 @@ namespace visione::cors { namespace { -std::string allowedOrigin() +std::vector allowedOrigins() { - return drogon::app() - .getCustomConfig()["cors"] - .get("allowed_origin", "http://localhost:5173") - .asString(); + auto cfg = drogon::app().getCustomConfig(); + std::vector origins; + + if (cfg.isMember("cors") && cfg["cors"].isObject()) + { + auto &c = cfg["cors"]; + if (c.isMember("allowed_origin")) + { + auto &v = c["allowed_origin"]; + if (v.isArray()) + { + for (const auto &el : v) + { + if (el.isString()) + origins.emplace_back(el.asString()); + } + } + else if (v.isString()) + { + origins.emplace_back(v.asString()); + } + } + } + + if (origins.empty()) + origins.emplace_back("http://localhost:5173"); + + return origins; } bool isAllowed(const drogon::HttpRequestPtr &request) { - return request->getHeader("Origin") == allowedOrigin(); + auto origin = request->getHeader("Origin"); + if (origin.empty()) + return false; + + auto origins = allowedOrigins(); + for (const auto &o : origins) + { + if (o == "*" || o == origin) + return true; + } + return false; } void addHeaders(const drogon::HttpRequestPtr &request, const drogon::HttpResponsePtr &response) { - if (!isAllowed(request)) - { + auto origin = request->getHeader("Origin"); + if (origin.empty()) return; + + auto origins = allowedOrigins(); + bool allowAll = false; + bool matched = false; + for (const auto &o : origins) + { + if (o == "*") + { + allowAll = true; + break; + } + if (o == origin) + { + matched = true; + break; + } } - response->addHeader("Access-Control-Allow-Origin", allowedOrigin()); + if (!allowAll && !matched) + return; + + if (allowAll) + response->addHeader("Access-Control-Allow-Origin", "*"); + else + response->addHeader("Access-Control-Allow-Origin", origin); + response->addHeader("Access-Control-Allow-Credentials", "true"); response->addHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE,OPTIONS"); response->addHeader("Access-Control-Allow-Headers", "Authorization,Content-Type"); + response->addHeader("Vary", "Origin"); } } // namespace diff --git a/config.json b/config.json index 66782bc..e7bfd4d 100644 --- a/config.json +++ b/config.json @@ -63,7 +63,7 @@ "spec_path": "build/openapi/visione.openapi.json" }, "cors": { - "allowed_origin": "http://localhost:5173" + "allowed_origin": ["http://localhost:3000", "http://localhost:5137"] } } -} +} \ No newline at end of file From 80cebeaf9c6158d6c2071b3baa5778beb2aef0d0 Mon Sep 17 00:00:00 2001 From: ReLoia Date: Wed, 10 Jun 2026 12:52:22 +0200 Subject: [PATCH 2/8] add Dockerfile and docker-compose for backend and database services --- Dockerfile | 39 +++++++++++++++++++++++++++ docker-compose.development.yaml | 47 +++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.development.yaml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..06e5f28 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +# --- Builder Stage --- +FROM ubuntu:22.04 AS builder +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential cmake ninja-build git pkg-config \ + libssl-dev zlib1g-dev \ + libmariadb-dev libmariadb-dev-compat \ + libsqlite3-dev python3 libjsoncpp-dev uuid-dev ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +RUN rm -rf /usr/include/mysql && ln -s /usr/include/mariadb /usr/include/mysql + +WORKDIR /app +COPY . /app + +RUN cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \ + && cmake --build build -- -j$(nproc) + +# --- Runtime Stage --- +FROM ubuntu:22.04 AS runtime +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + libssl3 ca-certificates libstdc++6 libmariadb3 libjsoncpp25 libuuid1 \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY --from=builder /app/build/visione-backend /app/visione-backend +COPY --from=builder /app/build/openapi /app/build/openapi +COPY --from=builder /app/migrations /app/migrations + +EXPOSE 5555 + +RUN chown -R 1000:1000 /app +USER 1000:1000 + +ENTRYPOINT ["/app/visione-backend"] \ No newline at end of file diff --git a/docker-compose.development.yaml b/docker-compose.development.yaml new file mode 100644 index 0000000..ff8e9e3 --- /dev/null +++ b/docker-compose.development.yaml @@ -0,0 +1,47 @@ +services: + backend: + build: + context: . + dockerfile: Dockerfile + ports: + - "${BACKEND_PORT:-5555}:5555" + volumes: + - ./config.json:/app/config.json + environment: + - DB_HOST=mysql + - DB_PORT=3306 + - DB_USER=${MYSQL_USER:-visione} + - DB_PASSWORD=${MYSQL_PASSWORD:-visione} + - DB_NAME=${MYSQL_DATABASE:-visione} + - SMTP_HOST=mailhog + - SMTP_PORT=1025 + depends_on: + mysql: + condition: service_healthy + + mysql: + image: mysql:8.4 + environment: + MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:-root}" + MYSQL_DATABASE: "${MYSQL_DATABASE:-visione}" + MYSQL_USER: "${MYSQL_USER:-visione}" + MYSQL_PASSWORD: "${MYSQL_PASSWORD:-visione}" + ports: + - "${MYSQL_PORT:-3306}:3306" + volumes: + - mysql-data:/var/lib/mysql + healthcheck: + test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u$${MYSQL_USER} -p$${MYSQL_PASSWORD} --silent"] + interval: 5s + timeout: 5s + retries: 20 + start_period: 20s + + mailhog: + image: mailhog/mailhog:v1.0.1 + ports: + - "${MAILHOG_SMTP_PORT:-1025}:1025" + - "${MAILHOG_WEB_PORT:-8025}:8025" + +volumes: + mysql-data: \ No newline at end of file From 2dd8be41ac8013f660026358fcb64cd897b1d1fe Mon Sep 17 00:00:00 2001 From: gabdevele Date: Wed, 10 Jun 2026 21:26:03 +0200 Subject: [PATCH 3/8] refactor Dockerfile and docker-compose --- .dockerignore | 7 ++++ Dockerfile | 33 ++++--------------- ...development.yaml => docker-compose.dev.yml | 0 3 files changed, 13 insertions(+), 27 deletions(-) create mode 100644 .dockerignore rename docker-compose.development.yaml => docker-compose.dev.yml (100%) diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a21dafa --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +build/ +.git/ +.vscode/ +.cache/ +uploads/ +.env +.env.example \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 06e5f28..d67088e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,39 +1,18 @@ -# --- Builder Stage --- -FROM ubuntu:22.04 AS builder -ENV DEBIAN_FRONTEND=noninteractive - -RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential cmake ninja-build git pkg-config \ - libssl-dev zlib1g-dev \ - libmariadb-dev libmariadb-dev-compat \ - libsqlite3-dev python3 libjsoncpp-dev uuid-dev ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -RUN rm -rf /usr/include/mysql && ln -s /usr/include/mariadb /usr/include/mysql +FROM drogonframework/drogon:latest WORKDIR /app COPY . /app -RUN cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \ - && cmake --build build -- -j$(nproc) - -# --- Runtime Stage --- -FROM ubuntu:22.04 AS runtime -ENV DEBIAN_FRONTEND=noninteractive - -RUN apt-get update && apt-get install -y --no-install-recommends \ - libssl3 ca-certificates libstdc++6 libmariadb3 libjsoncpp25 libuuid1 \ +# funziona anche senza ma ninja rende il build dell'immagine più veloce +RUN apt-get update && apt-get install -y --no-install-recommends ninja-build \ && rm -rf /var/lib/apt/lists/* -WORKDIR /app - -COPY --from=builder /app/build/visione-backend /app/visione-backend -COPY --from=builder /app/build/openapi /app/build/openapi -COPY --from=builder /app/migrations /app/migrations +RUN cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \ + && cmake --build build EXPOSE 5555 RUN chown -R 1000:1000 /app USER 1000:1000 -ENTRYPOINT ["/app/visione-backend"] \ No newline at end of file +ENTRYPOINT ["/app/build/visione-backend"] \ No newline at end of file diff --git a/docker-compose.development.yaml b/docker-compose.dev.yml similarity index 100% rename from docker-compose.development.yaml rename to docker-compose.dev.yml From 3edbc0edd4fa19ee0ea6df743dcb31e1f0a82ce4 Mon Sep 17 00:00:00 2001 From: gabdevele Date: Wed, 10 Jun 2026 21:35:10 +0200 Subject: [PATCH 4/8] fix docker startup config error --- main.cc | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/main.cc b/main.cc index 933dc4c..7854cc0 100644 --- a/main.cc +++ b/main.cc @@ -5,16 +5,46 @@ #include "repositories/MigrationRunner.h" #include +#include +#include int main() { setvbuf(stdout, nullptr, _IONBF, 0); (void)RequestLogger::classTypeName(); + Json::Value config; + std::ifstream configFile("config.json"); + if (configFile.is_open()) + { + configFile >> config; + + if (const char* envHost = std::getenv("DB_HOST")) + config["db_clients"][0]["host"] = envHost; + if (const char* envPort = std::getenv("DB_PORT")) + config["db_clients"][0]["port"] = std::stoi(envPort); + if (const char* envUser = std::getenv("DB_USER")) + config["db_clients"][0]["user"] = envUser; + if (const char* envPass = std::getenv("DB_PASSWORD")) + config["db_clients"][0]["passwd"] = envPass; + if (const char* envDb = std::getenv("DB_NAME")) + config["db_clients"][0]["dbname"] = envDb; + + if (const char* envSmtpHost = std::getenv("SMTP_HOST")) + config["custom_config"]["mail"]["smtp_host"] = envSmtpHost; + if (const char* envSmtpPort = std::getenv("SMTP_PORT")) + config["custom_config"]["mail"]["smtp_port"] = std::stoi(envSmtpPort); + + drogon::app().loadConfigJson(config); + } + else + { + drogon::app().loadConfigFile("config.json"); + } + Json::Value requestLoggerConfig; requestLoggerConfig["include_query"] = true; - drogon::app().loadConfigFile("config.json"); drogon::app().addPlugin("RequestLogger", {}, requestLoggerConfig); visione::cors::configure(); From 7abcc8e78afb088c3ef156f37da47266035ae7b5 Mon Sep 17 00:00:00 2001 From: gabdevele Date: Wed, 10 Jun 2026 21:59:27 +0200 Subject: [PATCH 5/8] restore old dockerfile --- Dockerfile | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index d67088e..b4d7e76 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,39 @@ -FROM drogonframework/drogon:latest +# --- Builder Stage --- +FROM ubuntu:22.04 AS builder +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential cmake ninja-build git pkg-config \ + libssl-dev zlib1g-dev \ + libmariadb-dev libmariadb-dev-compat \ + libsqlite3-dev python3 libjsoncpp-dev uuid-dev ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +RUN rm -rf /usr/include/mysql && ln -s /usr/include/mariadb /usr/include/mysql WORKDIR /app COPY . /app -# funziona anche senza ma ninja rende il build dell'immagine più veloce -RUN apt-get update && apt-get install -y --no-install-recommends ninja-build \ - && rm -rf /var/lib/apt/lists/* - RUN cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \ && cmake --build build +# --- Runtime Stage --- +FROM ubuntu:22.04 AS runtime +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + libssl3 ca-certificates libstdc++6 libmariadb3 libjsoncpp25 libuuid1 \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY --from=builder /app/build/visione-backend /app/visione-backend +COPY --from=builder /app/build/openapi /app/build/openapi +COPY --from=builder /app/migrations /app/migrations + EXPOSE 5555 RUN chown -R 1000:1000 /app USER 1000:1000 -ENTRYPOINT ["/app/build/visione-backend"] \ No newline at end of file +ENTRYPOINT ["/app/visione-backend"] \ No newline at end of file From 3e9a0ca97856c3dad5877dbe0d6841f4b0879e6f Mon Sep 17 00:00:00 2001 From: gabdevele Date: Wed, 10 Jun 2026 23:00:28 +0200 Subject: [PATCH 6/8] Fix Dokploy compose --- README.md | 14 ++++++++++++ docker-compose.dev.yml | 49 ++++++++++++++++++++++++++++-------------- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 13cda15..377d7fa 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,20 @@ ctest --test-dir build --output-on-failure The `RequestLogger` plugin logs every response as method, path, status and client address. +## Dokploy + +Use `docker-compose.dev.yml` as the Dokploy compose path for a self-contained +backend deployment with MySQL and MailHog. Configure the public domain in +Dokploy against service `backend` and container port `5555`. + +Before deploying, create an Advanced Mount named `config.json` in Dokploy and +paste the repository `config.json` content into it. The compose file mounts it +from `../files/config.json` so AutoDeploy does not depend on bind mounts from a +freshly cloned repository. + +Set `MYSQL_PASSWORD`, `MYSQL_ROOT_PASSWORD` and any other environment-specific +values in Dokploy environment variables. + ## Current Endpoints - `GET /api/v1/health`: process health check, no external dependency. diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index ff8e9e3..d77bc7a 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -3,33 +3,41 @@ services: build: context: . dockerfile: Dockerfile - ports: - - "${BACKEND_PORT:-5555}:5555" + restart: unless-stopped volumes: - - ./config.json:/app/config.json + - ../files/config.json:/app/config.json:ro + - uploads-data:/app/uploads environment: - - DB_HOST=mysql - - DB_PORT=3306 - - DB_USER=${MYSQL_USER:-visione} - - DB_PASSWORD=${MYSQL_PASSWORD:-visione} - - DB_NAME=${MYSQL_DATABASE:-visione} - - SMTP_HOST=mailhog - - SMTP_PORT=1025 + DB_HOST: ${DB_HOST:-mysql} + DB_PORT: ${DB_PORT:-3306} + DB_USER: ${MYSQL_USER:-visione} + DB_PASSWORD: ${MYSQL_PASSWORD:-visione} + DB_NAME: ${MYSQL_DATABASE:-visione} + SMTP_HOST: ${SMTP_HOST:-mailhog} + SMTP_PORT: ${SMTP_PORT:-1025} + expose: + - "5555" + networks: + - visione + - dokploy-network depends_on: mysql: condition: service_healthy mysql: image: mysql:8.4 + restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:-root}" MYSQL_DATABASE: "${MYSQL_DATABASE:-visione}" MYSQL_USER: "${MYSQL_USER:-visione}" MYSQL_PASSWORD: "${MYSQL_PASSWORD:-visione}" - ports: - - "${MYSQL_PORT:-3306}:3306" + expose: + - "3306" volumes: - mysql-data:/var/lib/mysql + networks: + - visione healthcheck: test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u$${MYSQL_USER} -p$${MYSQL_PASSWORD} --silent"] interval: 5s @@ -39,9 +47,18 @@ services: mailhog: image: mailhog/mailhog:v1.0.1 - ports: - - "${MAILHOG_SMTP_PORT:-1025}:1025" - - "${MAILHOG_WEB_PORT:-8025}:8025" + restart: unless-stopped + expose: + - "1025" + - "8025" + networks: + - visione volumes: - mysql-data: \ No newline at end of file + mysql-data: + uploads-data: + +networks: + visione: + dokploy-network: + external: true From dd02c6987aac2fad10f90e81bc5974fd17948b28 Mon Sep 17 00:00:00 2001 From: gabdevele Date: Wed, 10 Jun 2026 23:07:22 +0200 Subject: [PATCH 7/8] Update Dockerfile and docker-compose for config.json and Mailpit integration --- Dockerfile | 3 ++- README.md | 12 ++++++------ docker-compose.dev.yml | 3 +-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index b4d7e76..455b9f1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,7 @@ WORKDIR /app COPY --from=builder /app/build/visione-backend /app/visione-backend COPY --from=builder /app/build/openapi /app/build/openapi +COPY --from=builder /app/config.json /app/config.json COPY --from=builder /app/migrations /app/migrations EXPOSE 5555 @@ -36,4 +37,4 @@ EXPOSE 5555 RUN chown -R 1000:1000 /app USER 1000:1000 -ENTRYPOINT ["/app/visione-backend"] \ No newline at end of file +ENTRYPOINT ["/app/visione-backend"] diff --git a/README.md b/README.md index 377d7fa..dd0ba13 100644 --- a/README.md +++ b/README.md @@ -134,13 +134,13 @@ client address. ## Dokploy Use `docker-compose.dev.yml` as the Dokploy compose path for a self-contained -backend deployment with MySQL and MailHog. Configure the public domain in -Dokploy against service `backend` and container port `5555`. +backend deployment with MySQL and a local SMTP catcher. Configure the public +domain in Dokploy against service `backend` and container port `5555`. -Before deploying, create an Advanced Mount named `config.json` in Dokploy and -paste the repository `config.json` content into it. The compose file mounts it -from `../files/config.json` so AutoDeploy does not depend on bind mounts from a -freshly cloned repository. +The runtime image includes `config.json`; override environment-specific values +with Dokploy environment variables. The SMTP catcher service keeps the internal +name `mailhog` for compatibility, but uses the multi-architecture Mailpit image +to avoid `exec format error` failures on ARM servers. Set `MYSQL_PASSWORD`, `MYSQL_ROOT_PASSWORD` and any other environment-specific values in Dokploy environment variables. diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index d77bc7a..3ad1189 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -5,7 +5,6 @@ services: dockerfile: Dockerfile restart: unless-stopped volumes: - - ../files/config.json:/app/config.json:ro - uploads-data:/app/uploads environment: DB_HOST: ${DB_HOST:-mysql} @@ -46,7 +45,7 @@ services: start_period: 20s mailhog: - image: mailhog/mailhog:v1.0.1 + image: axllent/mailpit:latest restart: unless-stopped expose: - "1025" From 59a05acc242339974a17275e89e82d9ead33de3d Mon Sep 17 00:00:00 2001 From: gabdevele Date: Wed, 10 Jun 2026 23:21:34 +0200 Subject: [PATCH 8/8] fix(docker): remove priv desc on startup --- Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 455b9f1..411a3a7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,7 +34,4 @@ COPY --from=builder /app/migrations /app/migrations EXPOSE 5555 -RUN chown -R 1000:1000 /app -USER 1000:1000 - ENTRYPOINT ["/app/visione-backend"]