Compare commits

...

2 commits

Author SHA1 Message Date
c69f2eb4f0 feat: add docker files
adds compose.yml, Dockerfile and entrypoint.sh for running the backend inside of docker
2025-05-01 01:09:24 +02:00
026d48c6e7 feat: load config from proper location
also adds a way to change load location using cmdline arguments
2025-05-01 01:08:45 +02:00
6 changed files with 109 additions and 6 deletions

View file

@ -11,6 +11,7 @@ codegen-units = 1
[dependencies] [dependencies]
actix-web = "4.10" actix-web = "4.10"
argon2 = { version = "0.5.3", features = ["std"] } argon2 = { version = "0.5.3", features = ["std"] }
clap = { version = "4.5.37", features = ["derive"] }
futures = "0.3" futures = "0.3"
regex = "1.11" regex = "1.11"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }

19
Dockerfile Normal file
View file

@ -0,0 +1,19 @@
FROM debian:12
RUN apt update && apt install libssl3 && rm -rf /var/lib/apt/lists/* /var/cache/apt/* /tmp/*
COPY target/release/backend /usr/bin/gorb-backend
COPY entrypoint.sh /usr/bin/entrypoint.sh
RUN useradd --create-home --home-dir /gorb gorb
USER gorb
ENV DATABASE_USERNAME="gorb"
ENV DATABASE_PASSWORD="gorb"
ENV DATABASE="gorb"
ENV DATABASE_HOST="localhost"
ENV DATABASE_PORT="5432"
ENTRYPOINT ["/usr/bin/entrypoint.sh"]

33
compose.yml Normal file
View file

@ -0,0 +1,33 @@
version: '3.5'
volumes:
gorb-backend:
gorb-database:
networks:
gorb:
services:
backend:
image: gorb/backend:latest
restart: always
ports:
- 8080:8080
networks:
- gorb
volumes:
- gorb-backend:/gorb
environment:
- DATABASE_USERNAME=gorb
- DATABASE_PASSWORD=gorb
- DATABASE=gorb
- DATABASE_HOST=database
- DATABASE_PORT=5432
database:
image: postgres:16
restart: always
networks:
- gorb
volumes:
- gorb-database:/var/lib/postgresql/data
environment:
- POSTGRES_USER=gorb
- POSTGRES_PASSWORD=gorb
- POSTGRES_DB=gorb

42
entrypoint.sh Executable file
View file

@ -0,0 +1,42 @@
#!/bin/sh
if [ ! -d "/gorb/config" ]; then
mkdir /gorb/config
fi
if [ ! -d "/gorb/logs" ]; then
mkdir /gorb/logs
fi
if [ ! -f "/gorb/config/config.toml" ]; then
cat > /gorb/config/config.toml <<EOF
[database]
username = "${DATABASE_USERNAME}"
password = "${DATABASE_PASSWORD}"
database = "${DATABASE}"
host = "${DATABASE_HOST}"
port = ${DATABASE_PORT}
EOF
fi
rotate_log() {
LOGFILE="$1"
BASENAME=$(basename "$LOGFILE" .log)
DIRNAME=$(dirname "$LOGFILE")
if [ -f "$LOGFILE" ]; then
# Find the next available number
i=1
while [ -f "$DIRNAME/${BASENAME}.${i}.log.gz" ]; do
i=$((i + 1))
done
gzip "$LOGFILE"
mv "${LOGFILE}.gz" "$DIRNAME/${BASENAME}.${i}.log.gz"
fi
}
rotate_log "/gorb/logs/stdout.log"
rotate_log "/gorb/logs/stderr.log"
/usr/bin/gorb-backend --config /gorb/config/config.toml > /gorb/logs/stdout.log 2> /gorb/logs/stderr.log

View file

@ -26,8 +26,8 @@ struct WebBuilder {
} }
impl ConfigBuilder { impl ConfigBuilder {
pub async fn load() -> Result<Self, Error> { pub async fn load(path: String) -> Result<Self, Error> {
let raw = read_to_string("./config.toml").await?; let raw = read_to_string(path).await?;
let config = toml::from_str(&raw)?; let config = toml::from_str(&raw)?;
@ -39,13 +39,11 @@ impl ConfigBuilder {
Web { Web {
url: web.url.unwrap_or(String::from("0.0.0.0")), url: web.url.unwrap_or(String::from("0.0.0.0")),
port: web.port.unwrap_or(8080), port: web.port.unwrap_or(8080),
ssl: web.ssl.unwrap_or_default(),
} }
} else { } else {
Web { Web {
url: String::from("0.0.0.0"), url: String::from("0.0.0.0"),
port: 8080, port: 8080,
ssl: false,
} }
}; };
@ -66,7 +64,6 @@ pub struct Config {
pub struct Web { pub struct Web {
pub url: String, pub url: String,
pub port: u16, pub port: u16,
pub ssl: bool,
} }
impl Database { impl Database {

View file

@ -1,5 +1,6 @@
use actix_web::{App, HttpServer, web}; use actix_web::{App, HttpServer, web};
use argon2::Argon2; use argon2::Argon2;
use clap::Parser;
use sqlx::{PgPool, Pool, Postgres}; use sqlx::{PgPool, Pool, Postgres};
use std::time::SystemTime; use std::time::SystemTime;
mod config; mod config;
@ -8,6 +9,14 @@ mod api;
type Error = Box<dyn std::error::Error>; type Error = Box<dyn std::error::Error>;
/// Simple program to greet a person
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
#[arg(short, long, default_value_t = String::from("/etc/gorb/config.toml"))]
config: String,
}
#[derive(Clone)] #[derive(Clone)]
struct Data { struct Data {
pub pool: Pool<Postgres>, pub pool: Pool<Postgres>,
@ -18,7 +27,9 @@ struct Data {
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), Error> { async fn main() -> Result<(), Error> {
let config = ConfigBuilder::load().await?.build(); let args = Args::parse();
let config = ConfigBuilder::load(args.config).await?.build();
let web = config.web.clone(); let web = config.web.clone();