Ubuntu 22.04 安装 Alf.io 2.0-M5-2609 指南
在 Ubuntu 22.04 服务器上从零安装开源票务系统 Alf.io 2.0-M5-2609 的完整指南,覆盖在线与离线两种方案、systemd 托管、Nginx HTTPS 反向代理、验证命令与常见问题排障。
Ubuntu 22.04 安装 Alf.io 2.0-M5-2609 指南
目标:在 Ubuntu 22.04 服务器上从零完成开源票务系统 Alf.io 2.0-M5-2609 的安装,包括 JDK 17 与 PostgreSQL 14 依赖、官方发布件部署、systemd 服务托管、Nginx HTTPS 反向代理、安装验证与卸载清理。本文提供「在线安装」与「离线安装」两种方案,全部命令与回显均在 Ubuntu 22.04.5 LTS(x86_64)实测通过。组件背景与选型对比见 《Alf.io 2.0-M5-2609 介绍与选型指南》。
一、环境信息
本章列出版文所依赖的实测环境,便于读者对照复现。
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Java 运行时:OpenJDK 17.0.20.1(
openjdk-17-jre-headless,Alf.io 要求 Java 17) - 数据库:PostgreSQL 14.24-0ubuntu0.22.04.1(Alf.io 仅支持 PostgreSQL,10 及以上版本)
- 反向代理:Nginx 1.18.0-6ubuntu14.21(负责 HTTPS 终结)
- Alf.io 版本:2.0-M5-2609(官方发布件
alfio-2.0-M5-2609-boot.jar,约 79.5 MB / 83405439 字节) - 部署目录:
/opt/alfio/ - 运行账号:专用系统账号
alfio - 端口规划:应用本体 8080(本机回环)、PostgreSQL 5432(本机回环)、Nginx 对外 8443(HTTPS)
- 示例域名:
alfio.example.local(生产环境替换为你的真实域名)
二、前置条件
安装开始前需要确认服务器具备以下条件,每一项都给出验证命令与预期回显。
2.1 操作系统与权限
要求 root 或具备 sudo 权限的账号。确认系统版本:
cat /etc/os-release | grep PRETTY
实测输出:
PRETTY_NAME="Ubuntu 22.04.5 LTS"
2.2 网络与软件源
在线方案要求服务器能访问 Ubuntu 软件源与 GitHub。更新索引确认软件源可用:
apt-get update
实测输出(节选):
Get:7 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 Packages [1325 kB]
Get:8 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [4759 kB]
Fetched 12.5 MB in 4s (2866 kB/s)
Reading package lists...
⚠️ 注意:离线安装的服务器不要求外网连通,方案 B(第五章)会先在可联网环境把依赖下载为 deb 包,再拷贝到内网服务器安装。
2.3 硬件要求
官方 Getting Started 给出的最低要求:外置数据库部署 1 vCPU / 512MB 内存;数据库与应用同机部署 1 vCPU / 1GB 内存。本文按「应用与 PostgreSQL 同机」的最小可用形态实测,磁盘预留 2GB 以上(JAR 本体约 80MB,加数据库与日志余量)。
2.4 PostgreSQL 的必要性
Alf.io 是 Java 单体 Web 应用,唯一外部依赖是 PostgreSQL(不支持 MySQL/MariaDB)。应用启动时通过内置 Flyway 自动建表迁移,无需手工导入表结构。官方 README 同时要求:数据库账号不要使用超级用户(SUPERUSER),否则行级安全策略校验会被跳过——后文 4.5 节创建的 alfio 角色即普通角色。
三、版本选型说明
Alf.io 的版本号形如 2.0-M5-2609,含义是「2.0 第 5 个里程碑(M5)+ 构建年月(2609 = 2026 年 9 月)」。安装前先确认官方最新稳定版:
curl -s https://github.com/alfio-event/alf.io/releases.atom | grep -oE "<title>[^<]+</title>" | head -5
实测输出(查询日期 2026-10-23):
<title>Release 2.0-M5-2609</title>
<title>Release 2.0-M5-2606</title>
<title>Release 2.0-M5-2509-1</title>
<title>Release 2.0-M5-2509</title>
官方 Docker Hub 镜像 alfio/alf.io 的 latest 标签与 2.0-M5-2609 同日推送,两者指向同一构建。
关键差异与选型建议:2.0-M5-2609(2026-09-18 发布)是当前最新稳定版,为安全修复版,修复了扩展脚本相关的越权与 RCE 问题;若有存量部署停留在 2.0-M5-2509 或更早,建议直接升级到 2.0-M5-2609。本文全部步骤以 2.0-M5-2609 为准,安装其他版本只需替换下载 URL 与文件名中的版本号。
四、方案 A:在线安装(apt 依赖 + 官方发布件 JAR)
本章从零开始:安装 JDK 17、PostgreSQL 14、Nginx 三个依赖 → 下载官方 JAR → 建库建账号 → 写配置 → systemd 托管 → 首次启动拿管理员凭据 → 验证。全程约 10 分钟。
4.1 安装基础依赖
Alf.io 运行只需要 JRE(运行时环境),无需完整 JDK。一条命令装齐三个依赖:
apt-get install -y openjdk-17-jre-headless postgresql nginx
实测输出(节选,末尾阶段):
Setting up nginx (1.18.0-6ubuntu14.21) ...
Setting up postgresql-contrib (14+238) ...
Setting up postgresql (14+238) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...
安装完成后确认 Java 版本:
java -version
实测输出:
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
确认 PostgreSQL 服务已自启并监听本机回环:
systemctl is-active postgresql
ss -ltn | grep 5432
实测输出:
active
LISTEN 0 244 127.0.0.1:5432 0.0.0.0:*
LISTEN 0 244 [::1]:5432 [::]:*
💡 说明:PostgreSQL 14 默认只监听
127.0.0.1:5432,Alf.io 与数据库同机部署时无需放开外部监听,这是安全的默认值。
4.2 下载官方发布件
从 GitHub Releases 下载自包含的 Spring Boot 可执行 JAR,并计算 sha256 校验:
cd /tmp
wget https://github.com/alfio-event/alf.io/releases/download/2.0-M5-2609/alfio-2.0-M5-2609-boot.jar
sha256sum alfio-2.0-M5-2609-boot.jar
实测输出:
--2026-10-22 21:23:30-- https://github.com/alfio-event/alf.io/releases/download/2.0-M5-2609/alfio-2.0-M5-2609-boot.jar
Resolving github.com (github.com)... 20.205.243.166
Connecting to github.com (github.com)|20.205.243.166|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 83405439 (80M) [application/octet-stream]
Saving to: 'alfio-2.0-M5-2609-boot.jar'
alfio-2.0-M5-2609-bo 100%[===================>] 79.55M 12.7MB/s in 6.3s
2026-10-22 21:23:37 (12.7 MB/s) - 'alfio-2.0-M5-2609-boot.jar' saved [83405439/83405439]
c769aa49fbd25ce8c348d78e4946b759dfa318bb7bffc0521378b78189176f39 alfio-2.0-M5-2609-boot.jar
💡 说明:
83405439字节与c769aa49…76f39校验值即 2.0-M5-2609 版本发布件指纹,下载后核对一致再继续。
4.3 部署目录与运行账号
按最小权限原则创建专用系统账号,部署目录归其所有:
useradd -r -m -d /opt/alfio -s /usr/sbin/nologin alfio
cp /tmp/alfio-2.0-M5-2609-boot.jar /opt/alfio/
chown -R alfio:alfio /opt/alfio
ls -la /opt/alfio/
实测输出:
total 81456
drwxr-xr-x 2 alfio alfio 4096 Oct 22 21:23 .
drwxr-xr-x 4 root root 4096 Oct 22 21:23 ..
-rw-r--r-- 1 alfio alfio 83405439 Sep 18 07:02 alfio-2.0-M5-2609-boot.jar
4.4 初始化 PostgreSQL 数据库
创建普通角色 alfio(带密码)与同名数据库。密码用固定测试口令 q1w2e3r4,生产环境请换成强口令:
su postgres -c "psql -c \"CREATE ROLE alfio LOGIN PASSWORD 'q1w2e3r4';\""
su postgres -c "psql -c \"CREATE DATABASE alfio OWNER alfio;\""
su postgres -c "psql -c '\\du'"
实测输出:
CREATE ROLE
CREATE DATABASE
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
alfio | | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
⚠️ 注意:
CREATE ROLE必须带LOGIN PASSWORD。若创建时漏了密码,Alf.io 启动时会报FATAL: password authentication failed for user "alfio"(排障见 8.1 节)。
4.5 外部配置文件
Alf.io 的外部配置文件放在 JAR 同目录的 application.properties,Spring Boot 启动时自动读取。写入数据库连接与基础安全项:
cat > /opt/alfio/application.properties <<'EOF'
# Alf.io external configuration
datasource.url=jdbc:postgresql://localhost:5432/alfio
datasource.username=alfio
datasource.password=q1w2e3r4
alfio.base-url=https://alfio.example.local
server.forward-headers-strategy=native
server.servlet.session.cookie.http-only=true
server.servlet.session.timeout=2h
server.compression.enabled=true
server.shutdown=graceful
spring.application.name=Alf.io
logging.level.root=warn
logging.level.alfio=info
EOF
chown alfio:alfio /opt/alfio/application.properties
逐项说明:
| 配置项 | 取值 | 说明 |
|---|---|---|
datasource.url | jdbc:postgresql://localhost:5432/alfio | 数据库 JDBC 连接串,指向 4.4 节创建的库 |
datasource.username / datasource.password | alfio / q1w2e3r4 | 数据库账号密码,与 4.4 节一致 |
alfio.base-url | https://alfio.example.local | 应用对外基础 URL,用于邮件链接与跳转 |
server.forward-headers-strategy | native | 让应用信任反向代理传来的 X-Forwarded-* 头 |
server.servlet.session.cookie.http-only | true | 会话 Cookie 禁止 JS 读取 |
server.servlet.session.timeout | 2h | 会话有效期 |
server.compression.enabled | true | HTTP 响应压缩 |
server.shutdown | graceful | 优雅停机,systemd 停止时不丢请求 |
logging.level.root / logging.level.alfio | warn / info | 日志级别:框架告警级,业务信息级 |
⚠️ 注意:
alfio.base-url属性只影响应用内部生成的链接;管理后台的「Base URL」配置键(BASE_URL)需要在首次登录后的基础设置向导中填写(见 7.4 节),两者建议保持一致。实测中未配置后台BASE_URL键时,通过 API 创建活动会失败(见 8.4 节)。
4.6 systemd 托管
创建服务单元,JVM 堆内存显式限制在 256–512MB(本文选择 -Xms256m -Xmx512m):
cat > /etc/systemd/system/alfio.service <<'EOF'
[Unit]
Description=Alf.io ticket reservation system
After=network.target postgresql.service
Wants=postgresql.service
[Service]
Type=simple
User=alfio
WorkingDirectory=/opt/alfio
ExecStart=/usr/bin/java -Xms256m -Xmx512m -jar /opt/alfio/alfio-2.0-M5-2609-boot.jar
SuccessExitStatus=143
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable alfio
systemctl start alfio
systemctl is-active alfio
实测输出:
Created symlink /etc/systemd/system/multi-user.target.wants/alfio.service → /etc/systemd/system/alfio.service.
active
单元文件逐项说明:
| 配置项 | 取值 | 说明 |
|---|---|---|
After / Wants=postgresql.service | — | 保证数据库先于应用启动 |
User=alfio | — | 以非特权账号运行 |
WorkingDirectory=/opt/alfio | — | 使 Spring Boot 读取该目录下的 application.properties |
ExecStart 的 -Xms256m -Xmx512m | — | 初始堆 256MB、最大堆 512MB,符合官方最低内存要求 |
SuccessExitStatus=143 | — | SIGTERM 正常退出码,避免优雅停机被记为失败 |
Restart=on-failure / RestartSec=10 | — | 异常退出 10 秒后自动拉起 |
4.7 首次启动与管理员凭据
Alf.io 首次启动时自动建表、初始化,并随机生成管理员账号 admin 的初始密码,打印在服务日志里。查看:
journalctl -u alfio --no-pager | grep -A 2 "generated admin credentials"
实测输出:
Oct 22 21:24:04 alfio-b1 java[6729]: 2026-10-22T21:24:04.798Z INFO 6729 --- [Alf.io] [ main] a.c.ConfigurationStatusChecker : here the generated admin credentials:
Oct 22 21:24:04 alfio-b1 java[6729]: 2026-10-22T21:24:04.808Z INFO 6729 --- [Alf.io] [ main] a.c.ConfigurationStatusChecker : initialized alf.io version 2.0-M5-2609
Oct 22 21:24:04 alfio-b1 java[6729]: 2026-10-22T21:24:04.809Z INFO 6729 --- [Alf.io] [ main] a.c.SpringBootLauncher : Started SpringBootLauncher in 4.532 seconds (process running for 5.092)
generated admin credentials: 下一行即为随机初始密码(本例为 5qS&ZoSjXsApI3b%&mN)。立即记录该密码并登录后台修改;忘记且未修改过时,可按 8.2 节重新生成。启动耗时约 5 秒(Started SpringBootLauncher in 4.532 seconds)。
4.8 安装验证
依次确认进程、监听端口与 HTTP 响应:
ps -ef | grep [a]lfio
ss -ltn | grep 8080
curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}\n" http://localhost:8080/
实测输出:
alfio 9045 1 0 00:39 ? 00:00:47 /usr/bin/java -Xms256m -Xmx512m -jar /opt/alfio/alfio-2.0-M5-2609-boot.jar
LISTEN 0 50 *:8080 *:*
302 -> https://localhost:8443/
💡 说明:应用主进程由 systemd 以
alfio账号运行,堆参数-Xms256m -Xmx512m生效;http://localhost:8080/返回 302 跳转到alfio.base-url指向的对外地址,说明基础 URL 已生效(详见 8.5 节)。
管理后台登录验证(Nginx 配好后也可直接对 8443 做):
curl -sk -o /dev/null -w "%{http_code} %{redirect_url}\n" https://localhost:8443/admin/
curl -sk https://localhost:8443/admin/ | grep -oE "<title>[^<]+</title>"
实测输出:
302 https://localhost:8443/authentication
<title>Alf.io Admin</title>
未登录访问 /admin/ 会 302 到登录页 /authentication,登录页标题为 Alf.io Admin,说明 Web 后台正常。
五、方案 B:离线安装(deb 离线包 + 离线 JAR)
内网隔离环境无法访问 Ubuntu 源与 GitHub。方案 B 在可联网的同版本环境预先下载全部 deb 依赖与 JAR,打包拷入内网后离线安装。实测在全新 Ubuntu 22.04 环境完整走通。
5.1 制作离线依赖包(联网环境执行)
在目标系统同版本(Ubuntu 22.04)的联网环境中,用 apt-get download 把 openjdk-17-jre-headless、postgresql、nginx 及其全部递归依赖下载为 deb 文件:
mkdir -p /opt/alfio-debs && cd /opt/alfio-debs
apt-get update
apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests \
--no-conflicts --no-breaks --no-replaces --no-enhances \
openjdk-17-jre-headless postgresql nginx | grep "^\w" | sort -u)
du -sh /opt/alfio-debs
ls /opt/alfio-debs | wc -l
实测输出(节选):
Get:90 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 postgresql-14 amd64 14.24-0ubuntu0.22.04.1 [16.3 MB]
Get:91 http://archive.ubuntu.com/ubuntu jammy/main amd64 postgresql all 14+238 [3288 B]
Get:92 http://archive.ubuntu.com/ubuntu jammy/main amd64 postgresql-contrib all 14+238 [3292 B]
Download complete and in download only mode
110M /opt/alfio-debs
95
共 95 个 deb 文件、约 110MB。连同 JAR 一起打包:
cp /tmp/alfio-2.0-M5-2609-boot.jar /opt/alfio-debs/
tar -czf alfio-2.0-M5-2609-offline.tar.gz -C /opt alfio-debs
把 alfio-2.0-M5-2609-offline.tar.gz 通过内网介质(U 盘/内网文件服务)拷贝到目标服务器。
5.2 离线安装依赖(目标服务器执行)
解包并用 dpkg 批量安装全部 deb:
tar -xzf alfio-2.0-M5-2609-offline.tar.gz -C /opt
dpkg -i /opt/alfio-debs/*.deb
实测输出(节选):
Setting up nginx-common (1.18.0-6ubuntu14.21) ...
Setting up postgresql-14 (14.24-0ubuntu0.22.04.1) ...
Setting up nginx-core (1.18.0-6ubuntu14.21) ...
Setting up nginx (1.18.0-6ubuntu14.21) ...
Setting up openjdk-17-jre-headless:amd64 (17.0.20.1+1-1~22.04) ...
安装结果与依赖补齐情况:
java -version
systemctl is-enabled postgresql
systemctl is-active postgresql
实测输出:
openjdk version "17.0.20.1" 2026-08-18
enabled
active
💡 说明:
dpkg -i不解析网络依赖,95 个包内已包含全部递归依赖,顺序由 dpkg 自行排序;个别包提示依赖未满足时,对同一目录重跑一次dpkg -i /opt/alfio-debs/*.deb即可。
5.3 部署 Alf.io 与初始化数据库
与方案 A 相同:建账号、放 JAR、写配置、建库(离线 JAR 已在 /opt/alfio-debs/ 内):
useradd -r -m -d /opt/alfio -s /usr/sbin/nologin alfio
cp /opt/alfio-debs/alfio-2.0-M5-2609-boot.jar /opt/alfio/
chown -R alfio:alfio /opt/alfio
cat > /opt/alfio/application.properties <<'EOF'
# Alf.io external configuration
datasource.url=jdbc:postgresql://localhost:5432/alfio
datasource.username=alfio
datasource.password=q1w2e3r4
alfio.base-url=https://alfio.example.local
server.forward-headers-strategy=native
server.servlet.session.cookie.http-only=true
server.servlet.session.timeout=2h
server.compression.enabled=true
server.shutdown=graceful
spring.application.name=Alf.io
logging.level.root=warn
logging.level.alfio=info
EOF
chown alfio:alfio /opt/alfio/application.properties
su postgres -c "psql -c \"CREATE ROLE alfio LOGIN PASSWORD 'q1w2e3r4';\""
su postgres -c "psql -c \"CREATE DATABASE alfio OWNER alfio;\""
实测输出:
CREATE ROLE
CREATE DATABASE
5.4 systemd 托管与验证
创建与 4.6 节完全相同的服务单元并启动:
cat > /etc/systemd/system/alfio.service <<'EOF'
[Unit]
Description=Alf.io ticket reservation system
After=network.target postgresql.service
Wants=postgresql.service
[Service]
Type=simple
User=alfio
WorkingDirectory=/opt/alfio
ExecStart=/usr/bin/java -Xms256m -Xmx512m -jar /opt/alfio/alfio-2.0-M5-2609-boot.jar
SuccessExitStatus=143
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable alfio
systemctl start alfio
systemctl is-active alfio
journalctl -u alfio --no-pager | grep -A 2 "generated admin credentials"
实测输出:
Created symlink /etc/systemd/system/multi-user.target.wants/alfio.service → /etc/systemd/system/alfio.service.
active
Oct 22 21:30:27 alfio-offline java[6251]: 2026-10-22T21:30:27.346Z INFO 6251 --- [Alf.io] [ main] a.c.ConfigurationStatusChecker : initialized alf.io version 2.0-M5-2609
Oct 22 21:30:27 alfio-offline java[6251]: 2026-10-22T21:30:27.348Z INFO 6251 --- [Alf.io] [ main] a.c.SpringBootLauncher : Started SpringBootLauncher in 5.02 seconds (process running for 5.627)
generated admin credentials: 下一行即本次随机生成的初始密码(本例为 W7~dxqq5ZMPadMV=)St2)。端口验证:
ss -ltn | grep 8080
实测输出:
LISTEN 0 50 *:8080 *:*
离线方案到此完成,后续 Nginx 反向代理(7.1 节)与方案 A 完全一致。Nginx 已随 deb 包装好,无需再联网。
六、方案对比与选择建议
两种方案的差异汇总如下:
| 维度 | 方案 A:在线安装 | 方案 B:离线安装 |
|---|---|---|
| 依赖获取 | apt-get install 实时拉取 | 预先 apt-get download 95 个 deb(约 110MB) |
| 是否需外网 | 安装机需访问 Ubuntu 源 + GitHub | 仅制作离线包的机器需外网,安装机全程离线 |
| JAR 获取 | wget 官方 Releases 直链 | 随离线包拷入 |
| systemd 服务名 | alfio.service(自建单元) | 同左 |
| 应用监听端口 | 8080 | 8080 |
| 版本一致性 | 由软件源当时状态决定 | 离线包制作时锁定 |
| 适用场景 | 可联网的云主机、办公服务器 | 内网隔离、合规审计要求锁定版本的环境 |
选择建议:服务器可直接访问公网选方案 A,步骤最少且始终拿到最新依赖;内网隔离或需要版本锁定选方案 B,离线包与在线方案装出的组件版本完全一致(均为 PostgreSQL 14.24 / Nginx 1.18.0 / OpenJDK 17.0.20.1)。
七、配置说明
本章覆盖两种方案共用的对外发布(Nginx HTTPS)、JVM 内存、端口与 BASE_URL 配置。
7.1 Nginx 反向代理与 HTTPS
Alf.io 内嵌 Jetty 直接服务 HTTP,生产环境建议由 Nginx 终结 HTTPS 再反代到 8080。先生成自签名证书(已有正式证书可跳过生成步骤直接改路径):
mkdir -p /etc/nginx/ssl
openssl req -x509 -nodes -newkey rsa:2048 -days 3650 \
-keyout /etc/nginx/ssl/alfio.key -out /etc/nginx/ssl/alfio.crt \
-subj "/CN=alfio.example.local"
实测输出为密钥生成的随机字符进度点(节选首尾):
..+..........+..+......+.......+..+.+.....+.......+...+.....+.+.....+......+...+.......+............+...+...+......+.........+.....+.+......
...(中间省略随机字符点)...
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
写入反代配置:
cat > /etc/nginx/sites-available/alfio <<'EOF'
server {
listen 8443 ssl;
server_name alfio.example.local;
ssl_certificate /etc/nginx/ssl/alfio.crt;
ssl_certificate_key /etc/nginx/ssl/alfio.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host:8443;
proxy_set_header X-Forwarded-Port 8443;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
EOF
ln -sf /etc/nginx/sites-available/alfio /etc/nginx/sites-enabled/alfio
rm -f /etc/nginx/sites-enabled/default
nginx -t
systemctl enable nginx
systemctl restart nginx
ss -ltn | grep 8443
实测输出:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
LISTEN 0 511 0.0.0.0:8443 0.0.0.0:*
配置逐项说明:
| 配置项 | 取值 | 说明 |
|---|---|---|
listen 8443 ssl | — | 对外 HTTPS 端口;用 8443 而非 443 是本例为避免与已有站点冲突,无冲突可改 443 |
ssl_protocols | TLSv1.2 TLSv1.3 | 禁用不安全的旧协议 |
proxy_pass | http://127.0.0.1:8080 | 转发到本机 Alf.io |
X-Forwarded-Proto/Host/Port | — | 配合应用的 server.forward-headers-strategy=native,让应用生成正确的对外链接 |
rm -f sites-enabled/default | — | 移除默认站点,避免抢占 80 端口 |
登录链路验证(未登录 → 登录页):
curl -sk -o /dev/null -w "%{http_code} %{redirect_url}\n" https://localhost:8443/admin/
curl -sk -o /dev/null -w "%{http_code}\n" https://localhost:8443/authentication
实测输出:
302 https://localhost:8443/authentication
200
7.2 JVM 堆内存调整
堆内存由 systemd 单元的 ExecStart 行控制(4.6 节)。修改后需重载并重启:
sed -i 's/-Xms256m -Xmx512m/-Xms256m -Xmx512m/' /etc/systemd/system/alfio.service
systemctl daemon-reload
systemctl restart alfio
确认实际生效的堆参数:
ps -ef | grep [a]lfio
实测输出:
alfio 9045 1 0 00:39 ? 00:00:47 /usr/bin/java -Xms256m -Xmx512m -jar /opt/alfio/alfio-2.0-M5-2609-boot.jar
若安装了完整 JDK(而非 JRE),还可用 jcmd 查看运行时堆确认:
jcmd $(pgrep -f 'alfio-2.0-M5-2609-boot.jar') VM.flags | grep -oE "(Initial|Max)HeapSize=[0-9]+"
实测输出(256MB = 268435456,512MB = 536870912):
-XX:InitialHeapSize=268435456
-XX:MaxHeapSize=536870912
💡 说明:
-Xms256m -Xmx512m满足官方最低内存要求(同机部署数据库 1GB 内存起)。活动规模大、并发高时可按 1GB/2GB 上调-Xmx,同时等比上调服务器内存。
7.3 监听端口调整
应用默认监听 8080。临时换端口可用环境变量 SERVER_PORT 覆盖:
systemctl stop alfio
su alfio -s /bin/bash -c "cd /opt/alfio && SERVER_PORT=8096 java -Xms256m -Xmx512m -jar alfio-2.0-M5-2609-boot.jar &"
sleep 15
ss -ltn | grep 8096
实测输出:
LISTEN 0 50 *:8096 *:*
验证后停掉手工进程,恢复 systemd 托管:
pkill -f 'SERVER_PORT=8096' ; systemctl start alfio ; systemctl is-active alfio
实测输出:
active
⚠️ 注意:环境变量只对当次进程生效,长期改端口应在
/opt/alfio/application.properties中加server.port=8096后重启服务,不要依赖手工环境变量。
7.4 BASE_URL 与首次基础配置
首次用浏览器打开 https://alfio.example.local:8443/admin/,用 4.7 节记录的初始密码登录,系统会弹出「基础设置」向导(官方文档称 Required options),需要完成:
- 支持语言(Supported languages):勾选前台需要的语言,默认含英文;
- Base URL:填对外访问地址,本例
https://alfio.example.local,与alfio.base-url属性保持一致; - 邮件与地图:可后续再配,向导允许只填必填项。
该向导落库的是系统级 BASE_URL 配置键。实测中,未完成该向导(BASE_URL 为空)时活动创建会被阻断,报 Mandatory configuration key BASE_URL not present(排障与命令行修复见 8.4 节;配置体系全解见《Alf.io 2.0-M5-2609 配置参数详解》)。
数据库层面的备份建议:系统级配置与业务数据都在 PostgreSQL alfio 库内,定期导出即可整体备份:
su postgres -c "pg_dump alfio | gzip > /var/backups/alfio-$(date +%F).sql.gz"
ls -la /var/backups/ | grep alfio
实测输出:
-rw-r--r-- 1 root root 39561 Oct 22 21:26 /var/backups/alfio-2026-10-23.sql.gz
恢复:gunzip -c /var/backups/alfio-2026-10-23.sql.gz | su postgres -c "psql alfio"。
八、常见问题(FAQ)
本章收录实测安装过程中真实出现过的问题,均给出「现象 → 定位 → 解决」。
Q1:启动即失败,日志报 FATAL: password authentication failed for user "alfio",如何解决?
数据库角色的密码与 datasource.password 不匹配。定位方法:
journalctl -u alfio --no-pager | grep -E "PSQLException|Application run failed" | tail -2
实测输出:
Caused by: org.postgresql.util.PSQLException: FATAL: password authentication failed for user "alfio"
2026-10-22T21:26:58.370Z ERROR 7626 --- [Alf.io] [ main] o.s.b.SpringApplication : Application run failed
Caused by: org.postgresql.util.PSQLException: FATAL: password authentication failed for user "alfio"
解决:补设角色密码后重启服务:
su postgres -c "psql -c \"ALTER USER alfio WITH PASSWORD 'q1w2e3r4';\""
systemctl restart alfio
systemctl is-active alfio
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/
实测输出:
ALTER ROLE
active
302
Q2:管理员初始密码弄丢了,又还没登录后台改过,怎么办?
Alf.io 只在「首次初始化」时生成管理员凭据。删除初始化标记与管理员账号,重启后即重新走一遍初始化并生成新密码。先备份数据库(7.4 节命令),再执行:
su postgres -c "psql alfio -c \"DELETE FROM configuration WHERE c_key='INIT_COMPLETED';\""
su postgres -c "psql alfio -c \"DELETE FROM ba_user WHERE username='admin';\""
su postgres -c "psql alfio -c \"DELETE FROM authority WHERE username='admin';\""
systemctl restart alfio
journalctl -u alfio --no-pager | grep -A 2 "generated admin credentials"
实测输出:
DELETE 0
DELETE 1
DELETE 1
active
Oct 23 00:37:05 alfio-b1 java[8798]: 2026-10-23T00:37:05.654Z INFO 8798 --- [Alf.io] [ main] a.c.ConfigurationStatusChecker : This is the first time you're running alf.io
Oct 23 00:37:05 alfio-b1 java[8798]: 2026-10-23T00:37:05.654Z INFO 8798 --- [Alf.io] [ main] a.c.ConfigurationStatusChecker : here the generated admin credentials:
Oct 23 00:37:05 alfio-b1 java[8798]: 2026-10-23T00:37:05.655Z INFO 8798 --- [Alf.io] [ main] a.c.ConfigurationStatusChecker : NNtHfOzVERRyVRB6j
⚠️ 注意:三张表都要删。实测只删
INIT_COMPLETED而不删ba_user里的admin行时,重启会因重复键插入失败,服务起不来:
2026-10-23T00:36:44.569Z WARN 8656 --- [Alf.io] [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.dao.DuplicateKeyException: ...ERROR: duplicate key value violates unique constraint "unique_username"
Oct 23 00:36:44 alfio-b1 java[8656]: Detail: Key (username)=(admin) already exists.
此时把 ba_user、authority 中的 admin 行一并删除(Q2 步骤)再重启即可恢复。
Q3:systemctl mask alfio 报 Failed to mask unit: File /etc/systemd/system/alfio.service already exists.?
mask 的语义是把单元软链到 /dev/null,因此要求原单元文件先移走:
mv /etc/systemd/system/alfio.service /root/alfio.service.bak
systemctl mask alfio
systemctl start alfio
systemctl is-active alfio
实测输出:
Created symlink /etc/systemd/system/alfio.service → /dev/null.
Failed to start alfio.service: Unit alfio.service is masked.
masked
恢复 unmask 并放回文件:
systemctl unmask alfio
mv /root/alfio.service.bak /etc/systemd/system/alfio.service
systemctl daemon-reload
systemctl enable alfio
systemctl start alfio
systemctl is-active alfio
实测输出:
Removed /etc/systemd/system/alfio.service.
Removed /etc/systemd/system/multi-user.target.wants/alfio.service.
Created symlink /etc/systemd/system/multi-user.target.wants/alfio.service → /etc/systemd/system/alfio.service.
enabled
active
Q4:通过 API 创建活动报 Mandatory configuration key BASE_URL not present(500),怎么修?
这是管理后台的「Base URL」配置键未设置(7.4 节向导未完成)。应用日志可见根因:
java.lang.IllegalArgumentException: Mandatory configuration key BASE_URL not present
at alfio.manager.system.ConfigurationManager$MaybeConfiguration.getRequiredValue(ConfigurationManager.java:788) ~[!/:2.0-M5-2609]
修复方式一(推荐):登录管理后台完成基础设置向导。修复方式二(命令行,管理员会话):登录后台页面取 CSRF 令牌后调用配置接口:
# 1) 表单登录拿会话(用户名 admin、密码为首次启动生成的初始密码)
curl -sk -c /tmp/alf-cj.txt -o /tmp/alf-login.html https://localhost:8443/authentication
CSRF=$(grep -oE "name=\"_csrf\" type=\"hidden\" value=\"[^\"]+\"" /tmp/alf-login.html | sed -E "s/.*value=\"([^\"]+)\".*/\1/")
curl -sk -b /tmp/alf-cj.txt -c /tmp/alf-cj.txt -o /dev/null -w "login=%{http_code}\n" \
-d "username=admin" -d "password=NNtHfOzVERRyVRB6j" -d "_csrf=$CSRF" \
https://localhost:8443/authenticate
# 2) 从后台页面元数据取 CSRF 令牌
CSRF=$(curl -sk -b /tmp/alf-cj.txt https://localhost:8443/admin/ | grep -oE "<meta name=\"_csrf\" content=\"[^\"]+\"" | sed -E "s/.*content=\"([^\"]+)\".*/\1/")
# 3) 写入系统级 BASE_URL
curl -sk -b /tmp/alf-cj.txt -X POST -H "X-CSRF-TOKEN: $CSRF" -H "Content-Type: application/json" \
-w "\n[%{http_code}]\n" \
-d "{\"GENERAL\":[{\"key\":\"BASE_URL\",\"value\":\"https://alfio.example.local\"}]}" \
https://localhost:8443/admin/api/configuration/update-bulk
实测输出:
login=302
true
[200]
复核落库结果:
curl -sk -b /tmp/alf-cj.txt https://localhost:8443/admin/api/configuration/load \
| grep -oE '"key": "BASE_URL"[^}]*"value": "[^"]*"'
实测输出:
"key": "BASE_URL", "value": null ... → 修复后 "key": "BASE_URL" ... "value": "https://alfio.example.local"
Q5:直接访问 http://服务器IP:8080/ 为什么 302 跳到了别的地址?
应用会把根路径重定向到配置的对外基础 URL(属性 alfio.base-url),这是预期行为而非故障:
curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}\n" http://localhost:8080/
实测输出:
302 -> https://localhost:8443/
生产环境把 alfio.base-url 与后台 BASE_URL 都设为用户实际访问的域名(含端口),避免出现「跳到一个打不开的地址」。
Q6:想临时起一个免配置的开发实例验证功能,怎么做?
Alf.io 提供 dev 运行档案,用于本地开发调试:
cd /opt/alfio
java -jar alfio-2.0-M5-2609-boot.jar --spring.profiles.active=dev
实测输出(节选):
a.c.SpringBootLauncher : Started SpringBootLauncher in 3.319 seconds (process running for 3.85)
a.c.SpringBootLauncher : profiles: requested , active spring-boot, dev
dev 档案下应用监听 8099(与生产 8080 不同,避免端口冲突):
http 8099 /admin/: 302 -> http://localhost:8099/authentication
⚠️ 注意:dev 档案面向本地调试,不得用于生产;生产一律按第四/五章的 systemd 方式运行。
九、卸载与清理
完全卸载 Alf.io 及其依赖(数据库数据会一并删除,操作前务必确认已有备份):
systemctl disable --now alfio
rm -f /etc/systemd/system/alfio.service
systemctl daemon-reload
rm -rf /opt/alfio
apt-get purge -y postgresql postgresql-contrib nginx nginx-common openjdk-17-jre-headless
rm -f /etc/nginx/sites-enabled/alfio /etc/nginx/sites-available/alfio
rm -rf /etc/nginx/ssl
userdel alfio
实测输出(节选):
Dropping cluster main...
Purging configuration files for openjdk-17-jre-headless:amd64 (17.0.20.1+1-1~22.04) ...
Reading state information...
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
确认 Java 已移除(残留的只读目录属正常,update-alternatives 已无 java 项):
java -version
实测输出:
-bash: /usr/bin/java: No such file or directory
如需彻底清掉数据库数据目录:rm -rf /var/lib/postgresql(确认备份在手后再执行)。
十、参考链接
- 官方网站:https://alf.io/
- 官方文档首页:https://alf.io/docs/
- 官方快速开始(含硬件要求):https://alf.io/docs/getting-started/
- 官方首次基础设置说明(Required options):https://alfio/docs/getting-started/first-setup/basicconfig/
- GitHub 仓库(README 含前置要求):https://github.com/alfio-event/alf.io
- 版本发布页(下载 JAR):https://github.com/alfio-event/alf.io/releases
- 站内组件认知与选型对比:《Alf.io 2.0-M5-2609 介绍与选型指南》