From b6e4aa7622a0f64f03a7f65805781d487064454e Mon Sep 17 00:00:00 2001 From: Felipe Canin Novaes Date: Sat, 14 Mar 2026 20:56:21 -0300 Subject: [PATCH] feat: add Docker support with Dockerfile and docker-compose, update API URLs to use base_url --- .claude/settings.local.json | 5 ++- backend/.dockerignore | 5 +++ backend/Dockerfile | 40 +++++++++++++++++++ .../MewoSpool/Auth/Forgot Password.yml | 2 +- backend/bruno-routes/MewoSpool/Auth/Login.yml | 2 +- .../bruno-routes/MewoSpool/Auth/Logout.yml | 2 +- .../MewoSpool/Auth/OAuth Google.yml | 2 +- .../MewoSpool/Auth/Refresh Token.yml | 2 +- .../bruno-routes/MewoSpool/Auth/Register.yml | 2 +- .../MewoSpool/Auth/Reset Password.yml | 2 +- .../MewoSpool/Auth/Verify Email.yml | 2 +- backend/bruno-routes/MewoSpool/Dashboard.yml | 2 +- .../MewoSpool/Filaments/Create Filament.yml | 2 +- .../MewoSpool/Filaments/Delete Filament.yml | 2 +- .../MewoSpool/Filaments/Export Label SVG.yml | 2 +- .../MewoSpool/Filaments/Get Filament.yml | 2 +- .../MewoSpool/Filaments/Get QR Code.yml | 2 +- .../MewoSpool/Filaments/List Filaments.yml | 2 +- .../MewoSpool/Filaments/Update Filament.yml | 2 +- .../SpoolPresets/Create Spool Preset.yml | 2 +- .../SpoolPresets/Delete Spool Preset.yml | 2 +- .../SpoolPresets/List Spool Presets.yml | 2 +- .../SpoolPresets/Update Spool Preset.yml | 2 +- .../bruno-routes/MewoSpool/Users/Get Me.yml | 2 +- .../MewoSpool/Users/Update Me.yml | 2 +- .../MewoSpool/environments/route.yml | 6 ++- docker-compose.yml | 35 ++++++++++++++++ 27 files changed, 110 insertions(+), 25 deletions(-) create mode 100644 backend/.dockerignore create mode 100644 backend/Dockerfile create mode 100644 docker-compose.yml diff --git a/.claude/settings.local.json b/.claude/settings.local.json index eba9fbf..8b1db4f 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -12,7 +12,10 @@ "Bash(grep -rE '\"\"@adapters\"\"' tsconfig*.json babel.config.*)", "Bash(grep -n \"pub struct Line\\\\|pub fn add_shape\\\\|fn add_polygon\\\\|fn add_rect\\\\|PdfLayerReference\" /home/felipecn/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/printpdf-0.7.0/src/*.rs)", "mcp__paper__get_basic_info", - "mcp__paper__get_screenshot" + "mcp__paper__get_screenshot", + "Bash(find /var/home/felipecn/DEV/MeowSpool/backend/bruno-routes -name \"*.yml\" ! -name \"route.yml\" -exec sed -i 's|http://0\\\\.0\\\\.0\\\\.0:8080|{{base_url}}|g; s|https://meowspool\\\\.felipecncloud\\\\.com|{{base_url}}|g' {} +)", + "Bash(find /var/home/felipecn/DEV/MeowSpool/backend/bruno-routes -name \"*.yml\" ! -name \"route.yml\" ! -name \"Dashboard.yml\" -exec sed -i 's| url: \\\\\\({{.*}}\\\\\\)| url: \"\"\\\\1\"\"|g' {} +)", + "Bash(find /var/home/felipecn/DEV/MeowSpool/backend/bruno-routes -name \"*.yml\" ! -name \"route.yml\" -exec sed -i 's| url: \"\"\\\\?\\\\\\(.*\\\\\\)\"\"\\\\?$| url: \"\"\\\\1\"\"|g; s| url: \"\"\\\\\\(.*\\\\\\)\"\"\"\"\\\\?$| url: \"\"\\\\1\"\"|g' {} +)" ] } } diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..459109f --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,5 @@ +target/ +.env +.git +.gitignore +*.md diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..cfff09b --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,40 @@ +# ── Stage 1: builder ────────────────────────────────────────────────────────── +FROM rust:1.88-slim-bookworm AS builder + +# Build dependencies for native libs (OpenSSL via rustls not needed, but sqlx needs pkg-config) +RUN apt-get update && apt-get install -y --no-install-recommends \ + pkg-config \ + libssl-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +# Cache dependency compilation separately from source +COPY Cargo.toml Cargo.lock ./ + +# Create a dummy main so Cargo can compile deps without our source +RUN mkdir src && echo "fn main() {}" > src/main.rs +RUN cargo build --release --bin meowspool 2>/dev/null; true + +# Now copy real source and migrations +COPY src ./src +COPY migrations ./migrations + +# Touch main.rs so Cargo knows it changed, then build for real +RUN touch src/main.rs && cargo build --release --bin meowspool + +# ── Stage 2: runtime ────────────────────────────────────────────────────────── +FROM debian:bookworm-slim AS runtime + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY --from=builder /app/target/release/meowspool ./meowspool +COPY --from=builder /app/migrations ./migrations + +EXPOSE 8080 + +CMD ["./meowspool"] diff --git a/backend/bruno-routes/MewoSpool/Auth/Forgot Password.yml b/backend/bruno-routes/MewoSpool/Auth/Forgot Password.yml index 7d9a32a..da66f60 100644 --- a/backend/bruno-routes/MewoSpool/Auth/Forgot Password.yml +++ b/backend/bruno-routes/MewoSpool/Auth/Forgot Password.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: http://0.0.0.0:8080/api/v1/auth/forgot-password + url: "{{base_url}}/api/v1/auth/forgot-password" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Auth/Login.yml b/backend/bruno-routes/MewoSpool/Auth/Login.yml index bd02208..8a02fdb 100644 --- a/backend/bruno-routes/MewoSpool/Auth/Login.yml +++ b/backend/bruno-routes/MewoSpool/Auth/Login.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: https://meowspool.felipecncloud.com/api/v1/auth/login + url: "{{base_url}}/api/v1/auth/login" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Auth/Logout.yml b/backend/bruno-routes/MewoSpool/Auth/Logout.yml index 8dcd385..f0f0e64 100644 --- a/backend/bruno-routes/MewoSpool/Auth/Logout.yml +++ b/backend/bruno-routes/MewoSpool/Auth/Logout.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: http://0.0.0.0:8080/api/v1/auth/logout + url: "{{base_url}}/api/v1/auth/logout" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Auth/OAuth Google.yml b/backend/bruno-routes/MewoSpool/Auth/OAuth Google.yml index 7db25d7..0567aeb 100644 --- a/backend/bruno-routes/MewoSpool/Auth/OAuth Google.yml +++ b/backend/bruno-routes/MewoSpool/Auth/OAuth Google.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: http://0.0.0.0:8080/api/v1/auth/oauth/google + url: "{{base_url}}/api/v1/auth/oauth/google" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Auth/Refresh Token.yml b/backend/bruno-routes/MewoSpool/Auth/Refresh Token.yml index a6bd4c3..ea5925e 100644 --- a/backend/bruno-routes/MewoSpool/Auth/Refresh Token.yml +++ b/backend/bruno-routes/MewoSpool/Auth/Refresh Token.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: http://0.0.0.0:8080/api/v1/auth/refresh + url: "{{base_url}}/api/v1/auth/refresh" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Auth/Register.yml b/backend/bruno-routes/MewoSpool/Auth/Register.yml index c80ad4e..4156377 100644 --- a/backend/bruno-routes/MewoSpool/Auth/Register.yml +++ b/backend/bruno-routes/MewoSpool/Auth/Register.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: http://0.0.0.0:8080/api/v1/auth/register + url: "{{base_url}}/api/v1/auth/register" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Auth/Reset Password.yml b/backend/bruno-routes/MewoSpool/Auth/Reset Password.yml index cbf7d27..67bab7a 100644 --- a/backend/bruno-routes/MewoSpool/Auth/Reset Password.yml +++ b/backend/bruno-routes/MewoSpool/Auth/Reset Password.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: http://0.0.0.0:8080/api/v1/auth/reset-password + url: "{{base_url}}/api/v1/auth/reset-password" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Auth/Verify Email.yml b/backend/bruno-routes/MewoSpool/Auth/Verify Email.yml index fe965d3..2cb6f69 100644 --- a/backend/bruno-routes/MewoSpool/Auth/Verify Email.yml +++ b/backend/bruno-routes/MewoSpool/Auth/Verify Email.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: http://0.0.0.0:8080/api/v1/auth/verify-email + url: "{{base_url}}/api/v1/auth/verify-email" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Dashboard.yml b/backend/bruno-routes/MewoSpool/Dashboard.yml index 718bd9f..adf8a3f 100644 --- a/backend/bruno-routes/MewoSpool/Dashboard.yml +++ b/backend/bruno-routes/MewoSpool/Dashboard.yml @@ -5,7 +5,7 @@ info: http: method: GET - url: http://0.0.0.0:8080/api/v1/dashboard + url: "{{base_url}}/api/v1/dashboard" auth: type: bearer token: "{{access_token}}" diff --git a/backend/bruno-routes/MewoSpool/Filaments/Create Filament.yml b/backend/bruno-routes/MewoSpool/Filaments/Create Filament.yml index 35fa274..f431d31 100644 --- a/backend/bruno-routes/MewoSpool/Filaments/Create Filament.yml +++ b/backend/bruno-routes/MewoSpool/Filaments/Create Filament.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: http://0.0.0.0:8080/api/v1/filaments + url: "{{base_url}}/api/v1/filaments" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Filaments/Delete Filament.yml b/backend/bruno-routes/MewoSpool/Filaments/Delete Filament.yml index b9ebe6e..af8cf4b 100644 --- a/backend/bruno-routes/MewoSpool/Filaments/Delete Filament.yml +++ b/backend/bruno-routes/MewoSpool/Filaments/Delete Filament.yml @@ -5,7 +5,7 @@ info: http: method: DELETE - url: http://0.0.0.0:8080/api/v1/filaments/{{filament_id}} + url: "{{base_url}}/api/v1/filaments/{{filament_id}}" auth: type: bearer token: "{{access_token}}" diff --git a/backend/bruno-routes/MewoSpool/Filaments/Export Label SVG.yml b/backend/bruno-routes/MewoSpool/Filaments/Export Label SVG.yml index 72855ec..a97f6fe 100644 --- a/backend/bruno-routes/MewoSpool/Filaments/Export Label SVG.yml +++ b/backend/bruno-routes/MewoSpool/Filaments/Export Label SVG.yml @@ -5,7 +5,7 @@ info: http: method: GET - url: http://0.0.0.0:8080/api/v1/filaments/{{filament_id}}/label.svg + url: "{{base_url}}/api/v1/filaments/{{filament_id}}/label.svg" params: - name: width_mm value: "80" diff --git a/backend/bruno-routes/MewoSpool/Filaments/Get Filament.yml b/backend/bruno-routes/MewoSpool/Filaments/Get Filament.yml index 295d9dd..7046eae 100644 --- a/backend/bruno-routes/MewoSpool/Filaments/Get Filament.yml +++ b/backend/bruno-routes/MewoSpool/Filaments/Get Filament.yml @@ -5,7 +5,7 @@ info: http: method: GET - url: http://0.0.0.0:8080/api/v1/filaments/{{filament_id}} + url: "{{base_url}}/api/v1/filaments/{{filament_id}}" auth: type: bearer token: "{{access_token}}" diff --git a/backend/bruno-routes/MewoSpool/Filaments/Get QR Code.yml b/backend/bruno-routes/MewoSpool/Filaments/Get QR Code.yml index 0084da8..aa488db 100644 --- a/backend/bruno-routes/MewoSpool/Filaments/Get QR Code.yml +++ b/backend/bruno-routes/MewoSpool/Filaments/Get QR Code.yml @@ -5,7 +5,7 @@ info: http: method: GET - url: http://0.0.0.0:8080/api/v1/filaments/{{filament_id}}/qrcode + url: "{{base_url}}/api/v1/filaments/{{filament_id}}/qrcode" auth: type: bearer token: "{{access_token}}" diff --git a/backend/bruno-routes/MewoSpool/Filaments/List Filaments.yml b/backend/bruno-routes/MewoSpool/Filaments/List Filaments.yml index 2f0f7c5..83d7583 100644 --- a/backend/bruno-routes/MewoSpool/Filaments/List Filaments.yml +++ b/backend/bruno-routes/MewoSpool/Filaments/List Filaments.yml @@ -5,7 +5,7 @@ info: http: method: GET - url: http://0.0.0.0:8080/api/v1/filaments + url: "{{base_url}}/api/v1/filaments" params: - name: page value: "1" diff --git a/backend/bruno-routes/MewoSpool/Filaments/Update Filament.yml b/backend/bruno-routes/MewoSpool/Filaments/Update Filament.yml index 98ddc93..97d66e2 100644 --- a/backend/bruno-routes/MewoSpool/Filaments/Update Filament.yml +++ b/backend/bruno-routes/MewoSpool/Filaments/Update Filament.yml @@ -5,7 +5,7 @@ info: http: method: PUT - url: http://0.0.0.0:8080/api/v1/filaments/{{filament_id}} + url: "{{base_url}}/api/v1/filaments/{{filament_id}}" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/SpoolPresets/Create Spool Preset.yml b/backend/bruno-routes/MewoSpool/SpoolPresets/Create Spool Preset.yml index 6e90d3f..9b5aeb1 100644 --- a/backend/bruno-routes/MewoSpool/SpoolPresets/Create Spool Preset.yml +++ b/backend/bruno-routes/MewoSpool/SpoolPresets/Create Spool Preset.yml @@ -5,7 +5,7 @@ info: http: method: POST - url: http://0.0.0.0:8080/api/v1/spool-presets + url: "{{base_url}}/api/v1/spool-presets" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/SpoolPresets/Delete Spool Preset.yml b/backend/bruno-routes/MewoSpool/SpoolPresets/Delete Spool Preset.yml index 0d930aa..589ffca 100644 --- a/backend/bruno-routes/MewoSpool/SpoolPresets/Delete Spool Preset.yml +++ b/backend/bruno-routes/MewoSpool/SpoolPresets/Delete Spool Preset.yml @@ -5,7 +5,7 @@ info: http: method: DELETE - url: http://0.0.0.0:8080/api/v1/spool-presets/{{preset_id}} + url: "{{base_url}}/api/v1/spool-presets/{{preset_id}}" auth: type: bearer token: "{{access_token}}" diff --git a/backend/bruno-routes/MewoSpool/SpoolPresets/List Spool Presets.yml b/backend/bruno-routes/MewoSpool/SpoolPresets/List Spool Presets.yml index c2aa136..a22b334 100644 --- a/backend/bruno-routes/MewoSpool/SpoolPresets/List Spool Presets.yml +++ b/backend/bruno-routes/MewoSpool/SpoolPresets/List Spool Presets.yml @@ -5,7 +5,7 @@ info: http: method: GET - url: http://0.0.0.0:8080/api/v1/spool-presets + url: "{{base_url}}/api/v1/spool-presets" auth: type: bearer token: "{{access_token}}" diff --git a/backend/bruno-routes/MewoSpool/SpoolPresets/Update Spool Preset.yml b/backend/bruno-routes/MewoSpool/SpoolPresets/Update Spool Preset.yml index e9e1cae..cd190d1 100644 --- a/backend/bruno-routes/MewoSpool/SpoolPresets/Update Spool Preset.yml +++ b/backend/bruno-routes/MewoSpool/SpoolPresets/Update Spool Preset.yml @@ -5,7 +5,7 @@ info: http: method: PUT - url: http://0.0.0.0:8080/api/v1/spool-presets/{{preset_id}} + url: "{{base_url}}/api/v1/spool-presets/{{preset_id}}" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/Users/Get Me.yml b/backend/bruno-routes/MewoSpool/Users/Get Me.yml index 4cba86f..ebd937a 100644 --- a/backend/bruno-routes/MewoSpool/Users/Get Me.yml +++ b/backend/bruno-routes/MewoSpool/Users/Get Me.yml @@ -5,7 +5,7 @@ info: http: method: GET - url: http://0.0.0.0:8080/api/v1/users/me + url: "{{base_url}}/api/v1/users/me" auth: type: bearer token: "{{access_token}}" diff --git a/backend/bruno-routes/MewoSpool/Users/Update Me.yml b/backend/bruno-routes/MewoSpool/Users/Update Me.yml index 56a85be..d84283d 100644 --- a/backend/bruno-routes/MewoSpool/Users/Update Me.yml +++ b/backend/bruno-routes/MewoSpool/Users/Update Me.yml @@ -5,7 +5,7 @@ info: http: method: PUT - url: http://0.0.0.0:8080/api/v1/users/me + url: "{{base_url}}/api/v1/users/me" body: type: json data: |- diff --git a/backend/bruno-routes/MewoSpool/environments/route.yml b/backend/bruno-routes/MewoSpool/environments/route.yml index b78ac8a..425ab60 100644 --- a/backend/bruno-routes/MewoSpool/environments/route.yml +++ b/backend/bruno-routes/MewoSpool/environments/route.yml @@ -1,10 +1,12 @@ name: route variables: + - name: base_url + value: https://meowspool.felipecncloud.com - secret: true name: access_token - secret: true name: refresh_token - name: preset_id - value: 88eab1b9-e979-46db-940f-59cac97df60b + value: 07188f3b-2b74-4251-88bc-037de7628d65 - name: filament_id - value: da5e431c-bc2e-4075-aa1c-ce82ee9567b4 + value: "" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..064bdba --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,35 @@ +services: + db: + image: postgres:16-alpine + restart: unless-stopped + env_file: .env + environment: + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB} + volumes: + - postgres_data:/var/lib/postgresql/data + ports: + - "${POSTGRES_PORT:-5432}:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + interval: 5s + timeout: 5s + retries: 5 + + backend: + build: + context: ./backend + dockerfile: Dockerfile + restart: unless-stopped + env_file: .env + environment: + DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} + ports: + - "${PORT:-8080}:8080" + depends_on: + db: + condition: service_healthy + +volumes: + postgres_data: