Добавление докерфайла

This commit is contained in:
Кобелев Андрей Андреевич 2022-10-13 16:00:35 +03:00
parent c4db474fc8
commit 971dc91dfd
8 changed files with 154 additions and 1116 deletions

3
.dockerignore Normal file
View File

@ -0,0 +1,3 @@
/target
cats.db
.DS_Store

3
.gitignore vendored
View File

@ -1,5 +1,6 @@
/target /target
/frontend
cats.db cats.db
.DS_Store .DS_Store
settings.yml settings.yml

1034
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,14 @@
[package] [package]
name = "loyalty_rust" name = "cat_rust"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
sqlx = { version = "0.6", features = [ "runtime-async-std-native-tls" ] }
actix-web = "4" actix-web = "4"
config = "0.13.1" config = "0.13.1"
serde = "1.0.8" serde = "1.0.8"
deadpool-postgres = { version = "0.10.2", features = ["serde"] }
tokio-postgres = "0.7.6"
rusqlite = { version = "0.28.0", features = ["bundled"] } rusqlite = { version = "0.28.0", features = ["bundled"] }
r2d2 = "0.8" r2d2 = "0.8"
r2d2_sqlite = "0.21" r2d2_sqlite = "0.21"

21
Dockerfile Normal file
View File

@ -0,0 +1,21 @@
FROM rust:1.62.1-alpine3.16
# This is important, see https://github.com/rust-lang/docker-rust/issues/85
ENV RUSTFLAGS="-C target-feature=-crt-static"
# if needed, add additional dependencies here
RUN apk add --no-cache musl-dev
# set the workdir and copy the source into it
WORKDIR /app
COPY ./ /app
# do a release build
RUN cargo build --release
RUN strip target/release/cat_rust
# use a plain alpine image, the alpine version needs to match the builder
FROM alpine:3.16
WORKDIR /app
# if needed, install additional dependencies here
RUN apk add --no-cache libgcc
# copy the binary into the final image
COPY --from=0 /app/target/release/cat_rust .
# set the binary as entrypoint
ENTRYPOINT ["/app/cat_rust"]

18
docker-compose.yml Normal file
View File

@ -0,0 +1,18 @@
version: "3.9"
services:
app:
image: docker.io/library/cat-rust
volumes:
- ./settings.yml:/app/settings.yml
- ./static:/app/static
ports:
- 8080:8080
dozzle:
container_name: dozzle
image: amir20/dozzle:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- 8070:8080

View File

