Compare commits

...
2 Commits
4 changed files with 155 additions and 11 deletions
+39
View File
@@ -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"]
+67 -9
View File
@@ -6,33 +6,91 @@ namespace visione::cors
{ {
namespace namespace
{ {
std::string allowedOrigin() std::vector<std::string> allowedOrigins()
{ {
return drogon::app() auto cfg = drogon::app().getCustomConfig();
.getCustomConfig()["cors"] std::vector<std::string> origins;
.get("allowed_origin", "http://localhost:5173")
.asString(); 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) 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, void addHeaders(const drogon::HttpRequestPtr &request,
const drogon::HttpResponsePtr &response) const drogon::HttpResponsePtr &response)
{ {
if (!isAllowed(request)) auto origin = request->getHeader("Origin");
{ if (origin.empty())
return; 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-Credentials", "true");
response->addHeader("Access-Control-Allow-Methods", response->addHeader("Access-Control-Allow-Methods",
"GET,POST,PATCH,DELETE,OPTIONS"); "GET,POST,PATCH,DELETE,OPTIONS");
response->addHeader("Access-Control-Allow-Headers", response->addHeader("Access-Control-Allow-Headers",
"Authorization,Content-Type"); "Authorization,Content-Type");
response->addHeader("Vary", "Origin");
} }
} // namespace } // namespace
+2 -2
View File
@@ -63,7 +63,7 @@
"spec_path": "build/openapi/visione.openapi.json" "spec_path": "build/openapi/visione.openapi.json"
}, },
"cors": { "cors": {
"allowed_origin": "http://localhost:5173" "allowed_origin": ["http://localhost:3000", "http://localhost:5137"]
} }
} }
} }
+47
View File
@@ -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: