从外企辞职后,我就一直在寻找一个类似Jira和Azure Dev Ops的项目管理工具,为了避免重复造轮子,我在Github找到了这个项目。实现效果如下: 可以添加不同项目和子项目
在每个项目和子项目里,都可以添加具体的任务
也可以自己定义上方的任务点标识
切换到甘特图后,可以清楚看到每个任务的时间线和关键节点
本文记录如何在 Ubuntu 服务器上使用 Docker 部署 Vikunja,并通过 Caddy 提供 HTTPS 访问。方案采用单容器 Vikunja、SQLite 数据库和反向代理,适合个人使用、小团队使用,资源占用低,迁移和备份也比较简单。
1. 部署目标
完成部署后,可以通过浏览器访问:
https://todo.example.com
实现效果:
- 使用域名访问 Vikunja。
- 支持 HTTPS。
- Vikunja 使用 Docker 隔离运行。
- 数据使用 SQLite 文件保存。
- Vikunja 服务只监听本机地址,不直接暴露业务端口。
- 支持后续配置邮件提醒。
- 支持备份、恢复和升级。
2. 推荐架构
flowchart TD
A[用户浏览器] -->|HTTPS 443| B[Caddy 反向代理]
B -->|HTTP 127.0.0.1:3456| C[Vikunja Docker 容器]
C --> D[SQLite 数据库文件]
C --> E[附件目录]
服务关系:
用户设备
↓
https://todo.example.com
↓
Caddy
↓
http://127.0.0.1:3456
↓
Vikunja
↓
SQLite 数据库文件
3. 环境准备
推荐环境:
系统:Ubuntu 22.04 / Ubuntu 24.04
CPU:1 核以上
内存:1GB 以上
磁盘:10GB 以上
域名:一个可解析到服务器的域名或子域名
本文使用以下占位符:
<SERVER_IP> 服务器公网 IP
todo.example.com Vikunja 访问域名
<YOUR_EMAIL> 邮箱地址
<APP_PASSWORD> SMTP 应用专用密码
请在实际部署时替换为自己的信息。
4. 域名解析
在 DNS 服务商后台添加一条 A 记录:
记录类型:A
主机记录:todo
记录值:<SERVER_IP>
TTL:默认或 10 分钟
最终访问域名为:
todo.example.com
解析生效后,可以在本地或服务器执行:
ping todo.example.com
如果解析到服务器公网 IP,说明 DNS 配置正常。
5. 安装 Docker
登录服务器:
ssh ubuntu@<SERVER_IP>
如果使用 root 用户:
ssh root@<SERVER_IP>
安装 Docker:
sudo apt update
sudo apt install -y ca-certificates curl
curl -fsSL https://get.docker.com | sudo sh
sudo systemctl enable docker
sudo systemctl start docker
检查 Docker:
sudo docker version
sudo docker compose version
测试 Docker:
sudo docker run hello-world
如果能看到测试容器正常运行,说明 Docker 安装完成。
6. 部署 Vikunja
6.1 创建目录
sudo mkdir -p /opt/vikunja
cd /opt/vikunja
sudo mkdir -p files db
sudo chown -R 1000:1000 files db
目录说明:
/opt/vikunja/files Vikunja 附件目录
/opt/vikunja/db SQLite 数据库目录
6.2 创建 docker-compose.yml
cd /opt/vikunja
sudo nano docker-compose.yml
填入以下内容:
services:
vikunja:
image: vikunja/vikunja:latest
container_name: vikunja
restart: unless-stopped
ports:
- "127.0.0.1:3456:3456"
environment:
VIKUNJA_SERVICE_PUBLICURL: https://todo.example.com/
VIKUNJA_SERVICE_ENABLEREGISTRATION: "true"
VIKUNJA_DATABASE_TYPE: sqlite
VIKUNJA_DATABASE_PATH: /db/vikunja.db
volumes:
- ./files:/app/vikunja/files
- ./db:/db
mem_limit: 256m
cpus: 0.5
保存方式:
Ctrl + O
回车
Ctrl + X
配置说明:
VIKUNJA_SERVICE_PUBLICURL 对外访问地址
VIKUNJA_SERVICE_ENABLEREGISTRATION 是否允许注册
VIKUNJA_DATABASE_TYPE 数据库类型
VIKUNJA_DATABASE_PATH SQLite 数据库路径
mem_limit 容器内存限制
cpus 容器 CPU 限制
这里把端口绑定到:
127.0.0.1:3456
表示 Vikunja 只允许服务器本机访问。公网访问会通过 Caddy 转发,不需要直接暴露 3456 端口。
6.3 启动 Vikunja
cd /opt/vikunja
sudo docker compose up -d
检查容器:
sudo docker ps
查看日志:
sudo docker logs -f vikunja
本机测试:
curl -I http://127.0.0.1:3456
正常返回示例:
HTTP/1.1 200 OK
Server: Vikunja
Content-Type: text/html; charset=utf-8
出现 200 OK,说明 Vikunja 已经在服务器本地运行。
7. 配置 Caddy 反向代理
Caddy 用来完成两件事:
- 把
https://todo.example.com转发到http://127.0.0.1:3456。 - 自动申请和续期 HTTPS 证书。
7.1 开放防火墙端口
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo ufw status
只需要开放:
22 SSH
80 HTTP,证书申请和跳转使用
443 HTTPS
不要开放 3456。
7.2 创建 Caddy 目录
sudo mkdir -p /opt/caddy
cd /opt/caddy
7.3 创建 Caddy docker-compose.yml
sudo nano docker-compose.yml
填入:
services:
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
network_mode: host
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./data:/data
- ./config:/config
7.4 创建 Caddyfile
sudo nano Caddyfile
填入:
todo.example.com {
reverse_proxy 127.0.0.1:3456
}
7.5 启动 Caddy
cd /opt/caddy
sudo docker compose up -d
查看容器:
sudo docker ps
查看日志:
sudo docker logs -f caddy
日志没有明显错误后,打开:
https://todo.example.com
如果能看到 Vikunja 登录页,说明部署完成。
8. 初始化账号
第一次打开 Vikunja,需要创建账户。
访问:
https://todo.example.com
点击创建账户,填写用户名、邮箱和密码。
创建完成后,建议马上关闭公开注册。
cd /opt/vikunja
sudo nano docker-compose.yml
把:
VIKUNJA_SERVICE_ENABLEREGISTRATION: "true"
改成:
VIKUNJA_SERVICE_ENABLEREGISTRATION: "false"
重启 Vikunja:
cd /opt/vikunja
sudo docker compose up -d
之后已有账号可以登录,新用户不能继续注册。
9. 资源限制
当前配置限制为:
mem_limit: 256m
cpus: 0.5
查看资源占用:
sudo docker stats
如果页面响应慢,可以适当提高限制:
mem_limit: 384m
cpus: 1
修改后重启:
cd /opt/vikunja
sudo docker compose up -d
10. 配置邮件提醒
Vikunja 支持任务提醒邮件和每日摘要邮件。界面里开启邮件通知前,服务器必须先配置 SMTP。
10.1 Gmail SMTP 示例
如果使用 Gmail,需要先开启 Google 两步验证,然后生成 App Password。
Google 账号安全页:
https://myaccount.google.com/security
应用专用密码页面:
https://myaccount.google.com/apppasswords
创建一个应用密码,例如命名为:
Vikunja
得到 16 位密码后保存备用。
10.2 修改 Vikunja 配置
cd /opt/vikunja
sudo nano docker-compose.yml
在 environment: 下加入:
VIKUNJA_MAILER_ENABLED: "true"
VIKUNJA_MAILER_HOST: smtp.gmail.com
VIKUNJA_MAILER_PORT: "465"
VIKUNJA_MAILER_AUTHTYPE: login
VIKUNJA_MAILER_USERNAME: <YOUR_EMAIL>
VIKUNJA_MAILER_PASSWORD: <APP_PASSWORD>
VIKUNJA_MAILER_FROMEMAIL: <YOUR_EMAIL>
VIKUNJA_MAILER_FORCESSL: "true"
完整示例:
services:
vikunja:
image: vikunja/vikunja:latest
container_name: vikunja
restart: unless-stopped
ports:
- "127.0.0.1:3456:3456"
environment:
VIKUNJA_SERVICE_PUBLICURL: https://todo.example.com/
VIKUNJA_SERVICE_ENABLEREGISTRATION: "false"
VIKUNJA_DATABASE_TYPE: sqlite
VIKUNJA_DATABASE_PATH: /db/vikunja.db
VIKUNJA_MAILER_ENABLED: "true"
VIKUNJA_MAILER_HOST: smtp.gmail.com
VIKUNJA_MAILER_PORT: "465"
VIKUNJA_MAILER_AUTHTYPE: login
VIKUNJA_MAILER_USERNAME: <YOUR_EMAIL>
VIKUNJA_MAILER_PASSWORD: <APP_PASSWORD>
VIKUNJA_MAILER_FROMEMAIL: <YOUR_EMAIL>
VIKUNJA_MAILER_FORCESSL: "true"
volumes:
- ./files:/app/vikunja/files
- ./db:/db
mem_limit: 256m
cpus: 0.5
重启:
cd /opt/vikunja
sudo docker compose up -d
10.3 测试邮件
先尝试:
sudo docker exec -it vikunja /app/vikunja/vikunja testmail <YOUR_EMAIL>
如果提示缓存权限问题,可以使用:
sudo docker exec -e XDG_CACHE_HOME=/tmp -it vikunja /app/vikunja/vikunja testmail <YOUR_EMAIL>
如果不确定可执行文件路径,可以查找:
sudo docker exec -it vikunja sh -lc 'find / -name vikunja -type f 2>/dev/null'
常见输出:
/app/vikunja/vikunja
测试成功后,检查收件箱和垃圾箱。
11. 日常维护命令
查看容器:
sudo docker ps
查看 Vikunja 日志:
sudo docker logs -f vikunja
查看 Caddy 日志:
sudo docker logs -f caddy
查看端口:
sudo ss -tulpn | grep -E ':80|:443|:3456'
查看资源占用:
sudo docker stats
重启 Vikunja:
cd /opt/vikunja
sudo docker compose up -d
重启 Caddy:
cd /opt/caddy
sudo docker compose up -d
12. 备份
关键数据:
/opt/vikunja/db
/opt/vikunja/files
/opt/vikunja/docker-compose.yml
手动备份:
cd /opt
sudo tar -czf vikunja-backup-$(date +%F).tar.gz vikunja
查看备份文件:
ls -lh /opt/vikunja-backup-*.tar.gz
建议把备份文件下载到本地,避免服务器故障时数据丢失。
13. 恢复
把备份文件上传到服务器 /opt 目录,然后执行:
cd /opt
sudo tar -xzf vikunja-backup-xxxx-xx-xx.tar.gz
cd /opt/vikunja
sudo docker compose up -d
检查服务:
sudo docker ps
curl -I http://127.0.0.1:3456
14. 升级
升级前先备份:
cd /opt
sudo tar -czf vikunja-backup-before-upgrade-$(date +%F).tar.gz vikunja
拉取新镜像并重启:
cd /opt/vikunja
sudo docker compose pull
sudo docker compose up -d
sudo docker image prune -f
查看日志确认启动正常:
sudo docker logs -f vikunja
15. 常见问题
15.1 域名打不开
检查 DNS:
ping todo.example.com
检查 Caddy:
sudo docker logs -f caddy
检查端口:
sudo ss -tulpn | grep -E ':80|:443'
检查防火墙:
sudo ufw status
15.2 本机能访问,域名不能访问
先测试本机:
curl -I http://127.0.0.1:3456
如果返回 200 OK,说明 Vikunja 正常。问题通常在 DNS、Caddy 或防火墙。
15.3 HTTPS 证书申请失败
检查:
- 域名是否解析到服务器公网 IP。
- 80 和 443 是否放行。
- Caddy 是否正常运行。
- 是否有其他程序占用 80 或 443。
命令:
sudo ss -tulpn | grep -E ':80|:443'
sudo docker logs -f caddy
15.4 3456 端口外部访问不了
这是正常现象。
当前配置:
ports:
- "127.0.0.1:3456:3456"
表示 3456 只允许服务器本机访问。外部访问必须走:
https://todo.example.com
15.5 邮件测试提示 executable file not found
错误示例:
exec: "vikunja": executable file not found in $PATH
解决方式:
sudo docker exec -it vikunja /app/vikunja/vikunja testmail <YOUR_EMAIL>
15.6 忘记关闭注册
编辑:
cd /opt/vikunja
sudo nano docker-compose.yml
确认:
VIKUNJA_SERVICE_ENABLEREGISTRATION: "false"
重启:
sudo docker compose up -d
16. 安全检查清单
部署完成后,建议检查:
[ ] 域名已使用 HTTPS
[ ] Vikunja 只监听 127.0.0.1:3456
[ ] 服务器未开放 3456 端口
[ ] 公开注册已关闭
[ ] Docker 容器已设置 restart: unless-stopped
[ ] 已配置备份方式
[ ] 邮件提醒使用应用专用密码
[ ] 防火墙只开放 22、80、443
17. 最终目录结构
/opt
├── vikunja
│ ├── docker-compose.yml
│ ├── db
│ │ └── vikunja.db
│ └── files
└── caddy
├── docker-compose.yml
├── Caddyfile
├── data
└── config
18. 最终运行结构
flowchart LR
A[DNS A 记录] --> B[todo.example.com]
B --> C[Caddy 80/443]
C --> D[Vikunja 127.0.0.1:3456]
D --> E[SQLite /opt/vikunja/db]
D --> F[Files /opt/vikunja/files]
最终访问地址:
https://todo.example.com
部署完成后,Vikunja 就可以作为自托管任务管理系统使用。