Skip to content
LiKe's Blog
Go back

做你自己的项目经理 - Vikunja 部署记录

Edit page

从外企辞职后,我就一直在寻找一个类似Jira和Azure Dev Ops的项目管理工具,为了避免重复造轮子,我在Github找到了这个项目。实现效果如下: 可以添加不同项目和子项目

在每个项目和子项目里,都可以添加具体的任务

也可以自己定义上方的任务点标识

切换到甘特图后,可以清楚看到每个任务的时间线和关键节点

本文记录如何在 Ubuntu 服务器上使用 Docker 部署 Vikunja,并通过 Caddy 提供 HTTPS 访问。方案采用单容器 Vikunja、SQLite 数据库和反向代理,适合个人使用、小团队使用,资源占用低,迁移和备份也比较简单。

1. 部署目标

完成部署后,可以通过浏览器访问:

https://todo.example.com

实现效果:

  1. 使用域名访问 Vikunja。
  2. 支持 HTTPS。
  3. Vikunja 使用 Docker 隔离运行。
  4. 数据使用 SQLite 文件保存。
  5. Vikunja 服务只监听本机地址,不直接暴露业务端口。
  6. 支持后续配置邮件提醒。
  7. 支持备份、恢复和升级。

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 用来完成两件事:

  1. https://todo.example.com 转发到 http://127.0.0.1:3456
  2. 自动申请和续期 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 证书申请失败

检查:

  1. 域名是否解析到服务器公网 IP。
  2. 80 和 443 是否放行。
  3. Caddy 是否正常运行。
  4. 是否有其他程序占用 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 就可以作为自托管任务管理系统使用。


Edit page
Share this post: