From c9a777b5fbe7cd836c116d33f3dde1389cfa240b Mon Sep 17 00:00:00 2001 From: rafapolo Date: Mon, 30 Mar 2026 18:30:36 +0200 Subject: [PATCH] fix deploy --- .dockerignore | 10 +++++-- Caddyfile | 33 +++++++++++++++++++-- Dockerfile | 69 ++++++++++++++++++++++++++++++++++++++++++++ ask/src/main.rs | 41 +++++++++++++++++++++----- scripts/build_ask.sh | 4 +-- start.sh | 4 +-- 6 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore index be13161..9dad0d0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,10 @@ -ask/target -ask/src .git +.gitignore *.md +.venv +tasks +docs +queries +scripts +haloy.yml +Dockerfile diff --git a/Caddyfile b/Caddyfile index 79fe27b..b43e4e3 100644 --- a/Caddyfile +++ b/Caddyfile @@ -8,8 +8,37 @@ } handle @ask { - reverse_proxy localhost:7682 { - flush_interval -1 + handle /health { + respond 200 + } + + handle /login { + reverse_proxy 127.0.0.1:8081 + } + + handle /query { + reverse_proxy 127.0.0.1:8081 + } + + @websocket { + header Connection *Upgrade* + header Upgrade websocket + } + + handle @websocket { + reverse_proxy localhost:7682 { + flush_interval -1 + } + } + + handle { + forward_auth 127.0.0.1:8081 { + uri /auth + copy_headers Cookie + } + reverse_proxy localhost:7682 { + flush_interval -1 + } } } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c4fc7a7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,69 @@ +FROM --platform=linux/amd64 rust:latest AS builder + +RUN apt-get update -qq && \ + apt-get install -y --no-install-recommends \ + build-essential pkg-config libssl-dev curl unzip musl-tools && \ + curl -fsSL https://github.com/duckdb/duckdb/releases/download/v1.5.1/libduckdb-linux-amd64.zip \ + -o /tmp/libduckdb.zip && \ + unzip -o /tmp/libduckdb.zip -d /usr/local && \ + cp /usr/local/libduckdb.so /usr/local/lib/ && \ + cp /usr/local/duckdb.hpp /usr/local/include/ && \ + cp /usr/local/duckdb.h /usr/local/include/ && \ + ldconfig && \ + rm /tmp/libduckdb.zip && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +WORKDIR /build +COPY ask/Cargo.toml ask/Cargo.lock ./ +COPY ask/src ./src + +RUN rustup target add x86_64-unknown-linux-musl && \ + mkdir -p /build/.cargo && \ + printf '[target.x86_64-unknown-linux-musl]\nlinker = "gcc"\n' > /build/.cargo/config.toml && \ + printf 'rustflags = ["-L", "/usr/local/lib", "-C", "target-feature=+crt-static"]\n' >> /build/.cargo/config.toml && \ + sed -i 's/features = \["bundled"\]/default-features = false/' Cargo.toml && \ + rm -f Cargo.lock && \ + cargo build --release --target x86_64-unknown-linux-musl + +FROM --platform=linux/amd64 debian:12-slim + +RUN apt-get update -qq && \ + apt-get install -y --no-install-recommends \ + curl ca-certificates unzip bsdmainutils python3 \ + less ncurses-bin && \ + curl -fsSL \ + "https://github.com/caddyserver/caddy/releases/download/v2.9.1/caddy_2.9.1_linux_amd64.tar.gz" \ + | tar -xz -C /usr/local/bin caddy && \ + chmod +x /usr/local/bin/caddy && \ + curl -fsSL \ + "https://github.com/duckdb/duckdb/releases/download/v1.5.1/duckdb_cli-linux-amd64.zip" \ + -o /tmp/duckdb.zip && \ + unzip /tmp/duckdb.zip -d /usr/local/bin && \ + chmod +x /usr/local/bin/duckdb && \ + rm /tmp/duckdb.zip && \ + curl -fsSL "https://github.com/tsl0922/ttyd/releases/latest/download/ttyd.x86_64" \ + -o /usr/local/bin/ttyd && \ + chmod +x /usr/local/bin/ttyd && \ + curl -fsSL https://github.com/duckdb/duckdb/releases/download/v1.5.1/libduckdb-linux-amd64.zip \ + -o /tmp/libduckdb.zip && \ + unzip -o /tmp/libduckdb.zip -d /usr/local && \ + cp /usr/local/libduckdb.so /usr/local/lib/ && \ + ldconfig && \ + rm /tmp/libduckdb.zip && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY --from=builder /build/target/x86_64-unknown-linux-musl/release/ask ./ask +COPY ask/system_prompt.md ./system_prompt.md +COPY data/basedosdados.duckdb ./data/ +COPY context ./context/ +COPY auth.py ./ +COPY start.sh ./ +COPY Caddyfile ./ + +RUN chmod +x start.sh ask + +EXPOSE 8080 + +ENTRYPOINT ["./start.sh"] diff --git a/ask/src/main.rs b/ask/src/main.rs index cdb69e7..3d72e1a 100644 --- a/ask/src/main.rs +++ b/ask/src/main.rs @@ -24,9 +24,17 @@ use serde_json::{json, Value}; use std::{ env, fs, io::{stdout, IsTerminal, Write}, + path::PathBuf, sync::mpsc, time::{Duration, Instant}, }; + +fn project_path(rel: &str) -> PathBuf { + match env::var("CARGO_MANIFEST_DIR") { + Ok(manifest_dir) => PathBuf::from(manifest_dir).join("..").join(rel), + Err(_) => PathBuf::from(rel), + } +} use syntect::easy::HighlightLines; use syntect::highlighting::ThemeSet; use syntect::parsing::SyntaxSet; @@ -1436,12 +1444,21 @@ VARIÁVEIS DE AMBIENTE let model = model_override.unwrap_or_else(|| { env::var("GEMINI_MODEL").unwrap_or_else(|_| "gemini-flash-latest".into()) }); - let schema_file = - env::var("SCHEMA_FILE").unwrap_or_else(|_| "context/schema_compact_inline.txt".into()); - let schema_json = - env::var("SCHEMA_JSON").unwrap_or_else(|_| "context/basedosdados-schema.json".into()); - let embeddings_file = - env::var("EMBEDDINGS_FILE").unwrap_or_else(|_| "context/table_embeddings.json".into()); + let schema_file = env::var("SCHEMA_FILE").unwrap_or_else(|_| { + project_path("context/schema_compact_inline.txt") + .to_string_lossy() + .into() + }); + let schema_json = env::var("SCHEMA_JSON").unwrap_or_else(|_| { + project_path("context/basedosdados-schema.json") + .to_string_lossy() + .into() + }); + let embeddings_file = env::var("EMBEDDINGS_FILE").unwrap_or_else(|_| { + project_path("context/table_embeddings.json") + .to_string_lossy() + .into() + }); let similarity_threshold = env::var("SIMILARITY_THRESHOLD") .ok() .and_then(|v| v.parse().ok()) @@ -1449,8 +1466,16 @@ VARIÁVEIS DE AMBIENTE let use_table_selection = env::var("USE_TABLE_SELECTION") .map(|v| v != "false" && v != "0") .unwrap_or(true); - let db_file = env::var("DB_FILE").unwrap_or_else(|_| "data/basedosdados.duckdb".into()); - let prompt_file = env::var("PROMPT_FILE").unwrap_or_else(|_| "ask/system_prompt.md".into()); + let db_file = env::var("DB_FILE").unwrap_or_else(|_| { + project_path("data/basedosdados.duckdb") + .to_string_lossy() + .into() + }); + let prompt_file = env::var("PROMPT_FILE").unwrap_or_else(|_| { + project_path("ask/system_prompt.md") + .to_string_lossy() + .into() + }); let schema = fs::read_to_string(&schema_file) .with_context(|| format!("Não foi possível ler o schema: {}", schema_file))?; diff --git a/scripts/build_ask.sh b/scripts/build_ask.sh index b627b44..360467d 100755 --- a/scripts/build_ask.sh +++ b/scripts/build_ask.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -cd "$(dirname "$0")" +cd "$(dirname "$0")/.." echo "=== Building ask binary for Linux x86_64 ===" echo "Using Debian x86_64 container for native build..." @@ -14,7 +14,7 @@ docker build \ -t ask-builder \ --build-arg BUILDKIT_INLINE_CACHE=1 \ -f - ask/ <<'EOF' -FROM rust:1.85-slim +FROM rust:latest RUN apt-get update -qq && \ apt-get install -y --no-install-recommends \ diff --git a/start.sh b/start.sh index e9d914e..945891b 100644 --- a/start.sh +++ b/start.sh @@ -22,10 +22,10 @@ echo "[start] Starting ttyd terminal (db)..." ttyd --port 7681 --writable duckdb -readonly --init /app/ssh_init.sql /app/data/basedosdados.duckdb & echo "[start] Starting ttyd terminal (ask)..." -ttyd --port 7682 --writable /app/ask & +PROMPT_FILE=/app/system_prompt.md ttyd --port 7682 --writable /app/ask & echo "[start] Starting auth service..." -python3 /app/shell/auth.py & +python3 /app/auth.py & echo "[start] Starting Caddy..." exec caddy run --config /app/Caddyfile --adapter caddyfile