Rewrite config implementation

This commit is contained in:
Felix Ableitner 2021-02-19 15:28:08 +01:00
parent f83b5590c7
commit 1bc7317b24
41 changed files with 383 additions and 376 deletions

59
Cargo.lock generated
View file

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3
[[package]] [[package]]
name = "activitystreams" name = "activitystreams"
version = "0.7.0-alpha.10" version = "0.7.0-alpha.10"
@ -1101,6 +1103,15 @@ dependencies = [
"termcolor", "termcolor",
] ]
[[package]]
name = "envy"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "2.5.1" version = "2.5.1"
@ -1953,6 +1964,7 @@ dependencies = [
"comrak", "comrak",
"deser-hjson", "deser-hjson",
"diesel", "diesel",
"envy",
"futures", "futures",
"http", "http",
"itertools", "itertools",
@ -1960,7 +1972,6 @@ dependencies = [
"lazy_static", "lazy_static",
"lettre", "lettre",
"log", "log",
"merge",
"openssl", "openssl",
"percent-encoding", "percent-encoding",
"rand 0.8.3", "rand 0.8.3",
@ -2113,28 +2124,6 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "merge"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9"
dependencies = [
"merge_derive",
"num-traits",
]
[[package]]
name = "merge_derive"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "migrations_internals" name = "migrations_internals"
version = "1.4.1" version = "1.4.1"
@ -2568,30 +2557,6 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]] [[package]]
name = "proc-macro-hack" name = "proc-macro-hack"
version = "0.5.19" version = "0.5.19"

View file

@ -1,6 +1,13 @@
#!/bin/bash #!/bin/bash
set -e set -e
export LEMMY_JWT_SECRET=changeme
export LEMMY_FEDERATION__ENABLED=true
export LEMMY_TLS_ENABLED=false
export LEMMY_SETUP__ADMIN_PASSWORD=lemmy
export LEMMY_RATE_LIMIT__POST=99999
export LEMMY_RATE_LIMIT__REGISTER=99999
export LEMMY_CAPTCHA__ENABLED=false
export LEMMY_TEST_SEND_SYNC=1 export LEMMY_TEST_SEND_SYNC=1
export RUST_BACKTRACE=1 export RUST_BACKTRACE=1
@ -28,39 +35,52 @@ fi
killall lemmy_server || true killall lemmy_server || true
echo "$PWD"
echo "start alpha" echo "start alpha"
LEMMY_HOSTNAME=lemmy-alpha:8541 \ LEMMY_HOSTNAME=lemmy-alpha:8541 \
LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_alpha.hjson \ LEMMY_PORT=8541 \
LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_alpha" \ LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_alpha" \
target/lemmy_server >/tmp/lemmy_alpha.out 2>&1 & LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon \
LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha \
LEMMY_SETUP__SITE_NAME=lemmy-alpha \
target/lemmy_server >/dev/null 2>&1 &
echo "start beta" echo "start beta"
LEMMY_HOSTNAME=lemmy-beta:8551 \ LEMMY_HOSTNAME=lemmy-beta:8551 \
LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_beta.hjson \ LEMMY_PORT=8551 \
LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_beta" \ LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_beta" \
target/lemmy_server >/tmp/lemmy_beta.out 2>&1 & LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon \
LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta \
LEMMY_SETUP__SITE_NAME=lemmy-beta \
target/lemmy_server >/dev/null 2>&1 &
echo "start gamma" echo "start gamma"
LEMMY_HOSTNAME=lemmy-gamma:8561 \ LEMMY_HOSTNAME=lemmy-gamma:8561 \
LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_gamma.hjson \ LEMMY_PORT=8561 \
LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_gamma" \ LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_gamma" \
target/lemmy_server >/tmp/lemmy_gamma.out 2>&1 & LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon \
LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma \
LEMMY_SETUP__SITE_NAME=lemmy-gamma \
target/lemmy_server >/dev/null 2>&1 &
echo "start delta" echo "start delta"
# An instance with only an allowlist for beta # An instance with only an allowlist for beta
LEMMY_HOSTNAME=lemmy-delta:8571 \ LEMMY_HOSTNAME=lemmy-delta:8571 \
LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_delta.hjson \ LEMMY_PORT=8571 \
LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_delta" \ LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_delta" \
target/lemmy_server >/tmp/lemmy_delta.out 2>&1 & LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta \
LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta \
LEMMY_SETUP__SITE_NAME=lemmy-delta \
target/lemmy_server >/dev/null 2>&1 &
echo "start epsilon" echo "start epsilon"
# An instance who has a blocklist, with lemmy-alpha blocked # An instance who has a blocklist, with lemmy-alpha blocked
LEMMY_HOSTNAME=lemmy-epsilon:8581 \ LEMMY_HOSTNAME=lemmy-epsilon:8581 \
LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_epsilon.hjson \ LEMMY_PORT=8581 \
LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_epsilon" \ LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_epsilon" \
target/lemmy_server >/tmp/lemmy_epsilon.out 2>&1 & LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha \
LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon \
LEMMY_SETUP__SITE_NAME=lemmy-epsilon \
target/lemmy_server >/dev/null 2>&1 &
echo "wait for all instances to start" echo "wait for all instances to start"
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8541/api/v2/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8541/api/v2/site')" != "200" ]]; do sleep 1; done

View file

