From aa114539c0a435d3976524f8287d5b0449d739c9 Mon Sep 17 00:00:00 2001 From: dboures Date: Tue, 14 Mar 2023 20:46:49 -0500 Subject: [PATCH] feat: add docker deployment --- .dockerignore | 1 + .env-example | 5 +++++ Dockerfile.server | 19 +++++++++++++++++++ Dockerfile.worker | 19 +++++++++++++++++++ docker-compose.yml | 33 +++++++++++++++++++++++++++++++++ src/server/main.rs | 7 +++++-- src/worker/main.rs | 5 ++++- 7 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 .dockerignore create mode 100644 .env-example create mode 100644 Dockerfile.server create mode 100644 Dockerfile.worker create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f2a4093 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +**/target \ No newline at end of file diff --git a/.env-example b/.env-example new file mode 100644 index 0000000..e9feb23 --- /dev/null +++ b/.env-example @@ -0,0 +1,5 @@ +RPC_URL=http://solana-mainnet-api.rpc-node.com +DATABASE_URL= +SQLX_OFFLINE=true +MAX_PG_POOL_CONNS_WORKER=5 +MAX_PG_POOL_CONNS_SERVER=15 \ No newline at end of file diff --git a/Dockerfile.server b/Dockerfile.server new file mode 100644 index 0000000..0d7e204 --- /dev/null +++ b/Dockerfile.server @@ -0,0 +1,19 @@ +FROM lukemathwalker/cargo-chef:latest-rust-1.67.1-slim AS chef + +FROM chef AS planner +COPY . . +RUN cargo chef prepare --recipe-path server-recipe.json + +FROM chef AS builder +COPY --from=planner server-recipe.json server-recipe.json +RUN apt-get update && apt-get install -y libudev-dev clang pkg-config libssl-dev build-essential cmake +RUN rustup component add rustfmt +RUN cargo chef cook --release --recipe-path server-recipe.json +# Build application +COPY . . +RUN cargo build --release --bin server + +# We do not need the Rust toolchain to run the binary! +FROM debian:bullseye-slim AS runtime +COPY --from=builder /target/release/server /usr/local/bin +ENTRYPOINT ["/usr/local/bin/server"] \ No newline at end of file diff --git a/Dockerfile.worker b/Dockerfile.worker new file mode 100644 index 0000000..33e57d0 --- /dev/null +++ b/Dockerfile.worker @@ -0,0 +1,19 @@ +FROM lukemathwalker/cargo-chef:latest-rust-1.67.1-slim AS chef + +FROM chef AS planner +COPY . . +RUN cargo chef prepare --recipe-path worker-recipe.json + +FROM chef AS builder +COPY --from=planner worker-recipe.json worker-recipe.json +RUN apt-get update && apt-get install -y libudev-dev clang pkg-config libssl-dev build-essential cmake +RUN rustup component add rustfmt +RUN cargo chef cook --release --recipe-path worker-recipe.json +# Build application +COPY . . +RUN cargo build --release --bin worker + +# We do not need the Rust toolchain to run the binary! +FROM debian:bullseye-slim AS runtime +COPY --from=builder /target/release/worker /usr/local/bin +ENTRYPOINT ["/usr/local/bin/worker"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4d9d04e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,33 @@ +services: + + server: + env_file: .env + build: + dockerfile: Dockerfile.server + depends_on: + - "db" + entrypoint: + - "/usr/local/bin/server" + - "/etc/markets.json" + + ports: + - 127.0.0.1:8080:8080 + restart: always + volumes: + - ./markets.json:/etc/markets.json + + worker: + env_file: .env + build: + dockerfile: Dockerfile.worker + depends_on: + - "db" + restart: always + entrypoint: + - "/usr/local/bin/worker" + - "/etc/markets.json" + volumes: + - ./markets.json:/etc/markets.json + +volumes: + data: \ No newline at end of file diff --git a/src/server/main.rs b/src/server/main.rs index 648b0a4..60aecb0 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -12,6 +12,7 @@ use openbook_candles::{ utils::{Config, WebContext}, }; use traders::{get_top_traders_by_base_volume, get_top_traders_by_quote_volume}; +use std::env; mod candles; mod markets; @@ -23,7 +24,9 @@ async fn main() -> std::io::Result<()> { dotenv::dotenv().ok(); env_logger::init(); - let path_to_markets_json: String = dotenv::var("PATH_TO_MARKETS_JSON").unwrap(); + let args: Vec = env::args().collect(); + assert!(args.len() == 2); + let path_to_markets_json = &args[1]; let rpc_url: String = dotenv::var("RPC_URL").unwrap(); let database_url: String = dotenv::var("DATABASE_URL").unwrap(); let max_pg_pool_connections: u32 = dotenv::var("MAX_PG_POOL_CONNS_SERVER") @@ -37,7 +40,7 @@ async fn main() -> std::io::Result<()> { max_pg_pool_connections, }; - let markets = load_markets(&path_to_markets_json); + let markets = load_markets(path_to_markets_json); let market_infos = fetch_market_infos(&config, markets).await.unwrap(); let pool = connect_to_database(&config).await.unwrap(); diff --git a/src/worker/main.rs b/src/worker/main.rs index d4605b0..a1a7ff1 100644 --- a/src/worker/main.rs +++ b/src/worker/main.rs @@ -12,12 +12,15 @@ use openbook_candles::utils::Config; use solana_sdk::pubkey::Pubkey; use std::{collections::HashMap, str::FromStr}; use tokio::sync::mpsc; +use std::env; #[tokio::main] async fn main() -> anyhow::Result<()> { dotenv::dotenv().ok(); - let path_to_markets_json: String = dotenv::var("PATH_TO_MARKETS_JSON").unwrap(); + let args: Vec = env::args().collect(); + assert!(args.len() == 2); + let path_to_markets_json = &args[1]; let rpc_url: String = dotenv::var("RPC_URL").unwrap(); let database_url: String = dotenv::var("DATABASE_URL").unwrap(); let max_pg_pool_connections: u32 = dotenv::var("MAX_PG_POOL_CONNS_WORKER")