Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API: Basic Dockerisation #12

Merged
merged 7 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

# Database. Fill in the missing fields with secure values
POSTGRES_USER=
POSTGRES_PASSWORD=
POSTGRES_DB=blee

# Internal Stuff, modify iff you know what you are doing
CONFIG_DIR=/data
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Vidix
# Blee

Enjoy your Concert movies, Music Videos and music DVD Extras, all in one place
2 changes: 2 additions & 0 deletions api/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target/
Dockerfile*
3 changes: 2 additions & 1 deletion api/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
target
target
.vscode/
73 changes: 70 additions & 3 deletions api/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM rust:1.76-slim-buster as builder
RUN apt update -y && apt install libpq-dev -y
WORKDIR /usr/src/api
COPY . .
RUN cargo install --path api

FROM debian:bullseye-slim as runner
RUN apt update -y && apt install libpq-dev -y
COPY --from=builder /usr/local/cargo/bin/api /usr/local/bin/api
ENV ROCKET_ADDRESS=0.0.0.0
EXPOSE 8000
CMD DB_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}" ROCKET_DATABASES="{db={url=$DB_URL}}" api
8 changes: 8 additions & 0 deletions api/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM rust:1.76-slim-buster as builder
RUN apt update -y && apt install libpq-dev -y
WORKDIR /app
RUN cargo install cargo-watch
ENV ROCKET_ADDRESS=0.0.0.0
EXPOSE 8000
# We reduce the pool_size because of this: https://github.com/rwf2/Rocket/issues/1931#issuecomment-955945953
CMD cargo build && DB_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}" ROCKET_DATABASES="{db={url=$DB_URL, pool_size=2}}" cargo watch -x run
2 changes: 1 addition & 1 deletion api/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ serde = { version = "1.0", features = ["derive"] }
rocket_okapi = { version = "0.8.0", features = ["swagger", "uuid"] }
serde_json = "1.0"
schemars = { version = "0.8", features = ["chrono", "uuid1"] }
diesel = { version = "2.1.0" }
diesel = { version = "2.1.0", features = ["postgres"] }
chrono = { version = "0.4.34", features = ["serde"] }
slug = "0.1.5"
blurhash = "0.2.1"
Expand Down
6 changes: 4 additions & 2 deletions api/api/src/controllers/images.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::path::Path;
use crate::config::Config;
use crate::error_handling::ApiError;
use crate::services;
Expand All @@ -9,6 +8,7 @@ use rocket::State;
use rocket_okapi::okapi::openapi3::OpenApi;
use rocket_okapi::settings::OpenApiSettings;
use rocket_okapi::{openapi, openapi_get_routes_spec};
use std::path::Path;

pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
openapi_get_routes_spec![settings: serve_image]
Expand All @@ -25,7 +25,9 @@ async fn serve_image(
let image_row = db
.run(move |conn| services::image::get(&uuid, conn).map_err(|e| ApiError::from(e)))
.await?;
let image_path = Path::new(&config.data_folder).join(image_row.id.to_string()).join("image.webp");
let image_path = Path::new(&config.data_folder)
.join(image_row.id.to_string())
.join("image.webp");
NamedFile::open(&image_path)
.await
.map_err(|_| ApiError::ImageServingError)
Expand Down
15 changes: 6 additions & 9 deletions api/api/src/controllers/index.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
use crate::responses::index::IndexResponse;
use infrastructure::Database;
use rocket::{get, serde::json::Json};
use rocket_okapi::okapi::openapi3::OpenApi;
use rocket_okapi::settings::OpenApiSettings;
use rocket_okapi::{openapi, openapi_get_routes_spec};
use serde::Serialize;

pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
openapi_get_routes_spec![settings: index]
#[derive(Serialize)]
pub struct IndexResponse {
pub message: &'static str,
}

#[openapi(tag = "Index")]
#[get("/")]
async fn index(_db: Database) -> Json<IndexResponse> {
pub fn index(_db: Database) -> Json<IndexResponse> {
Json(IndexResponse {
message: "Hello World".to_owned(),
message: "Welcome to Blee's API. Hit '/swagger' for more!",
})
}
2 changes: 1 addition & 1 deletion api/api/src/controllers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod artists;
pub mod extras;
pub mod images;
pub mod index;
pub mod movies;
pub mod images;
20 changes: 16 additions & 4 deletions api/api/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::config::Config;
use crate::controllers::index::index;
use crate::error_handling::not_found;
use crate::swagger::custom_openapi_spec;
use infrastructure::Database;
use infrastructure::{apply_migrations, Database};
use rocket::fairing::AdHoc;
use rocket::figment::providers::Serialized;
use rocket::figment::Figment;
Expand All @@ -28,22 +29,34 @@ fn rocket() -> Rocket<Build> {
create_server()
}

async fn run_migrations(rocket: Rocket<Build>) -> Rocket<Build> {
let _ = Database::get_one(&rocket)
.await
.expect("Get DB Handle from Rocket")
.run(|conn| apply_migrations(conn))
.await;

rocket
}

pub fn create_server() -> Rocket<Build> {
let data_dir = env::var("DATA_DIR").expect("env variable `DATA_DIR` not set.");
let data_dir = env::var("CONFIG_DIR").expect("env variable `CONFIG_DIR` not set.");
let figment = Figment::from(rocket::Config::figment()).merge(Serialized::defaults(Config {
data_folder: data_dir,
}));
let mut building_rocket = rocket::custom(figment)
.attach(Database::fairing())
.attach(AdHoc::config::<Config>())
.attach(AdHoc::on_ignite("Run migrations", run_migrations))
.register("/", catchers![not_found])
.mount(
"/swagger",
make_swagger_ui(&SwaggerUIConfig {
url: "./openapi.json".to_owned(),
..Default::default()
}),
);
)
.mount("/", routes![index]);

let openapi_settings = OpenApiSettings {
json_path: "/swagger/openapi.json".to_owned(),
Expand All @@ -54,7 +67,6 @@ pub fn create_server() -> Rocket<Build> {
"/artists" => controllers::artists::get_routes_and_docs(&openapi_settings),
"/extras" => controllers::extras::get_routes_and_docs(&openapi_settings),
"/images" => controllers::images::get_routes_and_docs(&openapi_settings),
"/index" => controllers::index::get_routes_and_docs(&openapi_settings),
"/movies" => controllers::movies::get_routes_and_docs(&openapi_settings),
"/swagger" => (vec![], custom_openapi_spec()),
};
Expand Down
9 changes: 0 additions & 9 deletions api/api/src/responses/index.rs

This file was deleted.

1 change: 0 additions & 1 deletion api/api/src/responses/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub mod artist;
pub mod extra_creation;
pub mod index;
pub mod movie_creation;
3 changes: 2 additions & 1 deletion api/infrastructure/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
diesel = { version = "2.0.0", features = ["postgres"] }
diesel = { version = "2.1.0", features = ["postgres"] }
diesel_migrations = "2.0.0"
rocket_sync_db_pools = { version = "0.1.0", features = [
"diesel_postgres_pool",
] }
Expand Down
14 changes: 14 additions & 0 deletions api/infrastructure/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use rocket_okapi::{gen::OpenApiGenerator, request::*};
use rocket_sync_db_pools::{database, diesel};

Expand All @@ -14,3 +15,16 @@ impl<'r> OpenApiFromRequest<'r> for Database {
Ok(RequestHeaderInput::None)
}
}

pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("./migrations");

pub fn apply_migrations(connection: &mut impl MigrationHarness<diesel::pg::Pg>) {
match connection.run_pending_migrations(MIGRATIONS) {
Ok(_) => {
println!("Migrations successfully completed");
}
Err(e) => {
panic!("error running pending migrations {}", e)
}
};
}
31 changes: 31 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
services:
api:
build:
context: ./api
dockerfile: Dockerfile.dev
ports:
- "8000:8000"
restart: on-failure
depends_on:
db:
condition: service_healthy
environment:
- POSTGRES_HOST=db
- POSTGRES_PORT=5432
- CONFIG_DIR=/data
env_file:
- .env
volumes:
- ./api:/app
- ./data:/data
db:
image: postgres:alpine3.16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 3s
timeout: 5s
retries: 5
env_file:
- .env
volumes:
db:
Loading