Skip to content

Commit

Permalink
Merge pull request #1036 from TriliumNext/feat_env-config
Browse files Browse the repository at this point in the history
feat(services/config): Add ability to set Trilium configuration variables via ENV variables
  • Loading branch information
eliandoran authored Jan 26, 2025
2 parents 7ae7831 + 8472e44 commit e4b186c
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 11 deletions.
5 changes: 5 additions & 0 deletions config-sample.ini
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ keyPath=
# once set, expressjs will use the X-Forwarded-For header set by the rev. proxy to determinate the real IPs of clients.
# expressjs shortcuts are supported: loopback(127.0.0.1/8, ::1/128), linklocal(169.254.0.0/16, fe80::/10), uniquelocal(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7)
trustedReverseProxy=false

[Sync]
#syncServerHost=
#syncServerTimeout=
#syncServerProxy=
5 changes: 1 addition & 4 deletions docker_healthcheck.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import http from "http";
import ini from "ini";
import fs from "fs";
import dataDir from "./src/services/data_dir.js";
const config = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, "utf-8"));
import config from "./src/services/config.js";

if (config.Network.https) {
// built-in TLS (terminated by trilium) is not supported yet, PRs are welcome
Expand Down
76 changes: 75 additions & 1 deletion src/services/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fs from "fs";
import dataDir from "./data_dir.js";
import path from "path";
import resourceDir from "./resource_dir.js";
import { envToBoolean } from "./utils.js";

const configSampleFilePath = path.resolve(resourceDir.RESOURCE_DIR, "config-sample.ini");

Expand All @@ -14,6 +15,79 @@ if (!fs.existsSync(dataDir.CONFIG_INI_PATH)) {
fs.writeFileSync(dataDir.CONFIG_INI_PATH, configSample);
}

const config = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, "utf-8"));
const iniConfig = ini.parse(fs.readFileSync(dataDir.CONFIG_INI_PATH, "utf-8"));

export interface TriliumConfig {
General: {
instanceName: string;
noAuthentication: boolean;
noBackup: boolean;
noDesktopIcon: boolean;
};
Network: {
host: string;
port: string;
https: boolean;
certPath: string;
keyPath: string;
trustedReverseProxy: boolean | string;
};
Sync: {
syncServerHost: string;
syncServerTimeout: string;
syncProxy: string;
};
}

//prettier-ignore
const config: TriliumConfig = {

General: {
instanceName:
process.env.TRILIUM_GENERAL_INSTANCENAME || iniConfig.General.instanceName || "",

noAuthentication:
envToBoolean(process.env.TRILIUM_GENERAL_NOAUTHENTICATION) || iniConfig.General.noAuthentication || false,

noBackup:
envToBoolean(process.env.TRILIUM_GENERAL_NOBACKUP) || iniConfig.General.noBackup || false,

noDesktopIcon:
envToBoolean(process.env.TRILIUM_GENERAL_NODESKTOPICON) || iniConfig.General.noDesktopIcon || false
},

Network: {
host:
process.env.TRILIUM_NETWORK_HOST || iniConfig.Network.host || "0.0.0.0",

port:
process.env.TRILIUM_NETWORK_PORT || iniConfig.Network.port || "3000",

https:
envToBoolean(process.env.TRILIUM_NETWORK_HTTPS) || iniConfig.Network.https || false,

certPath:
process.env.TRILIUM_NETWORK_CERTPATH || iniConfig.Network.certPath || "",

keyPath:
process.env.TRILIUM_NETWORK_KEYPATH || iniConfig.Network.keyPath || "",

trustedReverseProxy:
process.env.TRILIUM_NETWORK_TRUSTEDREVERSEPROXY || iniConfig.Network.trustedReverseProxy || false
},

Sync: {
syncServerHost:
process.env.TRILIUM_SYNC_SERVER_HOST || iniConfig?.Sync?.syncServerHost || "",

syncServerTimeout:
process.env.TRILIUM_SYNC_SERVER_TIMEOUT || iniConfig?.Sync?.syncServerTimeout || "120000",

syncProxy:
// additionally checking in iniConfig for inconsistently named syncProxy for backwards compatibility
process.env.TRILIUM_SYNC_SERVER_PROXY || iniConfig?.Sync?.syncProxy || iniConfig?.Sync?.syncServerProxy || ""
}

};

export default config;
2 changes: 1 addition & 1 deletion src/services/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function getRunAtHours(note: BNote): number[] {
}

function runNotesWithLabel(runAttrValue: string) {
const instanceName = config.General ? config.General.instanceName : null;
const instanceName = config.General.instanceName;
const currentHours = new Date().getHours();
const notes = attributeService.getNotesWithLabel("run", runAttrValue);

Expand Down
7 changes: 3 additions & 4 deletions src/services/sync_options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use strict";

import optionService from "./options.js";
import type { OptionNames } from "./options_interface.js";
import config from "./config.js";

/*
Expand All @@ -11,14 +10,14 @@ import config from "./config.js";
* to live sync server.
*/

function get(name: OptionNames) {
return (config["Sync"] && config["Sync"][name]) || optionService.getOption(name);
function get(name: keyof typeof config.Sync) {
return (config["Sync"] && config["Sync"][name]) || optionService.getOption(name);
}

export default {
// env variable is the easiest way to guarantee we won't overwrite prod data during development
// after copying prod document/data directory
getSyncServerHost: () => process.env.TRILIUM_SYNC_SERVER_HOST || get("syncServerHost"),
getSyncServerHost: () => get("syncServerHost"),
isSyncSetup: () => {
const syncServerHost = get("syncServerHost");

Expand Down
15 changes: 14 additions & 1 deletion src/services/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,18 @@ export function isString(x: any) {
return Object.prototype.toString.call(x) === "[object String]";
}

// try to turn 'true' and 'false' strings from process.env variables into boolean values or undefined
export function envToBoolean(val: string | undefined) {
if (val === undefined || typeof val !== "string") return undefined;

const valLc = val.toLowerCase().trim();

if (valLc === "true") return true;
if (valLc === "false") return false;

return undefined;
}

/**
* Returns the directory for resources. On Electron builds this corresponds to the `resources` subdirectory inside the distributable package.
* On development builds, this simply refers to the root directory of the application.
Expand Down Expand Up @@ -352,5 +364,6 @@ export default {
isString,
getResourceDir,
isMac,
isWindows
isWindows,
envToBoolean
};

0 comments on commit e4b186c

Please sign in to comment.