diff --git a/Cargo.lock b/Cargo.lock index 03238de..a06cb52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2222,6 +2222,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "measure_time" version = "0.8.2" @@ -3431,6 +3437,7 @@ dependencies = [ "indexmap", "inquire", "local-ip-addr", + "md5", "mime_guess", "names", "nix", diff --git a/Cargo.toml b/Cargo.toml index 5df91d0..1ee1b45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ hcl-rs = "0.12.3" indexmap = {version = "1.9.2", features = ["serde"]} inquire = "0.6.2" local-ip-addr = "0.1.1" +md5 = "0.7.0" mime_guess = "2.0.4" names = "0.14.0" nix = "0.26.2" diff --git a/examples/nginx-nodejs-redis/Superfile.hcl b/examples/nginx-nodejs-redis/Superfile.hcl index 7446440..dd7fb65 100644 --- a/examples/nginx-nodejs-redis/Superfile.hcl +++ b/examples/nginx-nodejs-redis/Superfile.hcl @@ -1,14 +1,14 @@ project = "nginx-nodejs-redis" service "nodejs" { - type = "exec" + type = "docker" command = "npm start" working_dir = "./web" description = "Ping Service Example" depends_on = ["redis"] wait_for = ["redis"] env = { - REDIS_HOST = "localhost" + REDIS_HOST = "redis" } autostart = true autorestart = false @@ -20,13 +20,15 @@ service "nodejs" { command = "npm install" } - use "flox" { - environment = ".#nginx-nodejs-redis" - } + #use "flox" { + # environment = ".#nginx-nodejs-redis" + #} + + use "docker" { } } service "redis" { - type = "exec" + type = "docker" command = "redis-server" stop_command = "redis-cli shutdown" working_dir = "." @@ -40,7 +42,12 @@ service "redis" { stderr = "/tmp/redis-stderr.log" port = 6379 - use "flox" { - environment = ".#nginx-nodejs-redis" + #use "flox" { + # environment = ".#nginx-nodejs-redis" + #} + + use "docker" { + image = "redislabs/redismod:edge" + ports = ["6379:6379"] } } diff --git a/examples/nginx-nodejs-redis/web/.dockerignore b/examples/nginx-nodejs-redis/web/.dockerignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/examples/nginx-nodejs-redis/web/.dockerignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/examples/nginx-nodejs-redis/web/Dockerfile b/examples/nginx-nodejs-redis/web/Dockerfile index 3d1b21f..07dd5bd 100644 --- a/examples/nginx-nodejs-redis/web/Dockerfile +++ b/examples/nginx-nodejs-redis/web/Dockerfile @@ -3,7 +3,7 @@ FROM node:14.17.3-alpine3.14 WORKDIR /usr/src/app COPY package.json package-lock.json ./ -RUN npm ci +RUN npm install COPY ./server.js ./ CMD ["npm","start"] diff --git a/src/superviseur/drivers/docker/driver.rs b/src/superviseur/drivers/docker/driver.rs index eed5607..f2c671f 100644 --- a/src/superviseur/drivers/docker/driver.rs +++ b/src/superviseur/drivers/docker/driver.rs @@ -12,7 +12,8 @@ use owo_colors::OwoColorize; use shiplift::{ rep::ContainerDetails, tty::{self, TtyChunk}, - ContainerConnectionOptions, ContainerOptions, Docker, LogsOptions, + ContainerConnectionOptions, ContainerOptions, Docker, LogsOptions, NetworkCreateOptions, + PullOptions, }; use tokio::sync::mpsc; use tokio_stream::StreamExt; @@ -105,10 +106,51 @@ impl Driver { self.docker .networks() .get(&network.id) - .connect(&ContainerConnectionOptions::builder(container.id()).build()) + .connect( + &ContainerConnectionOptions::builder(container.id()) + .aliases(vec![&self.service.name]) + .build(), + ) .await?; } } + if cfg.networks.clone().unwrap_or(Vec::new()).len() == 0 { + // create a network + let project_hash = format!("{:x}", md5::compute(&self.context)); + let network_name = format!("{}_{}", self.project, project_hash); + // verify if network exists + match self.docker.networks().get(&network_name).inspect().await { + Ok(network) => { + // network exists + self.docker + .networks() + .get(&network.id) + .connect( + &ContainerConnectionOptions::builder(container.id()) + .aliases(vec![&self.service.name]) + .build(), + ) + .await?; + } + Err(_) => { + // network does not exist + let network = self + .docker + .networks() + .create(&NetworkCreateOptions::builder(&network_name).build()) + .await?; + self.docker + .networks() + .get(&network.id) + .connect( + &ContainerConnectionOptions::builder(container.id()) + .aliases(vec![&self.service.name]) + .build(), + ) + .await?; + } + } + } } None => {} }; @@ -138,11 +180,31 @@ impl Driver { } async fn build_image(&self, project: String) -> anyhow::Result<()> { - if self.config.as_ref().unwrap().image.is_some() { + if let Some(img) = &self.config.as_ref().unwrap().image { println!( "-> Skipping {} build, using image from config", self.service.name.bright_green() ); + let mut stream = self + .docker + .images() + .pull(&PullOptions::builder().image(img).build()); + + while let Some(pull_result) = stream.next().await { + match pull_result { + Ok(output) => { + print!("\r"); + print!( + "{} {} {}", + output["id"], output["status"], output["progress"] + ) + } + Err(e) => eprintln!("Error: {}", e), + } + } + + println!(""); + return Ok(()); } println!(