Skip to content

Commit

Permalink
Allow configurations via CLI arguments in addition to env vars.
Browse files Browse the repository at this point in the history
  • Loading branch information
denschub committed Jun 8, 2024
1 parent fc9d972 commit afb26bf
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
DATABASE_URL=postgres://postgres@127.0.0.1/vssv
LISTEN_URL=[::1]:3000
LISTEN_ADDR=[::1]:3000
26 changes: 22 additions & 4 deletions Cargo.lock

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

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description = "A very simple secrets vault."
authors = ["Dennis Schubert <mail@dennis-schubert.de>"]
repository = "https://github.com/denschub/vssv"
license = "MIT"
version = "1.0.0"
version = "1.1.0"
edition = "2021"

[profile.release]
Expand All @@ -15,8 +15,7 @@ anyhow = "1"
axum = { version = "0.7", features = ["macros"] }
axum-extra = { version = "0.9", features = ["typed-header"] }
chrono = "0.4"
clap = "4"
dotenvy = "0.15"
clap = { version = "4", features = ["derive", "env"] }
num_cpus = "1"
serde = { version = "1", features = ["derive"] }
sqlx = { version = "0.7", features = [
Expand Down
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.1.0

This release allows using CLI flags in addition to environment variables to configure `vssv`.

# 1.0.0

The first public release. Changes are: everything and nothing.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ RUN \
USER app:app
COPY --from=builder /app/out/bin/vssv /app

ENV LISTEN_URL [::]:3000
ENV LISTEN_ADDR [::]:3000
EXPOSE 3000
HEALTHCHECK CMD curl -f http://localhost:3000/readyz || exit 1
CMD ["/app/vssv"]
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ First, scroll back up and re-read the "You don't want to use this." section.

But if you have to, there is a container image [in the GitHub Container registry at `ghcr.io/denschub/vssv:latest`](https://github.com/denschub/vssv/pkgs/container/vssv), and [on Docker Hub as `denschub/vssv:latest`](https://hub.docker.com/repository/docker/denschub/vssv/general). The container exposes port 3000.

Make sure to set the `DATABASE_URL` environment variable to a valid PostgreSQL connection URL like `postgres://postgres@127.0.0.1/vssv`. The database needs to exist before starting the server, but the server startup procedure will take care of all database migrations.
Configuration of the server is done with either environment variables or via CLI arguments. Make sure to set `DATABASE_URL`/`--database-url` to a valid PostgreSQL connection URL like `postgres://postgres@127.0.0.1/vssv`. The database needs to exist before starting the server, but the server startup procedure will take care of all database migrations.

Released binaries are available for all stable releases. Check the [Releases section on GitHub](https://github.com/denschub/vssv/releases) for the latest release, and you'll find a `.zip` with a pre-built binary. If you run the binary yourself, also make sure to set the `[::1]:3000` environment variable to a valid listen address, like `[::1]:3000`, for example.
Released binaries are available for all stable releases. Check the [Releases section on GitHub](https://github.com/denschub/vssv/releases) for the latest release, and you'll find a `.zip` with a pre-built binary. If you run the binary yourself, also make sure to set `LISTEN_ADDR`/`--listen-addr` to a valid listen address, like `[::1]:3000`, for example.

You can also build a binary yourself if you have the latest stable Rust toolchain installed. Simply run `cargo build --release`, and you'll find a ready-to-use binary at `target/release/vssv`.

Expand Down
17 changes: 16 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
use sqlx::PgPool;
use std::net::SocketAddr;

use sqlx::{postgres::PgConnectOptions, PgPool};

pub mod errors;
pub mod models;
pub mod routes;

#[derive(Debug, clap::Parser)]
#[clap(about, version, propagate_version = true)]
pub struct Cli {
/// The database URL to connect to. Needs to be a valid PostgreSQL
/// connection URL, like `postgres://postgres@127.0.0.1/vssv`
#[clap(long, short, env = "DATABASE_URL")]
pub database_url: PgConnectOptions,

/// The Socket Address the server should listen on
#[clap(long, short, env = "LISTEN_ADDR", default_value = "[::1]:3000")]
pub listen_addr: SocketAddr,
}

/// Holds the web server's state.
#[derive(Clone)]
pub struct ServerState {
Expand Down
27 changes: 13 additions & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::{env, net::SocketAddr};
use std::net::SocketAddr;

use anyhow::Context;
use dotenvy::dotenv;
use sqlx::{postgres::PgPoolOptions, PgPool};
use clap::Parser;
use sqlx::{
postgres::{PgConnectOptions, PgPoolOptions},
PgPool,
};
use tokio::{net::TcpListener, signal};

use tracing::info;
use vssv::{routes::build_router, ServerState};
use vssv::{routes::build_router, Cli, ServerState};

/// Listens to SIGINT (aka ctrl-c) and SIGTERM and completes whenever one of
/// those signals happen.
Expand All @@ -33,32 +35,29 @@ async fn shutdown_signal() {

/// Creates a [PgPool] if possible. The pool has its max_connections value set
/// to the number of CPUs available.
pub async fn get_db_pool(db_url: &str) -> Result<PgPool, sqlx::Error> {
pub async fn get_db_pool(connect_options: PgConnectOptions) -> Result<PgPool, sqlx::Error> {
PgPoolOptions::new()
.max_connections(
num_cpus::get()
.try_into()
.expect("number of CPU cores should fit into an u32"),
)
.connect(db_url)
.connect_with(connect_options)
.await
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
tracing_subscriber::fmt::init();

dotenv().ok();
let database_url = env::var("DATABASE_URL").context("DATABASE_URL must be set")?;
let listen_url = env::var("LISTEN_URL").context("LISTEN_URL must be set")?;

let db_pool = get_db_pool(&database_url).await?;
let db_pool = get_db_pool(cli.database_url).await?;
sqlx::migrate!().run(&db_pool).await?;

let router = build_router(ServerState { database: db_pool });
let listener = TcpListener::bind(listen_url).await?;
let listener = TcpListener::bind(cli.listen_addr).await?;

info!("Will start to listen on `{}`...", listener.local_addr()?);
info!("Will start to listen on `{}`...", cli.listen_addr);
axum::serve(
listener,
router.into_make_service_with_connect_info::<SocketAddr>(),
Expand Down

0 comments on commit afb26bf

Please sign in to comment.