feat(server-setup): replace nginx with caddy
Test / test (push) Successful in 1m14s

Assisted-by: GLM 5.3 Flash
This commit is contained in:
2026-09-29 00:32:44 +02:00
parent 37e06d090c
commit 108a166ee0
3 changed files with 63 additions and 11 deletions
+43 -10
View File
@@ -44,7 +44,7 @@
use strict;
use warnings;
my $VERSION = '2.0.0';
my $VERSION = '2.1.0';
my $BOLD = "\033[1m";
my $RED = "\033[31m";
@@ -67,16 +67,39 @@ my %SUPPORTED_OS = (
);
# Base packages installed on Fedora, CentOS Stream and openEuler alike.
# caddy is the reverse proxy the deploy scripts serve the endpoints through;
# openEuler ships no package for it, and install_packages says so and leaves
# it to the script that needs it.
my @BASE_PACKAGES = qw(
nano curl wget htop tmux rsync nginx openssl jq fastfetch
nano curl wget htop tmux rsync caddy openssl jq fastfetch
);
# Services to open in firewalld by default. ssh is mandatory: losing it means
# locking out remote administration.
my @FIREWALL_SERVICES = ('ssh');
# Opened in firewalld only when nginx is installed, which it is by default.
my @NGINX_FIREWALL_SERVICES = ('http', 'https');
# Opened in firewalld only when caddy is installed, which it is by default
# wherever the package exists.
my @CADDY_FIREWALL_SERVICES = ('http', 'https');
# The one base package a distribution's repositories do not carry, with the
# reason and who provides it instead.
my %UNPACKAGED = (
openeuler => {
caddy => 'openEuler ships no caddy package; the scripts that need the '
. 'proxy install the release binary themselves',
},
);
# Test-visible accessors: the catalogue is lexical to this file, so the checks
# under tests/ read the base package list and the unpackaged map through these.
sub base_packages { return @BASE_PACKAGES; }
sub unpackaged_for {
my ($os_id) = @_;
return () unless exists $UNPACKAGED{$os_id};
return %{ $UNPACKAGED{$os_id} };
}
# dnf-automatic configuration file. dnf 4 ships it with defaults; dnf 5 reads host
# overrides from this path (its own defaults live in /usr/share/dnf5).
@@ -565,19 +588,29 @@ sub ensure_epel {
# ---------------------------------------------------------------------------
sub install_packages {
my ($dry_run) = @_;
my (@installed, @skipped, @failed, @to_install);
my ($os_id, $dry_run) = @_;
my (@installed, @skipped, @failed, @to_install, @unpackaged);
_status('Checking base packages');
for my $pkg (@BASE_PACKAGES) {
# exists and not a bare lookup: descending into a missing os key
# would autovivify it.
if (exists $UNPACKAGED{$os_id} && exists $UNPACKAGED{$os_id}{$pkg}) {
push @unpackaged, [$pkg, $UNPACKAGED{$os_id}{$pkg}];
next;
}
if (rpm_installed($pkg)) { push @skipped, $pkg }
else { push @to_install, $pkg }
}
my $already = scalar @skipped;
my $missing = scalar @to_install;
my $total = scalar @BASE_PACKAGES;
my $total = scalar @BASE_PACKAGES - scalar @unpackaged;
_status_done("$already/$total already installed");
for my $entry (@unpackaged) {
my ($pkg, $reason) = @$entry;
_info("$pkg is not packaged on this distribution: $reason");
}
if (!@to_install) {
_ok('All base packages already present');
@@ -663,9 +696,9 @@ sub setup_firewall {
$info{installed} = 1;
}
# ssh is mandatory; http and https only when nginx is present.
# ssh is mandatory; http and https only when caddy is present.
my @services = @FIREWALL_SERVICES;
push @services, @NGINX_FIREWALL_SERVICES if rpm_installed('nginx');
push @services, @CADDY_FIREWALL_SERVICES if rpm_installed('caddy');
# --- Permanent rules first, through the offline client, which needs no daemon
my $permanent_changed = 0;
@@ -1776,7 +1809,7 @@ sub main {
# 3. Base packages
print STDERR "\n${BOLD}── Base Packages ──$RESET\n";
if (!$opt{skip_packages}) {
$results{packages} = install_packages($opt{dry_run});
$results{packages} = install_packages($os_id, $opt{dry_run});
if (@{ $results{packages}{failed} }) {
push @warnings, 'Some packages failed to install: '
. join(', ', @{ $results{packages}{failed} });