From 5598fa51567b09c0c959078a50cb82b7d0e7f556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ty=C5=84ski?= Date: Sat, 3 Oct 2026 20:23:25 +0200 Subject: [PATCH] build(docker): add container setup with persistent ./data volume Add a multi-stage Dockerfile (Vue build + .NET 10 publish) and a docker-compose service exposing port 8080 with a single bind mount ./data -> /app/data for SurrealDB persistence. Include an example compose file, a .dockerignore, and document Docker usage and version 0.0.1 in the README. --- .dockerignore | 27 +++++++++++++++++++++ .gitignore | 7 ++++++ Dockerfile | 46 +++++++++++++++++++++++++++++++++++ README.md | 31 ++++++++++++++++++++---- docker-compose.yaml | 31 ++++++++++++++++++++++++ docker-compose.yaml.example | 48 +++++++++++++++++++++++++++++++++++++ 6 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yaml create mode 100644 docker-compose.yaml.example diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1fbaf8d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,27 @@ +# Git / IDE +.git +.gitignore +.vs +.idea +.vscode +*.user + +# .NET build artifacts +**/bin +**/obj + +# Node +**/node_modules + +# Build output (budowany wewnątrz obrazu) +client/dist +backend/wwwroot + +# Local SurrealDB data — dostarczane przez wolumen ./data +data +backend/data + +# Env / docs +.env +.env.* +backend/local-docs diff --git a/.gitignore b/.gitignore index ecaaac5..65e714f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ Thumbs.db bin/ obj/ +# Local SurrealDB data (embedded RocksDB) — persisted next to the running app +data/ + # Node node_modules/ dist/ @@ -28,3 +31,7 @@ backend/local-docs/ .env .env.* !.env.example + +# Docker — lokalne nadpisania +docker-compose.override.yaml +docker-compose.override.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7779aca --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +# syntax=docker/dockerfile:1 + +# --- Stage 1: build klienta (Vue 3 + Vite) --- +FROM node:22-alpine AS client +WORKDIR /src/client +COPY client/package.json client/package-lock.json ./ +RUN npm ci +COPY client/ ./ +RUN npm run build + +# --- Stage 2: build i publish backendu (ASP.NET Core, .NET 10) --- +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build +WORKDIR /src +COPY backend/TarninaHub.csproj ./backend/ +RUN dotnet restore ./backend/TarninaHub.csproj +COPY backend/ ./backend/ +COPY --from=client /src/client/dist ./backend/wwwroot/ +RUN dotnet publish ./backend/TarninaHub.csproj \ + --configuration Release \ + --output /app/publish \ + /p:UseAppHost=false + +# --- Stage 3: runtime --- +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime +WORKDIR /app + +ARG APP_VERSION=0.0.1 +LABEL org.opencontainers.image.title="TarninaHub" \ + org.opencontainers.image.version="${APP_VERSION}" + +RUN apt-get update \ + && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + +ENV ASPNETCORE_ENVIRONMENT=Production \ + ASPNETCORE_URLS=http://+:8080 \ + DOTNET_EnableDiagnostics=0 + +COPY --from=build /app/publish ./ + +# Jedyny wolumen aplikacji: trwałe dane SurrealDB (embedded RocksDB). +RUN mkdir -p /app/data +VOLUME ["/app/data"] + +EXPOSE 8080 +ENTRYPOINT ["dotnet", "TarninaHub.dll"] diff --git a/README.md b/README.md index a53aab7..f65b417 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,14 @@ -# hubmi +# TarninaHub + +**Wersja: 0.0.1** Platforma Małopolskiego Hubu Innowacji Społecznych (MVP hackathonu). -- **backend/** — aplikacja backendowa w C# (ASP.NET Core, `HubMi.Api`). +- **backend/** — aplikacja backendowa w C# (ASP.NET Core, `TarninaHub`). - **client/** — aplikacja frontendowa Vue 3 + TypeScript (Vite). - **scripts/** — skrypty budujące całość. -- `HubMi.slnx` — solution .NET. +- `TarninaHub.slnx` — solution .NET. +- `Dockerfile` + `docker-compose.yaml` — uruchomienie kontenerowe. ## Wymagania @@ -34,15 +37,33 @@ npm --prefix client run copy # kopiuje client/dist -> backend/wwwroot node scripts/build.mjs # buduje całość (client + copy + backend) ``` +## Docker + +```pwsh +cp docker-compose.yaml.example docker-compose.yaml +docker compose up --build +``` + +- Aplikacja: http://localhost:8080 +- Dane: `./data` (bind mount, trwałe — SurrealDB embedded RocksDB) +- Obraz: `tarninahub:0.0.1` + +Wolumen hosta można wskazać zmienną `TARNINAHUB_PORT` (domyślnie `8080`). +Plik `docker-compose.yaml.example` jest szablonem; `docker-compose.yaml` możesz +dostosować lokalnie. + ## Struktura ``` -hubmi/ +TarninaHub/ ├─ backend/ # ASP.NET Core Web API + wwwroot (build z client) ├─ client/ # Vue 3 + TS + Vite ├─ scripts/ │ ├─ build.mjs # build całości │ └─ copy-client.mjs # client/dist -> backend/wwwroot -├─ HubMi.slnx +├─ Dockerfile # multi-stage: client + backend +├─ docker-compose.yaml # uruchomienie (bind ./data) +├─ docker-compose.yaml.example +├─ TarninaHub.slnx └─ README.md ``` diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..208a9d4 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,31 @@ +name: tarninahub + +services: + app: + image: tarninahub:0.0.1 + build: + context: . + dockerfile: Dockerfile + args: + APP_VERSION: 0.0.1 + container_name: tarninahub + restart: unless-stopped + # RocksDB zapisuje do bind-mountu ./data; root upraszcza uprawnienia (MVP). + user: "0:0" + ports: + - "${TARNINAHUB_PORT:-8080}:8080" + environment: + ASPNETCORE_ENVIRONMENT: Production + ASPNETCORE_URLS: http://+:8080 + SurrealDb__Namespace: hubmi + SurrealDb__Database: hubmi + SurrealDb__DataDirectory: data + volumes: + # Jedyny volumen aplikacji — trwałe dane (SurrealDB / RocksDB). + - ./data:/app/data + healthcheck: + test: ["CMD", "curl", "-fsS", "http://localhost:8080/api/health"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s diff --git a/docker-compose.yaml.example b/docker-compose.yaml.example new file mode 100644 index 0000000..1822ec3 --- /dev/null +++ b/docker-compose.yaml.example @@ -0,0 +1,48 @@ +# TarninaHub — szablon docker-compose (wersja projektu 0.0.1) +# +# Użycie: +# cp docker-compose.yaml.example docker-compose.yaml +# docker compose up --build +# +# Aplikacja: http://localhost:8080 +# Dane: ./data (bind mount, trwałe, SurrealDB embedded RocksDB) + +name: tarninahub + +services: + app: + # Obraz budowany lokalnie z Dockerfile (multi-stage: klient Vue + backend .NET). + image: tarninahub:${APP_VERSION:-0.0.1} + build: + context: . + dockerfile: Dockerfile + args: + APP_VERSION: ${APP_VERSION:-0.0.1} + container_name: tarninahub + restart: unless-stopped + # RocksDB zapisuje do bind-mountu ./data; root upraszcza uprawnienia (MVP). + # W produkcji użyj named volume albo dopasuj właściciela katalogu ./data. + user: "0:0" + ports: + - "${TARNINAHUB_PORT:-8080}:8080" + environment: + ASPNETCORE_ENVIRONMENT: Production + ASPNETCORE_URLS: http://+:8080 + # SurrealDB — wbudowany silnik RocksDB (domyślnie), dane w /app/data. + SurrealDb__Namespace: hubmi + SurrealDb__Database: hubmi + SurrealDb__DataDirectory: data + # Tryb zdalny (opcjonalnie) — wskaż zewnętrzny serwer SurrealDB zamiast + # wbudowanego RocksDB. Wtedy usuń `user: "0:0"` i przekieruj port 8010. + # SurrealDb__RemoteUrl: ws://127.0.0.1:8010/rpc + # SurrealDb__Username: root + # SurrealDb__Password: root + volumes: + # Jedyny volumen aplikacji — trwałe dane (SurrealDB / RocksDB). + - ./data:/app/data + healthcheck: + test: ["CMD", "curl", "-fsS", "http://localhost:8080/api/health"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s