@ -1,4 +1,5 @@
use rusqlite::{Error, Result}; use actix_web::{web, Error};
use rusqlite::Result;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
@ -19,6 +20,7 @@ pub type CatsResult = Result<Vec<Cat>, Error>;
pub type ColorsResult = Result<Vec<Color>, Error>; pub type ColorsResult = Result<Vec<Color>, Error>;
pub type CatResult = Result<Cat, Error>; pub type CatResult = Result<Cat, Error>;
pub type ColorResult = Result<Color, Error>; pub type ColorResult = Result<Color, Error>;
pub type Pool = r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>; pub type Pool = r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>;
// Сервис базы данных // Сервис базы данных
@ -76,31 +78,35 @@ impl Db {
} }
// Получение кошек // Получение кошек
pub fn get_cats(&self) -> CatsResult { pub async fn get_cats(&self) -> CatsResult {
let conn = match self.pool.get() { let pool = self.pool.clone();
Ok(conn) => conn, let conn = web::block(move || pool.get())
Err(err) => panic!("{}", err), .await?
}; .map_err(actix_web::error::ErrorInternalServerError)?;
let mut stmt = conn.prepare( return web::block(move || {
"SELECT c.id, c.name, cc.name from cats c INNER JOIN cat_colors cc ON cc.id = c.color_id;", let mut stmt = conn.prepare(
)?; "SELECT c.id, c.name, cc.name from cats c INNER JOIN cat_colors cc ON cc.id = c.color_id;",
return stmt )?;
.query_map([], |row| { return stmt
Ok(Cat { .query_map([], |row| {
id: row.get(0)?, Ok(Cat {
name: row.get(1)?, id: row.get(0)?,
color: row.get(2)?, name: row.get(1)?,
}) color: row.get(2)?,
}) })
.and_then(Iterator::collect); })
.and_then(Iterator::collect);
}).await?
.map_err(actix_web::error::ErrorInternalServerError);
} }
// Получение cлучайной кошки // Получение cлучайной кошки
pub fn get_random_cat(&self) -> CatResult { pub async fn get_random_cat(&self) -> CatResult {
let conn = match self.pool.get() { let pool = self.pool.clone();
Ok(conn) => conn, let conn = web::block(move || pool.get())
Err(err) => panic!("{}", err), .await?
}; .map_err(actix_web::error::ErrorInternalServerError)?;
return conn.query_row("SELECT c.id, c.name, cc.name from cats c INNER JOIN cat_colors cc ON cc.id = c.color_id ORDER BY random() LIMIT 1;", return web::block(move || {
return conn.query_row("SELECT c.id, c.name, cc.name from cats c INNER JOIN cat_colors cc ON cc.id = c.color_id ORDER BY random() LIMIT 1;",
[], [],
|row| { |row| {
Ok(Cat { Ok(Cat {
@ -108,33 +114,40 @@ impl Db {
name: row.get(1)?, name: row.get(1)?,
color: row.get(2)?, color: row.get(2)?,
}) })
}, })
); })
.await?
.map_err(actix_web::error::ErrorInternalServerError);
} }
// Получение цветов // Получение цветов
pub fn get_colors(&self) -> ColorsResult { pub async fn get_colors(&self) -> ColorsResult {
let conn = match self.pool.get() { let pool = self.pool.clone();
Ok(conn) => conn, let conn = web::block(move || pool.get())
Err(err) => panic!("{}", err), .await?
}; .map_err(actix_web::error::ErrorInternalServerError)?;
let mut stmt = conn.prepare("SELECT id, name from cat_colors")?; return web::block(move || {
return stmt let mut stmt = conn.prepare("SELECT id, name from cat_colors")?;
.query_map([], |row| { return stmt
Ok(Color { .query_map([], |row| {
id: row.get(0)?, Ok(Color {
name: row.get(1)?, id: row.get(0)?,
name: row.get(1)?,
})
}) })
}) .and_then(Iterator::collect);
.and_then(Iterator::collect); })
.await?
.map_err(actix_web::error::ErrorInternalServerError);
} }
// Добавление кошки // Добавление кошки
pub fn add_cat(&self, cat_name: String, cat_color: String) -> CatResult { pub async fn add_cat(&self, cat_name: String, cat_color: String) -> CatResult {
let conn = match self.pool.get() { let pool = self.pool.clone();
Ok(conn) => conn, let conn = web::block(move || pool.get())
Err(err) => panic!("{}", err), .await?
}; .map_err(actix_web::error::ErrorInternalServerError)?;
return web::block(move || {
return conn.query_row("INSERT INTO cats (name, color_id) SELECT ?1, id FROM cat_colors cc WHERE name = ?2 RETURNING id, name, ?2", return conn.query_row("INSERT INTO cats (name, color_id) SELECT ?1, id FROM cat_colors cc WHERE name = ?2 RETURNING id, name, ?2",
[cat_name, cat_color], [cat_name, cat_color],
|row| { |row| {
@ -144,23 +157,28 @@ impl Db {
color: row.get(2)?, color: row.get(2)?,
}) })
}, },
); )
}).await?.map_err(actix_web::error::ErrorInternalServerError);
} }
// Добавление цвета // Добавление цвета
pub fn add_color(&self, color_name: String) -> ColorResult { pub async fn add_color(&self, color_name: String) -> ColorResult {
let conn = match self.pool.get() { let pool = self.pool.clone();
Ok(conn) => conn, let conn = web::block(move || pool.get())
Err(err) => panic!("{}", err), .await?
}; .map_err(actix_web::error::ErrorInternalServerError)?;
return conn.query_row( return web::block(move || {
"INSERT INTO cat_colors (name) VALUES (?1) RETURNING id, name", return conn.query_row(
[color_name], "INSERT INTO cat_colors (name) VALUES (?1) RETURNING id, name",
|row| { [color_name],
Ok(Color { |row| {
id: row.get(0)?, Ok(Color {
name: row.get(1)?, id: row.get(0)?,
}) name: row.get(1)?,
}, })
); },
);
})
.await?
.map_err(actix_web::error::ErrorInternalServerError);
} }
} }

