build pipeline finished
This commit is contained in:
6
.dockerignore
Normal file
6
.dockerignore
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.env
|
||||||
|
target/
|
||||||
|
tests/
|
||||||
|
Dockerfile
|
||||||
|
scripts/
|
||||||
|
migrations/
|
||||||
25
Dockerfile
25
Dockerfile
@ -1,11 +1,28 @@
|
|||||||
FROM rust:1.76.0
|
FROM lukemathwalker/cargo-chef:latest-rust-1.76.0-bookworm as chef
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN apt update && apt install lld clang -y
|
RUN apt update && apt install lld clang -y
|
||||||
|
|
||||||
|
FROM chef AS planner
|
||||||
|
COPY . .
|
||||||
|
RUN cargo chef prepare --recipe-path recipe.json
|
||||||
|
|
||||||
|
FROM chef AS builder
|
||||||
|
COPY --from=planner /app/recipe.json recipe.json
|
||||||
|
RUN cargo chef cook --release --recipe-path recipe.json
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV SQLX_OFFLINE true
|
ENV SQLX_OFFLINE true
|
||||||
RUN cargo build --release
|
RUN cargo build --release
|
||||||
|
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
RUN apt-get update -y \
|
||||||
|
&& apt-get install -y --no-install-recommends openssl ca-certificates \
|
||||||
|
&& apt-get autoremove -y \
|
||||||
|
&& apt-get clean -y \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
COPY --from=builder /app/target/release/zero2prod zero2prod
|
||||||
|
COPY configuration configuration
|
||||||
ENV APP_ENVIRONMENT production
|
ENV APP_ENVIRONMENT production
|
||||||
|
|
||||||
ENTRYPOINT ["./target/release/zero2prod"]
|
ENTRYPOINT ["./zero2prod"]
|
||||||
|
|||||||
@ -1,2 +1,4 @@
|
|||||||
application:
|
application:
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
|
database:
|
||||||
|
require_ssl: false
|
||||||
|
|||||||
@ -1,2 +1,4 @@
|
|||||||
application:
|
application:
|
||||||
host: 0.0.0.0
|
host: 0.0.0.0
|
||||||
|
database:
|
||||||
|
require_ssl: true
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use config::Config;
|
use config::Config;
|
||||||
use secrecy::{ExposeSecret, Secret};
|
use secrecy::{ExposeSecret, Secret};
|
||||||
|
use sqlx::{postgres::{PgConnectOptions, PgSslMode}, ConnectOptions};
|
||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
@ -20,21 +21,27 @@ pub struct DatabaseSettings {
|
|||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub host: String,
|
pub host: String,
|
||||||
pub database_name: String,
|
pub database_name: String,
|
||||||
|
pub require_ssl: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DatabaseSettings {
|
impl DatabaseSettings {
|
||||||
pub fn connection_string(&self) -> Secret<String> {
|
pub fn without_db(&self) -> PgConnectOptions {
|
||||||
Secret::new(format!(
|
let ssl_mode = if self.require_ssl {
|
||||||
"postgres://{}:{}@{}:{}/{}",
|
PgSslMode::Require
|
||||||
self.username, self.password.expose_secret(), self.host, self.port, self.database_name
|
} else {
|
||||||
))
|
PgSslMode::Prefer
|
||||||
|
};
|
||||||
|
PgConnectOptions::new()
|
||||||
|
.host(&self.host)
|
||||||
|
.username(&self.username)
|
||||||
|
.password(self.password.expose_secret())
|
||||||
|
.port(self.port)
|
||||||
|
.ssl_mode(ssl_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connection_string_without_db(&self) -> Secret<String> {
|
pub fn with_db(&self) -> PgConnectOptions {
|
||||||
Secret::new(format!(
|
let options = self.without_db().database(&self.database_name);
|
||||||
"postgres://{}:{}@{}:{}",
|
options.log_statements(tracing::log::LevelFilter::Trace)
|
||||||
self.username, self.password.expose_secret(), self.host, self.port
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +58,7 @@ pub fn get_configuration() -> Result<Settings, config::ConfigError> {
|
|||||||
let settings = Config::builder()
|
let settings = Config::builder()
|
||||||
.add_source(config::File::with_name(base_config_file).required(true))
|
.add_source(config::File::with_name(base_config_file).required(true))
|
||||||
.add_source(config::File::with_name(environment_config_file).required(true))
|
.add_source(config::File::with_name(environment_config_file).required(true))
|
||||||
|
.add_source(config::Environment::with_prefix("APP").try_parsing(true).separator("_"))
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
settings.try_deserialize()
|
settings.try_deserialize()
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
use secrecy::ExposeSecret;
|
|
||||||
use sqlx::postgres::PgPoolOptions;
|
use sqlx::postgres::PgPoolOptions;
|
||||||
use zero2prod::configuration::get_configuration;
|
use zero2prod::configuration::get_configuration;
|
||||||
use zero2prod::startup::run;
|
use zero2prod::startup::run;
|
||||||
@ -11,8 +10,9 @@ async fn main() -> std::io::Result<()> {
|
|||||||
init_subscriber(subscriber);
|
init_subscriber(subscriber);
|
||||||
|
|
||||||
let config = get_configuration().expect("Failed to read configuration");
|
let config = get_configuration().expect("Failed to read configuration");
|
||||||
let connection_pool = PgPoolOptions::new()
|
println!("Application configuration: {}", config.application.port);
|
||||||
.max_connections(10).connect_lazy(config.database.connection_string().expose_secret()).expect("Failed to connect to Postgres.");
|
let connection_pool = PgPoolOptions::new().acquire_timeout(std::time::Duration::from_secs(2))
|
||||||
|
.max_connections(10).connect_lazy_with(config.database.with_db());
|
||||||
|
|
||||||
let address = format!("{}:{}", config.application.host, config.application.port);
|
let address = format!("{}:{}", config.application.host, config.application.port);
|
||||||
let listener = TcpListener::bind(address).expect("Failed to bind random port");
|
let listener = TcpListener::bind(address).expect("Failed to bind random port");
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use secrecy::ExposeSecret;
|
|
||||||
use sqlx::{postgres::PgPoolOptions, query, Connection, Executor, PgConnection, Pool, Postgres};
|
use sqlx::{postgres::PgPoolOptions, query, Connection, Executor, PgConnection, Pool, Postgres};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use std:: net::TcpListener;
|
use std:: net::TcpListener;
|
||||||
@ -44,7 +43,7 @@ async fn spawn_app() -> TestApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn configure_database(config: &DatabaseSettings) -> Pool<Postgres> {
|
pub async fn configure_database(config: &DatabaseSettings) -> Pool<Postgres> {
|
||||||
let mut connection = PgConnection::connect(config.connection_string_without_db().expose_secret())
|
let mut connection = PgConnection::connect_with(&config.without_db())
|
||||||
.await
|
.await
|
||||||
.expect("Failed to connect to Postgres.");
|
.expect("Failed to connect to Postgres.");
|
||||||
|
|
||||||
@ -54,7 +53,7 @@ pub async fn configure_database(config: &DatabaseSettings) -> Pool<Postgres> {
|
|||||||
|
|
||||||
let connection_pool = PgPoolOptions::new()
|
let connection_pool = PgPoolOptions::new()
|
||||||
.max_connections(10)
|
.max_connections(10)
|
||||||
.connect(config.connection_string().expose_secret())
|
.connect_with(config.with_db())
|
||||||
.await
|
.await
|
||||||
.expect("Failed to connect to Postgres.");
|
.expect("Failed to connect to Postgres.");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user