@ -190,7 +190,7 @@ pub(crate) fn check_optional_url(item: &Option<Option<String>>) -> Result<(), Le
pub(crate) async fn build_federated_instances( pub(crate) async fn build_federated_instances(
pool: &DbPool, pool: &DbPool,
) -> Result<Option<FederatedInstances>, LemmyError> { ) -> Result<Option<FederatedInstances>, LemmyError> {
if Settings::get().federation.unwrap_or_default().enabled { if Settings::get().federation.enabled {
let distinct_communities = blocking(pool, move |conn| { let distinct_communities = blocking(pool, move |conn| {
Community::distinct_federated_communities(conn) Community::distinct_federated_communities(conn)
}) })
@ -205,9 +205,7 @@ pub(crate) async fn build_federated_instances(
.collect::<Result<Vec<String>, LemmyError>>()?; .collect::<Result<Vec<String>, LemmyError>>()?;
linked.extend_from_slice(&allowed); linked.extend_from_slice(&allowed);
linked.retain(|a| { linked.retain(|a| !blocked.contains(a) && !a.eq("") && !a.eq(&Settings::get().hostname));
!blocked.contains(a) && !a.eq("") && !a.eq(&Settings::get().hostname.unwrap_or_default())
});
// Sort and remove dupes // Sort and remove dupes
linked.sort_unstable(); linked.sort_unstable();

View file

@ -121,7 +121,7 @@ impl Perform for Login {
// Return the jwt // Return the jwt
Ok(LoginResponse { Ok(LoginResponse {
jwt: Claims::jwt(user.id, Settings::get().hostname.unwrap_or_default())?, jwt: Claims::jwt(user.id, Settings::get().hostname)?,
}) })
} }
} }
@ -161,7 +161,7 @@ impl Perform for Register {
.await??; .await??;
// If its not the admin, check the captcha // If its not the admin, check the captcha
if !no_admins && Settings::get().captcha.unwrap_or_default().enabled { if !no_admins && Settings::get().captcha.enabled {
let check = context let check = context
.chat_server() .chat_server()
.send(CheckCaptcha { .send(CheckCaptcha {
@ -303,10 +303,7 @@ impl Perform for Register {
// Return the jwt // Return the jwt
Ok(LoginResponse { Ok(LoginResponse {
jwt: Claims::jwt( jwt: Claims::jwt(inserted_user.id, Settings::get().hostname)?,
inserted_user.id,
Settings::get().hostname.unwrap_or_default(),
)?,
}) })
} }
} }
@ -320,7 +317,7 @@ impl Perform for GetCaptcha {
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_id: Option<ConnectionId>, _websocket_id: Option<ConnectionId>,
) -> Result<Self::Response, LemmyError> { ) -> Result<Self::Response, LemmyError> {
let captcha_settings = Settings::get().captcha.unwrap_or_default(); let captcha_settings = Settings::get().captcha;
if !captcha_settings.enabled { if !captcha_settings.enabled {
return Ok(GetCaptchaResponse { ok: None }); return Ok(GetCaptchaResponse { ok: None });
@ -479,10 +476,7 @@ impl Perform for SaveUserSettings {
// Return the jwt // Return the jwt
Ok(LoginResponse { Ok(LoginResponse {
jwt: Claims::jwt( jwt: Claims::jwt(updated_user.id, Settings::get().hostname)?,
updated_user.id,
Settings::get().hostname.unwrap_or_default(),
)?,
}) })
} }
} }
@ -1018,10 +1012,7 @@ impl Perform for PasswordChange {
// Return the jwt // Return the jwt
Ok(LoginResponse { Ok(LoginResponse {
jwt: Claims::jwt( jwt: Claims::jwt(updated_user.id, Settings::get().hostname)?,
updated_user.id,
Settings::get().hostname.unwrap_or_default(),
)?,
}) })
} }
} }

View file

@ -88,7 +88,7 @@ where
.await? .await?
.iter() .iter()
.unique() .unique()
.filter(|inbox| inbox.host_str() != Some(&Settings::get().hostname.unwrap_or_default())) .filter(|inbox| inbox.host_str() != Some(&Settings::get().hostname))
.filter(|inbox| check_is_apub_id_valid(inbox).is_ok()) .filter(|inbox| check_is_apub_id_valid(inbox).is_ok())
.map(|inbox| inbox.to_owned()) .map(|inbox| inbox.to_owned())
.collect(); .collect();
@ -215,7 +215,7 @@ where
Kind: Serialize, Kind: Serialize,
<T as Extends<Kind>>::Error: From<serde_json::Error> + Send + Sync + 'static, <T as Extends<Kind>>::Error: From<serde_json::Error> + Send + Sync + 'static,
{ {
if !Settings::get().federation.unwrap_or_default().enabled || inboxes.is_empty() { if !Settings::get().federation.enabled || inboxes.is_empty() {
return Ok(()); return Ok(());
} }

View file

@ -41,8 +41,8 @@ use log::debug;
use url::Url; use url::Url;
/// The types of ActivityPub objects that can be fetched directly by searching for their ID. /// The types of ActivityPub objects that can be fetched directly by searching for their ID.
#[serde(untagged)]
#[derive(serde::Deserialize, Debug)] #[derive(serde::Deserialize, Debug)]
#[serde(untagged)]
enum SearchAcceptedObjects { enum SearchAcceptedObjects {
Person(Box<PersonExt>), Person(Box<PersonExt>),
Group(Box<GroupExt>), Group(Box<GroupExt>),

View file

@ -167,7 +167,7 @@ where
let id = activity.id_unchecked().context(location_info!())?; let id = activity.id_unchecked().context(location_info!())?;
let activity_domain = id.domain().context(location_info!())?; let activity_domain = id.domain().context(location_info!())?;
if activity_domain == Settings::get().hostname.unwrap_or_default() { if activity_domain == Settings::get().hostname {
return Err( return Err(
anyhow!( anyhow!(
"Error: received activity which was sent by local instance: {:?}", "Error: received activity which was sent by local instance: {:?}",

View file

@ -64,7 +64,7 @@ fn check_is_apub_id_valid(apub_id: &Url) -> Result<(), LemmyError> {
let domain = apub_id.domain().context(location_info!())?.to_string(); let domain = apub_id.domain().context(location_info!())?.to_string();
let local_instance = settings.get_hostname_without_port()?; let local_instance = settings.get_hostname_without_port()?;
if !settings.federation.unwrap_or_default().enabled { if !settings.federation.enabled {
return if domain == local_instance { return if domain == local_instance {
Ok(()) Ok(())
} else { } else {

View file

@ -194,7 +194,7 @@ where
let domain = object_id.domain().context(location_info!())?; let domain = object_id.domain().context(location_info!())?;
// if its a local object, return it directly from the database // if its a local object, return it directly from the database
if Settings::get().hostname.unwrap_or_default() == domain { if Settings::get().hostname == domain {
let object = blocking(context.pool(), move |conn| { let object = blocking(context.pool(), move |conn| {
To::read_from_apub_id(conn, &object_id.into()) To::read_from_apub_id(conn, &object_id.into())
}) })

View file

@ -99,7 +99,7 @@ impl FromApub for User_ {
) -> Result<User_, LemmyError> { ) -> Result<User_, LemmyError> {
let user_id = person.id_unchecked().context(location_info!())?.to_owned(); let user_id = person.id_unchecked().context(location_info!())?.to_owned();
let domain = user_id.domain().context(location_info!())?; let domain = user_id.domain().context(location_info!())?;
if domain == Settings::get().hostname.unwrap_or_default() { if domain == Settings::get().hostname {
let user = blocking(context.pool(), move |conn| { let user = blocking(context.pool(), move |conn| {
User_::read_from_apub_id(conn, &user_id.into()) User_::read_from_apub_id(conn, &user_id.into())
}) })

View file

@ -23,11 +23,8 @@ static APUB_JSON_CONTENT_TYPE_LONG: &str =
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""; "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
pub fn config(cfg: &mut web::ServiceConfig) { pub fn config(cfg: &mut web::ServiceConfig) {
if Settings::get().federation.unwrap_or_default().enabled { if Settings::get().federation.enabled {
println!( println!("federation enabled, host is {}", Settings::get().hostname);
"federation enabled, host is {}",
Settings::get().hostname.unwrap_or_default()
);
let digest_verifier = VerifyDigest::new(Sha256::new()); let digest_verifier = VerifyDigest::new(Sha256::new());
let header_guard_accept = guard::Any(guard::Header("Accept", APUB_JSON_CONTENT_TYPE)) let header_guard_accept = guard::Any(guard::Header("Accept", APUB_JSON_CONTENT_TYPE))

View file

@ -168,7 +168,7 @@ fn get_feed_user(
) -> Result<ChannelBuilder, LemmyError> { ) -> Result<ChannelBuilder, LemmyError> {
let site_view = SiteView::read(&conn)?; let site_view = SiteView::read(&conn)?;
let user = User_::find_by_username(&conn, &user_name)?; let user = User_::find_by_username(&conn, &user_name)?;
let user_url = user.get_profile_url(&Settings::get().hostname.unwrap_or_default()); let user_url = user.get_profile_url(&Settings::get().hostname);
let posts = PostQueryBuilder::create(&conn) let posts = PostQueryBuilder::create(&conn)
.listing_type(&ListingType::All) .listing_type(&ListingType::All)

View file

@ -54,10 +54,8 @@ async fn upload(
return Ok(HttpResponse::Unauthorized().finish()); return Ok(HttpResponse::Unauthorized().finish());
}; };
let mut client_req = client.request_from( let mut client_req =
format!("{}/image", Settings::get().pictrs_url.unwrap_or_default()), client.request_from(format!("{}/image", Settings::get().pictrs_url), req.head());
req.head(),
);
if let Some(addr) = req.head().peer_addr { if let Some(addr) = req.head().peer_addr {
client_req = client_req.header("X-Forwarded-For", addr.to_string()) client_req = client_req.header("X-Forwarded-For", addr.to_string())
@ -80,18 +78,14 @@ async fn full_res(
// If there are no query params, the URL is original // If there are no query params, the URL is original
let url = if params.format.is_none() && params.thumbnail.is_none() { let url = if params.format.is_none() && params.thumbnail.is_none() {
format!( format!("{}/image/original/{}", Settings::get().pictrs_url, name,)
"{}/image/original/{}",
Settings::get().pictrs_url.unwrap_or_default(),
name,
)
} else { } else {
// Use jpg as a default when none is given // Use jpg as a default when none is given
let format = params.format.unwrap_or_else(|| "jpg".to_string()); let format = params.format.unwrap_or_else(|| "jpg".to_string());
let mut url = format!( let mut url = format!(
"{}/image/process.{}?src={}", "{}/image/process.{}?src={}",
Settings::get().pictrs_url.unwrap_or_default(), Settings::get().pictrs_url,
format, format,
name, name,
); );
@ -140,7 +134,7 @@ async fn delete(
let url = format!( let url = format!(
"{}/image/delete/{}/{}", "{}/image/delete/{}/{}",
Settings::get().pictrs_url.unwrap_or_default(), Settings::get().pictrs_url,
&token, &token,
&file &file
); );

View file

@ -31,7 +31,7 @@ async fn node_info(context: web::Data<LemmyContext>) -> Result<HttpResponse, Err
.await? .await?
.map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?; .map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?;
let protocols = if Settings::get().federation.unwrap_or_default().enabled { let protocols = if Settings::get().federation.enabled {
vec!["activitypub".to_string()] vec!["activitypub".to_string()]
} else { } else {
vec![] vec![]

View file

@ -18,7 +18,7 @@ struct Params {
} }
pub fn config(cfg: &mut web::ServiceConfig) { pub fn config(cfg: &mut web::ServiceConfig) {
if Settings::get().federation.unwrap_or_default().enabled { if Settings::get().federation.enabled {
cfg.route( cfg.route(
".well-known/webfinger", ".well-known/webfinger",
web::get().to(get_webfinger_response), web::get().to(get_webfinger_response),

View file

@ -152,7 +152,7 @@ pub fn send_email_to_user(user: User_, subject_text: &str, body_text: &str, comm
let subject = &format!( let subject = &format!(
"{} - {} {}", "{} - {} {}",
subject_text, subject_text,
Settings::get().hostname.unwrap_or_default(), Settings::get().hostname,
user.name, user.name,
); );
let html = &format!( let html = &format!(

View file

@ -34,4 +34,4 @@ diesel = "1.4.5"
http = "0.2.3" http = "0.2.3"
jsonwebtoken = "7.2.0" jsonwebtoken = "7.2.0"
deser-hjson = "0.1.12" deser-hjson = "0.1.12"
merge = "0.1.0" envy = "0.4"

View file

@ -18,7 +18,7 @@ impl Claims {
}; };
decode::<Claims>( decode::<Claims>(
&jwt, &jwt,
&DecodingKey::from_secret(Settings::get().jwt_secret.unwrap_or_default().as_ref()), &DecodingKey::from_secret(Settings::get().jwt_secret.as_ref()),
&v, &v,
) )
} }
@ -31,7 +31,7 @@ impl Claims {
encode( encode(
&Header::default(), &Header::default(),
&my_claims, &my_claims,
&EncodingKey::from_secret(Settings::get().jwt_secret.unwrap_or_default().as_ref()), &EncodingKey::from_secret(Settings::get().jwt_secret.as_ref()),
) )
} }
} }

View file

@ -20,7 +20,7 @@ pub fn send_email(
html: &str, html: &str,
) -> Result<(), String> { ) -> Result<(), String> {
let email_config = Settings::get().email.ok_or("no_email_setup")?; let email_config = Settings::get().email.ok_or("no_email_setup")?;
let domain = Settings::get().hostname.unwrap_or_default(); let domain = Settings::get().hostname;
let (smtp_server, smtp_port) = { let (smtp_server, smtp_port) = {
let email_and_port = email_config.smtp_server.split(':').collect::<Vec<&str>>(); let email_and_port = email_config.smtp_server.split(':').collect::<Vec<&str>>();

View file

@ -83,12 +83,12 @@ impl actix_web::error::ResponseError for LemmyError {
lazy_static! { lazy_static! {
pub static ref WEBFINGER_COMMUNITY_REGEX: Regex = Regex::new(&format!( pub static ref WEBFINGER_COMMUNITY_REGEX: Regex = Regex::new(&format!(
"^group:([a-z0-9_]{{3, 20}})@{}$", "^group:([a-z0-9_]{{3, 20}})@{}$",
Settings::get().hostname.unwrap_or_default() Settings::get().hostname
)) ))
.unwrap(); .unwrap();
pub static ref WEBFINGER_USER_REGEX: Regex = Regex::new(&format!( pub static ref WEBFINGER_USER_REGEX: Regex = Regex::new(&format!(
"^acct:([a-z0-9_]{{3, 20}})@{}$", "^acct:([a-z0-9_]{{3, 20}})@{}$",
Settings::get().hostname.unwrap_or_default() Settings::get().hostname
)) ))
.unwrap(); .unwrap();
} }

View file

@ -70,7 +70,7 @@ impl RateLimited {
{ {
// Does not need to be blocking because the RwLock in settings never held across await points, // Does not need to be blocking because the RwLock in settings never held across await points,
// and the operation here locks only long enough to clone // and the operation here locks only long enough to clone
let rate_limit: RateLimitConfig = Settings::get().rate_limit.unwrap_or_default(); let rate_limit: RateLimitConfig = Settings::get().rate_limit;
// before // before
{ {

View file

@ -58,11 +58,7 @@ pub(crate) async fn fetch_iframely(
client: &Client, client: &Client,
url: &str, url: &str,
) -> Result<IframelyResponse, LemmyError> { ) -> Result<IframelyResponse, LemmyError> {
let fetch_url = format!( let fetch_url = format!("{}/oembed?url={}", Settings::get().iframely_url, url);
"{}/oembed?url={}",
Settings::get().iframely_url.unwrap_or_default(),
url
);
let response = retry(|| client.get(&fetch_url).send()).await?; let response = retry(|| client.get(&fetch_url).send()).await?;
@ -93,7 +89,7 @@ pub(crate) async fn fetch_pictrs(
let fetch_url = format!( let fetch_url = format!(
"{}/image/download?url={}", "{}/image/download?url={}",
Settings::get().pictrs_url.unwrap_or_default(), Settings::get().pictrs_url,
utf8_percent_encode(image_url, NON_ALPHANUMERIC) // TODO this might not be needed utf8_percent_encode(image_url, NON_ALPHANUMERIC) // TODO this might not be needed
); );

View file

@ -4,19 +4,20 @@ use std::net::{IpAddr, Ipv4Addr};
impl Default for Settings { impl Default for Settings {
fn default() -> Self { fn default() -> Self {
Self { Self {
database: Some(DatabaseConfig::default()), database: DatabaseConfig::default(),
rate_limit: Some(RateLimitConfig::default()), rate_limit: RateLimitConfig::default(),
federation: Some(FederationConfig::default()), federation: FederationConfig::default(),
captcha: Some(CaptchaConfig::default()), captcha: CaptchaConfig::default(),
email: None, email: None,
setup: None, setup: None,
hostname: None, // TODO: not sure how to handle this, its mandatory but not provided by defaults
bind: Some(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))), hostname: "hostname_not_set".into(),
port: Some(8536), bind: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
tls_enabled: Some(true), port: 8536,
jwt_secret: Some("changeme".into()), tls_enabled: true,
pictrs_url: Some("http://pictrs:8080".into()), jwt_secret: "changeme".into(),
iframely_url: Some("http://iframely".into()), pictrs_url: "http://pictrs:8080".into(),
iframely_url: "http://iframely".into(),
} }
} }
} }
@ -62,8 +63,8 @@ impl Default for FederationConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
enabled: false, enabled: false,
allowed_instances: Some("".into()), allowed_instances: "".into(),
blocked_instances: Some("".into()), blocked_instances: "".into(),
} }
} }
} }

View file

@ -0,0 +1,107 @@
use crate::settings::{structs::*, structs_opt::*};
pub(in crate::settings) trait Merge<T> {
fn merge(&mut self, opt: T);
}
impl Merge<SettingsOpt> for Settings {
fn merge(&mut self, opt: SettingsOpt) {
overwrite_if_some(&mut self.hostname, opt.hostname);
overwrite_if_some(&mut self.bind, opt.bind);
overwrite_if_some(&mut self.port, opt.port);
overwrite_if_some(&mut self.tls_enabled, opt.tls_enabled);
overwrite_if_some(&mut self.jwt_secret, opt.jwt_secret);
overwrite_if_some(&mut self.pictrs_url, opt.pictrs_url);
overwrite_if_some(&mut self.iframely_url, opt.iframely_url);
merge_if_some(&mut self.captcha, opt.captcha);
merge_if_some(&mut self.rate_limit, opt.rate_limit);
merge_if_some_opt(&mut self.email, opt.email);
merge_if_some_opt(&mut self.setup, opt.setup);
merge_if_some(&mut self.federation, opt.federation);
merge_if_some(&mut self.database, opt.database);
}
}
impl Merge<RateLimitConfigOpt> for RateLimitConfig {
fn merge(&mut self, opt: RateLimitConfigOpt) {
overwrite_if_some(&mut self.message, opt.message);
overwrite_if_some(&mut self.message_per_second, opt.message_per_second);
overwrite_if_some(&mut self.post, opt.post);
overwrite_if_some(&mut self.post_per_second, opt.post_per_second);
overwrite_if_some(&mut self.register, opt.register);
overwrite_if_some(&mut self.register_per_second, opt.register_per_second);
overwrite_if_some(&mut self.image, opt.image);
overwrite_if_some(&mut self.image_per_second, opt.image_per_second);
}
}
impl Merge<SetupOpt> for Setup {
fn merge(&mut self, opt: SetupOpt) {
overwrite_if_some(&mut self.admin_username, opt.admin_username);
overwrite_if_some(&mut self.admin_password, opt.admin_password);
overwrite_if_some(&mut self.admin_email, opt.admin_email);
overwrite_if_some(&mut self.site_name, opt.site_name);
}
}
impl Merge<EmailConfigOpt> for EmailConfig {
fn merge(&mut self, opt: EmailConfigOpt) {
overwrite_if_some(&mut self.smtp_server, opt.smtp_server);
overwrite_if_some(&mut self.smtp_login, opt.smtp_login);
overwrite_if_some(&mut self.smtp_password, opt.smtp_password);
overwrite_if_some(&mut self.smtp_from_address, opt.smtp_from_address);
overwrite_if_some(&mut self.use_tls, opt.use_tls);
}
}
impl Merge<DatabaseConfigOpt> for DatabaseConfig {
fn merge(&mut self, opt: DatabaseConfigOpt) {
overwrite_if_some(&mut self.user, opt.user);
overwrite_if_some(&mut self.password, opt.password);
overwrite_if_some(&mut self.host, opt.host);
overwrite_if_some(&mut self.port, opt.port);
overwrite_if_some(&mut self.database, opt.database);
overwrite_if_some(&mut self.pool_size, opt.pool_size);
}
}
impl Merge<FederationConfigOpt> for FederationConfig {
fn merge(&mut self, opt: FederationConfigOpt) {
overwrite_if_some(&mut self.enabled, opt.enabled);
overwrite_if_some(&mut self.allowed_instances, opt.allowed_instances);
overwrite_if_some(&mut self.blocked_instances, opt.blocked_instances);
}
}
impl Merge<CaptchaConfigOpt> for CaptchaConfig {
fn merge(&mut self, opt: CaptchaConfigOpt) {
overwrite_if_some(&mut self.enabled, opt.enabled);
overwrite_if_some(&mut self.difficulty, opt.difficulty);
}
}
fn overwrite_if_some<T>(lhs: &mut T, rhs: Option<T>) {
if let Some(x) = rhs {
*lhs = x;
}
}
fn merge_if_some<T, U>(lhs: &mut T, rhs: Option<U>)
where
T: Merge<U>,
{
if let Some(x) = rhs {
lhs.merge(x);
}
}
fn merge_if_some_opt<T, U>(lhs: &mut Option<T>, rhs: Option<U>)
where
T: Merge<U>,
{
if let Some(x) = rhs {
if let Some(y) = lhs {
y.merge(x)
}
}
}

View file

@ -1,11 +1,16 @@
use crate::{location_info, settings::structs::Settings, LemmyError}; use crate::{
use anyhow::Context; location_info,
settings::{merge::Merge, structs::Settings, structs_opt::SettingsOpt},
LemmyError,
};
use anyhow::{anyhow, Context};
use deser_hjson::from_str; use deser_hjson::from_str;
use merge::Merge;
use std::{env, fs, io::Error, sync::RwLock}; use std::{env, fs, io::Error, sync::RwLock};
pub mod defaults; pub mod defaults;
mod merge;
pub mod structs; pub mod structs;
mod structs_opt;
static CONFIG_FILE: &str = "config/config.hjson"; static CONFIG_FILE: &str = "config/config.hjson";
@ -25,13 +30,19 @@ impl Settings {
/// Note: The env var `LEMMY_DATABASE_URL` is parsed in /// Note: The env var `LEMMY_DATABASE_URL` is parsed in
/// `lemmy_db_queries/src/lib.rs::get_database_url_from_env()` /// `lemmy_db_queries/src/lib.rs::get_database_url_from_env()`
fn init() -> Result<Self, LemmyError> { fn init() -> Result<Self, LemmyError> {
let mut config = Settings::default();
// Read the config file // Read the config file
let mut custom_config = from_str::<Settings>(&Self::read_config_file()?)?; config.merge(from_str::<SettingsOpt>(&Self::read_config_file()?)?);
// Merge with default // Read env vars
custom_config.merge(Settings::default()); config.merge(envy::prefixed("LEMMY_").from_env::<SettingsOpt>()?);
Ok(custom_config) if config.hostname == Settings::default().hostname {
return Err(anyhow!("Hostname variable is not set!").into());
}
Ok(config)
} }
/// Returns the config as a struct. /// Returns the config as a struct.
@ -40,7 +51,7 @@ impl Settings {
} }
pub fn get_database_url(&self) -> String { pub fn get_database_url(&self) -> String {
let conf = self.database.to_owned().unwrap_or_default(); let conf = self.database.to_owned();
format!( format!(
"postgres://{}:{}@{}:{}/{}", "postgres://{}:{}@{}:{}/{}",
conf.user, conf.password, conf.host, conf.port, conf.database, conf.user, conf.password, conf.host, conf.port, conf.database,
@ -59,9 +70,7 @@ impl Settings {
let mut allowed_instances: Vec<String> = self let mut allowed_instances: Vec<String> = self
.federation .federation
.to_owned() .to_owned()
.unwrap_or_default()
.allowed_instances .allowed_instances
.unwrap_or_default()
.split(',') .split(',')
.map(|d| d.trim().to_string()) .map(|d| d.trim().to_string())
.collect(); .collect();
@ -74,9 +83,7 @@ impl Settings {
let mut blocked_instances: Vec<String> = self let mut blocked_instances: Vec<String> = self
.federation .federation
.to_owned() .to_owned()
.unwrap_or_default()
.blocked_instances .blocked_instances
.unwrap_or_default()
.split(',') .split(',')
.map(|d| d.trim().to_string()) .map(|d| d.trim().to_string())
.collect(); .collect();
@ -87,15 +94,11 @@ impl Settings {
/// Returns either "http" or "https", depending on tls_enabled setting /// Returns either "http" or "https", depending on tls_enabled setting
pub fn get_protocol_string(&self) -> &'static str { pub fn get_protocol_string(&self) -> &'static str {
if let Some(tls_enabled) = self.tls_enabled { if self.tls_enabled {
if tls_enabled {
"https" "https"
} else { } else {
"http" "http"
} }
} else {
"http"
}
} }
/// Returns something like `http://localhost` or `https://lemmy.ml`, /// Returns something like `http://localhost` or `https://lemmy.ml`,
@ -104,7 +107,7 @@ impl Settings {
format!( format!(
"{}://{}", "{}://{}",
self.get_protocol_string(), self.get_protocol_string(),
self.hostname.to_owned().unwrap_or_default() self.hostname.to_owned()
) )
} }
@ -116,7 +119,6 @@ impl Settings {
self self
.hostname .hostname
.to_owned() .to_owned()
.unwrap_or_default()
.split(':') .split(':')
.collect::<Vec<&str>>() .collect::<Vec<&str>>()
.first() .first()

View file

@ -1,22 +1,21 @@
use merge::Merge;
use serde::Deserialize; use serde::Deserialize;
use std::net::IpAddr; use std::net::IpAddr;
#[derive(Debug, Deserialize, Clone, Merge)] #[derive(Debug, Deserialize, Clone)]
pub struct Settings { pub struct Settings {
pub setup: Option<Setup>, pub setup: Option<Setup>,
pub database: Option<DatabaseConfig>, pub database: DatabaseConfig,
pub hostname: Option<String>, pub hostname: String,
pub bind: Option<IpAddr>, pub bind: IpAddr,
pub port: Option<u16>, pub port: u16,
pub tls_enabled: Option<bool>, pub tls_enabled: bool,
pub jwt_secret: Option<String>, pub jwt_secret: String,
pub pictrs_url: Option<String>, pub pictrs_url: String,
pub iframely_url: Option<String>, pub iframely_url: String,
pub rate_limit: Option<RateLimitConfig>, pub rate_limit: RateLimitConfig,
pub email: Option<EmailConfig>, pub email: Option<EmailConfig>,
pub federation: Option<FederationConfig>, pub federation: FederationConfig,
pub captcha: Option<CaptchaConfig>, pub captcha: CaptchaConfig,
} }
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize, Clone)]
@ -51,6 +50,7 @@ pub struct EmailConfig {
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize, Clone)]
pub struct CaptchaConfig { pub struct CaptchaConfig {
pub enabled: bool, pub enabled: bool,
// TODO: use enum for this
pub difficulty: String, pub difficulty: String,
} }
@ -67,6 +67,6 @@ pub struct DatabaseConfig {
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize, Clone)]
pub struct FederationConfig { pub struct FederationConfig {
pub enabled: bool, pub enabled: bool,
pub allowed_instances: Option<String>, pub allowed_instances: String,
pub blocked_instances: Option<String>, pub blocked_instances: String,
} }

View file

@ -0,0 +1,71 @@
use serde::Deserialize;
use std::net::IpAddr;
#[derive(Debug, Deserialize, Clone)]
pub struct SettingsOpt {
pub setup: Option<SetupOpt>,
pub database: Option<DatabaseConfigOpt>,
pub hostname: Option<String>,
pub bind: Option<IpAddr>,
pub port: Option<u16>,
pub tls_enabled: Option<bool>,
pub jwt_secret: Option<String>,
pub pictrs_url: Option<String>,
pub iframely_url: Option<String>,
pub rate_limit: Option<RateLimitConfigOpt>,
pub email: Option<EmailConfigOpt>,
pub federation: Option<FederationConfigOpt>,
pub captcha: Option<CaptchaConfigOpt>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct SetupOpt {
pub admin_username: Option<String>,
pub admin_password: Option<String>,
pub admin_email: Option<Option<String>>,
pub site_name: Option<String>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct RateLimitConfigOpt {
pub message: Option<i32>,
pub message_per_second: Option<i32>,
pub post: Option<i32>,
pub post_per_second: Option<i32>,
pub register: Option<i32>,
pub register_per_second: Option<i32>,
pub image: Option<i32>,
pub image_per_second: Option<i32>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct EmailConfigOpt {
pub smtp_server: Option<String>,
pub smtp_login: Option<Option<String>>,
pub smtp_password: Option<Option<String>>,
pub smtp_from_address: Option<String>,
pub use_tls: Option<bool>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct CaptchaConfigOpt {
pub enabled: Option<bool>,
pub difficulty: Option<String>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct DatabaseConfigOpt {
pub user: Option<String>,
pub password: Option<String>,
pub host: Option<String>,
pub port: Option<i32>,
pub database: Option<String>,
pub pool_size: Option<u32>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct FederationConfigOpt {
pub enabled: Option<bool>,
pub allowed_instances: Option<String>,
pub blocked_instances: Option<String>,
}

View file

@ -85,10 +85,7 @@ pub struct MentionData {
impl MentionData { impl MentionData {
pub fn is_local(&self) -> bool { pub fn is_local(&self) -> bool {
Settings::get() Settings::get().hostname.eq(&self.domain)
.hostname
.unwrap_or_default()
.eq(&self.domain)
} }
pub fn full_name(&self) -> String { pub fn full_name(&self) -> String {
format!("@{}@{}", &self.name, &self.domain) format!("@{}@{}", &self.name, &self.domain)

View file

@ -56,6 +56,7 @@ RUN addgroup -g 1000 lemmy
RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy
# Copy resources # Copy resources
COPY --chown=lemmy:lemmy config/defaults.hjson /config/defaults.hjson
COPY --chown=lemmy:lemmy --from=builder /app/lemmy_server /app/lemmy COPY --chown=lemmy:lemmy --from=builder /app/lemmy_server /app/lemmy
RUN chown lemmy:lemmy /app/lemmy RUN chown lemmy:lemmy /app/lemmy

View file

@ -38,9 +38,20 @@ services:
- lemmy-alpha - lemmy-alpha
lemmy-alpha: lemmy-alpha:
image: lemmy-federation:latest image: lemmy-federation:latest
volumes:
- ./lemmy_alpha.hjson:/config/config.hjson
environment: environment:
- LEMMY_HOSTNAME=lemmy-alpha:8541
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_alpha:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8541
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-alpha
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- LEMMY_TEST_SEND_SYNC=1 - LEMMY_TEST_SEND_SYNC=1
- RUST_BACKTRACE=1 - RUST_BACKTRACE=1
- RUST_LOG=debug - RUST_LOG=debug
@ -67,9 +78,20 @@ services:
- lemmy-beta - lemmy-beta
lemmy-beta: lemmy-beta:
image: lemmy-federation:latest image: lemmy-federation:latest
volumes:
- ./lemmy_beta.hjson:/config/config.hjson
environment: environment:
- LEMMY_HOSTNAME=lemmy-beta:8551
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_beta:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8551
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-beta
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- LEMMY_TEST_SEND_SYNC=1 - LEMMY_TEST_SEND_SYNC=1
- RUST_BACKTRACE=1 - RUST_BACKTRACE=1
- RUST_LOG=debug - RUST_LOG=debug
@ -96,9 +118,20 @@ services:
- lemmy-gamma - lemmy-gamma
lemmy-gamma: lemmy-gamma:
image: lemmy-federation:latest image: lemmy-federation:latest
volumes:
- ./lemmy_gamma.hjson:/config/config.hjson
environment: environment:
- LEMMY_HOSTNAME=lemmy-gamma:8561
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_gamma:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8561
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-gamma
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- LEMMY_TEST_SEND_SYNC=1 - LEMMY_TEST_SEND_SYNC=1
- RUST_BACKTRACE=1 - RUST_BACKTRACE=1
- RUST_LOG=debug - RUST_LOG=debug
@ -126,9 +159,20 @@ services:
- lemmy-delta - lemmy-delta
lemmy-delta: lemmy-delta:
image: lemmy-federation:latest image: lemmy-federation:latest
volumes:
- ./lemmy_delta.hjson:/config/config.hjson
environment: environment:
- LEMMY_HOSTNAME=lemmy-delta:8571
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_delta:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta
- LEMMY_PORT=8571
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-delta
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- LEMMY_TEST_SEND_SYNC=1 - LEMMY_TEST_SEND_SYNC=1
- RUST_BACKTRACE=1 - RUST_BACKTRACE=1
- RUST_LOG=debug - RUST_LOG=debug
@ -156,9 +200,20 @@ services:
- lemmy-epsilon - lemmy-epsilon
lemmy-epsilon: lemmy-epsilon:
image: lemmy-federation:latest image: lemmy-federation:latest
volumes:
- ./lemmy_epsilon.hjson:/config/config.hjson
environment: environment:
- LEMMY_HOSTNAME=lemmy-epsilon:8581
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_epsilon:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_TLS_ENABLED=false
- LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha
- LEMMY_PORT=8581
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-epsilon
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- LEMMY_TEST_SEND_SYNC=1 - LEMMY_TEST_SEND_SYNC=1
- RUST_BACKTRACE=1 - RUST_BACKTRACE=1
- RUST_LOG=debug - RUST_LOG=debug

View file

@ -1,37 +0,0 @@
{
hostname: lemmy-alpha:8541
port: 8541
tls_enabled: false
jwt_secret: changeme
setup: {
admin_username: lemmy_alpha
admin_password: lemmy
site_name: lemmy-alpha
}
database: {
database: lemmy
user: lemmy
password: password
host: postgres_alpha
port: 5432
pool_size: 5
}
federation: {
enabled: true
allowed_instances: lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon
}
captcha: {
enabled: false
difficulty: medium
}
rate_limit: {
message: 180
message_per_second: 60
post: 99999
post_per_second: 600
register: 99999
register_per_second: 3600
image: 6
image_per_second: 3600
}
}

View file

@ -1,37 +0,0 @@
{
hostname: lemmy-beta:8551
port: 8551
tls_enabled: false
jwt_secret: changeme
setup: {
admin_username: lemmy_beta
admin_password: lemmy
site_name: lemmy-beta
}
database: {
database: lemmy
user: lemmy
password: password
host: postgres_beta
port: 5432
pool_size: 5
}
federation: {
enabled: true
allowed_instances: lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon
}
captcha: {
enabled: false
difficulty: medium
}
rate_limit: {
message: 180
message_per_second: 60
post: 99999
post_per_second: 600
register: 99999
register_per_second: 3600
image: 6
image_per_second: 3600
}
}

View file

@ -1,37 +0,0 @@
{
hostname: lemmy-delta:8571
port: 8571
tls_enabled: false
jwt_secret: changeme
setup: {
admin_username: lemmy_delta
admin_password: lemmy
site_name: lemmy-delta
}
database: {
database: lemmy
user: lemmy
password: password
host: postgres_delta
port: 5432
pool_size: 5
}
federation: {
enabled: true
allowed_instances: lemmy-beta
}
captcha: {
enabled: false
difficulty: medium
}
rate_limit: {
message: 180
message_per_second: 60
post: 99999
post_per_second: 600
register: 99999
register_per_second: 3600
image: 6
image_per_second: 3600
}
}

View file

@ -1,37 +0,0 @@
{
hostname: lemmy-epsilon:8581
port: 8581
tls_enabled: false
jwt_secret: changeme
setup: {
admin_username: lemmy_epsilon
admin_password: lemmy
site_name: lemmy-epsilon
}
database: {
database: lemmy
user: lemmy
password: password
host: postgres_epsilon
port: 5432
pool_size: 5
}
federation: {
enabled: true
blocked_instances: lemmy-alpha
}
captcha: {
enabled: false
difficulty: medium
}
rate_limit: {
message: 180
message_per_second: 60
post: 99999
post_per_second: 600
register: 99999
register_per_second: 3600
image: 6
image_per_second: 3600
}
}

View file

@ -1,37 +0,0 @@
{
hostname: lemmy-gamma:8561
port: 8561
tls_enabled: false
jwt_secret: changeme
setup: {
admin_username: lemmy_gamma
admin_password: lemmy
site_name: lemmy-gamma
}
database: {
database: lemmy
user: lemmy
password: password
host: postgres_gamma
port: 5432
pool_size: 5
}
federation: {
enabled: true
allowed_instances: lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon
}
captcha: {
enabled: false
difficulty: medium
}
rate_limit: {
message: 180
message_per_second: 60
post: 99999
post_per_second: 600
register: 99999
register_per_second: 3600
image: 6
image_per_second: 3600
}
}

View file

@ -29,10 +29,6 @@
password: "password" password: "password"
# host where postgres is running # host where postgres is running
host: "postgres" host: "postgres"
# port where postgres can be accessed
port: 5432
# maximum number of active sql connections
pool_size: 5
} }
# # optional: email sending configuration # # optional: email sending configuration
# email: { # email: {

View file

@ -56,6 +56,7 @@ RUN addgroup -g 1000 lemmy
RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy
# Copy resources # Copy resources
COPY --chown=lemmy:lemmy config/defaults.hjson /config/defaults.hjson
COPY --chown=lemmy:lemmy --from=builder /app/lemmy_server /app/lemmy COPY --chown=lemmy:lemmy --from=builder /app/lemmy_server /app/lemmy
RUN chown lemmy:lemmy /app/lemmy RUN chown lemmy:lemmy /app/lemmy

View file

@ -31,6 +31,7 @@ RUN addgroup --gid 1000 lemmy
RUN adduser --no-create-home --shell /bin/sh --uid 1000 --gid 1000 lemmy RUN adduser --no-create-home --shell /bin/sh --uid 1000 --gid 1000 lemmy
# Copy resources # Copy resources
COPY --chown=lemmy:lemmy config/defaults.hjson /config/defaults.hjson
COPY --chown=lemmy:lemmy --from=builder /app/lemmy_server /app/lemmy COPY --chown=lemmy:lemmy --from=builder /app/lemmy_server /app/lemmy
RUN chown lemmy:lemmy /app/lemmy RUN chown lemmy:lemmy /app/lemmy

View file

@ -28,7 +28,7 @@ services:
lemmy-ui: lemmy-ui:
image: dessalines/lemmy-ui:0.9.7 image: dessalines/lemmy-ui:0.9.7
ports: ports:
- "1235:1234" - "127.0.0.1:1235:1234"
restart: always restart: always
environment: environment:
- LEMMY_INTERNAL_HOST=lemmy:8536 - LEMMY_INTERNAL_HOST=lemmy:8536

View file

@ -37,7 +37,7 @@ async fn main() -> Result<(), LemmyError> {
}; };
let manager = ConnectionManager::<PgConnection>::new(&db_url); let manager = ConnectionManager::<PgConnection>::new(&db_url);
let pool = Pool::builder() let pool = Pool::builder()
.max_size(settings.database.unwrap_or_default().pool_size) .max_size(settings.database.pool_size)
.build(manager) .build(manager)
.unwrap_or_else(|_| panic!("Error connecting to {}", db_url)); .unwrap_or_else(|_| panic!("Error connecting to {}", db_url));
@ -61,8 +61,7 @@ async fn main() -> Result<(), LemmyError> {
println!( println!(
"Starting http server at {}:{}", "Starting http server at {}:{}",
settings.bind.unwrap(), settings.bind, settings.port
settings.port.unwrap_or_default()
); );
let activity_queue = create_activity_queue(); let activity_queue = create_activity_queue();
@ -95,7 +94,7 @@ async fn main() -> Result<(), LemmyError> {
.configure(nodeinfo::config) .configure(nodeinfo::config)
.configure(webfinger::config) .configure(webfinger::config)
}) })
.bind((settings.bind.unwrap(), settings.port.unwrap_or_default()))? .bind((settings.bind, settings.port))?
.run() .run()
.await?; .await?;

View file

@ -39,7 +39,7 @@ use lemmy_server::code_migrations::run_advanced_migrations;
use lemmy_utils::{ use lemmy_utils::{
apub::generate_actor_keypair, apub::generate_actor_keypair,
rate_limit::{rate_limiter::RateLimiter, RateLimit}, rate_limit::{rate_limiter::RateLimiter, RateLimit},
settings::Settings, settings::structs::Settings,
}; };
use lemmy_websocket::{chat_server::ChatServer, LemmyContext}; use lemmy_websocket::{chat_server::ChatServer, LemmyContext};
use reqwest::Client; use reqwest::Client;
@ -58,7 +58,7 @@ fn create_context() -> LemmyContext {
}; };
let manager = ConnectionManager::<PgConnection>::new(&db_url); let manager = ConnectionManager::<PgConnection>::new(&db_url);
let pool = Pool::builder() let pool = Pool::builder()
.max_size(settings.database.unwrap_or_default().pool_size) .max_size(settings.database.pool_size)
.build(manager) .build(manager)
.unwrap(); .unwrap();
embedded_migrations::run(&pool.get().unwrap()).unwrap(); embedded_migrations::run(&pool.get().unwrap()).unwrap();