View File

@ -1,5 +1,5 @@
pub mod db; pub mod db;
use actix_web::{get, post, web, HttpResponse, Responder, Result}; use actix_web::{get, post, web, Error, HttpResponse, Responder, Result};
use db::Db; use db::Db;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -15,32 +15,20 @@ pub struct AddColorRequest {
#[get("/api/cats")] #[get("/api/cats")]
pub async fn get_cats(db: web::Data<Db>) -> Result<impl Responder> { pub async fn get_cats(db: web::Data<Db>) -> Result<impl Responder> {
let cats = db.get_cats(); let cats = db.get_cats().await;
let res = match cats { return Ok(HttpResponse::Ok().json(cats.map_err(Error::from)?));
Ok(v) => ArrayResponse { result: v },
Err(_err) => ArrayResponse { result: vec![] },
};
return Ok(HttpResponse::Ok().json(res));
} }
#[get("/api/cat/random")] #[get("/api/cat/random")]
pub async fn get_random_cat(db: web::Data<Db>) -> Result<impl Responder> { pub async fn get_random_cat(db: web::Data<Db>) -> Result<impl Responder> {
let cats = db.get_random_cat(); let cat = db.get_random_cat().await;
let res = match cats { return Ok(HttpResponse::Ok().json(cat.map_err(Error::from)?));
Ok(v) => v,
Err(_err) => panic!("{:?}", _err),
};
return Ok(HttpResponse::Ok().json(res));
} }
#[get("/colors")] #[get("/api/colors")]
pub async fn get_colors(db: web::Data<Db>) -> Result<impl Responder> { pub async fn get_colors(db: web::Data<Db>) -> Result<impl Responder> {
let colors = db.get_colors(); let colors = db.get_colors().await;
let res = match colors { return Ok(HttpResponse::Ok().json(colors.map_err(Error::from)?));
Ok(v) => ArrayResponse { result: v },
Err(_err) => ArrayResponse { result: vec![] },
};
return Ok(HttpResponse::Ok().json(res));
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -49,27 +37,19 @@ pub struct AddCatRequest {
pub color: String, pub color: String,
} }
#[post("/add/cat")] #[post("/api/add/cat")]
pub async fn add_cat(db: web::Data<Db>, cat: web::Json<AddCatRequest>) -> Result<impl Responder> { pub async fn add_cat(db: web::Data<Db>, cat: web::Json<AddCatRequest>) -> Result<impl Responder> {
let _cat = cat.into_inner(); let _cat = cat.into_inner();
let cat = db.add_cat(_cat.name, _cat.color); let cat = db.add_cat(_cat.name, _cat.color).await;
let res = match cat { return Ok(HttpResponse::Ok().json(cat.map_err(Error::from)?));
Ok(v) => ArrayResponse { result: vec![v] },
Err(_err) => panic!("{:?}", _err),
};
return Ok(HttpResponse::Ok().json(res));
} }
#[post("/add/color")] #[post("/api/add/color")]
pub async fn add_color( pub async fn add_color(
db: web::Data<Db>, db: web::Data<Db>,
cat: web::Json<AddColorRequest>, cat: web::Json<AddColorRequest>,
) -> Result<impl Responder> { ) -> Result<impl Responder> {
let _color = cat.into_inner(); let _color = cat.into_inner();
let cat = db.add_color(_color.name); let cat = db.add_color(_color.name).await;
let res = match cat { return Ok(HttpResponse::Ok().json(cat.map_err(Error::from)?));
Ok(v) => ArrayResponse { result: vec![v] },
Err(_err) => panic!("{:?}", _err),
};
return Ok(HttpResponse::Ok().json(res));
} }