added https for client and managment

This commit is contained in:
Philipp
2026-05-21 15:11:05 +02:00
parent 0046156e58
commit e5bcce5dbb
8 changed files with 129 additions and 11 deletions
+4
View File
@@ -7,6 +7,10 @@ RESTIC_KEEP_HOURLY=0
RESTIC_KEEP_DAILY=7
RESTIC_KEEP_WEEKLY=0
RESTIC_KEEP_MONTHLY=0
HOST="0.0.0.0"
PORT=3000
API_TOKEN="change-me-to-at-least-32-characters"
HTTPS_ENABLED=false
TLS_CERT_FILE=""
TLS_KEY_FILE=""
ALLOWED_MANAGEMENT_IPS=""
+16
View File
@@ -17,7 +17,11 @@ export const requiredEnv = [
export const config = {
port: Number(process.env.PORT || 3000),
host: process.env.HOST || '0.0.0.0',
apiToken: process.env.API_TOKEN || '',
httpsEnabled: process.env.HTTPS_ENABLED === 'true',
tlsCertFile: process.env.TLS_CERT_FILE || '',
tlsKeyFile: process.env.TLS_KEY_FILE || '',
allowedManagementIps: (process.env.ALLOWED_MANAGEMENT_IPS || '')
.split(',')
.map((value) => value.trim())
@@ -41,6 +45,10 @@ if (!config.apiToken || config.apiToken.length < minApiTokenLength) {
throw new Error(`API_TOKEN is required and must be at least ${minApiTokenLength} characters long.`);
}
if (config.httpsEnabled && (!config.tlsCertFile || !config.tlsKeyFile)) {
throw new Error('TLS_CERT_FILE and TLS_KEY_FILE are required when HTTPS_ENABLED=true.');
}
export const editableEnv = [
{ key: 'AWS_ACCESS_KEY_ID', label: 'AWS access key ID', required: true, secret: true },
{ key: 'AWS_SECRET_ACCESS_KEY', label: 'AWS secret access key', required: true, secret: true },
@@ -52,7 +60,11 @@ export const editableEnv = [
{ key: 'RESTIC_KEEP_WEEKLY', label: 'Keep weekly snapshots', required: false, secret: false },
{ key: 'RESTIC_KEEP_MONTHLY', label: 'Keep monthly snapshots', required: false, secret: false },
{ key: 'PORT', label: 'API port', required: false, secret: false },
{ key: 'HOST', label: 'API bind host', required: false, secret: false },
{ key: 'API_TOKEN', label: 'API token', required: true, secret: true },
{ key: 'HTTPS_ENABLED', label: 'Enable HTTPS', required: false, secret: false },
{ key: 'TLS_CERT_FILE', label: 'TLS certificate file', required: false, secret: false },
{ key: 'TLS_KEY_FILE', label: 'TLS private key file', required: false, secret: false },
{ key: 'ALLOWED_MANAGEMENT_IPS', label: 'Allowed management IPs', required: false, secret: false },
];
@@ -122,7 +134,11 @@ function applyRuntimeEnv(values) {
process.env[key] = value;
}
config.port = Number(process.env.PORT || 3000);
config.host = process.env.HOST || '0.0.0.0';
config.apiToken = process.env.API_TOKEN || '';
config.httpsEnabled = process.env.HTTPS_ENABLED === 'true';
config.tlsCertFile = process.env.TLS_CERT_FILE || '';
config.tlsKeyFile = process.env.TLS_KEY_FILE || '';
config.allowedManagementIps = (process.env.ALLOWED_MANAGEMENT_IPS || '')
.split(',')
.map((value) => value.trim())
+20 -2
View File
@@ -1,5 +1,8 @@
import cors from 'cors';
import express from 'express';
import http from 'node:http';
import https from 'node:https';
import { readFile } from 'node:fs/promises';
import { config } from './config.js';
import { backupRouter } from './routes/backup.js';
import { healthRouter } from './routes/health.js';
@@ -47,10 +50,25 @@ app.use((error, _req, res, _next) => {
res.status(status).json({ error: error.message || 'Internal server error.' });
});
app.listen(config.port, () => {
console.log(`Incus backup API listening on http://localhost:${config.port}`);
startServer().catch((error) => {
console.error(`Failed to start Incus backup API: ${error.message}`);
process.exit(1);
});
startScheduler().catch((error) => {
console.error(`Failed to start scheduler: ${error.message}`);
});
async function startServer() {
const protocol = config.httpsEnabled ? 'https' : 'http';
const server = config.httpsEnabled
? https.createServer({
cert: await readFile(config.tlsCertFile),
key: await readFile(config.tlsKeyFile),
}, app)
: http.createServer(app);
server.listen(config.port, config.host, () => {
console.log(`Incus backup API listening on ${protocol}://${config.host}:${config.port}`);
});
}