Vikunja
Office Web · Source · Docker Image · Documentation
Vikunja 是一款开源的待办事项(To-do)管理应用,支持任务列表、甘特图、看板、表格等多种视图,可自托管,提供 Web、桌面与移动端客户端。
部署教程
Vikunja 默认使用 SQLite,单容器即可运行,无需额外的数据库服务。
1. 配置 .env
# CUSTOM
TZ=Asia/Shanghai
SERV_PORT=3456
# Vikunja
# 公开访问地址(含端口,用于邮件链接、OAuth 回调等)
VIKUNJA_SERVICE_PUBLICURL=http://localhost:3456
# JWT 认证密钥,必须修改,使用 `openssl rand -hex 32` 生成
VIKUNJA_SERVICE_JWT_SECRET=<VIKUNJA_SERVICE_JWT_SECRET>
# SQLite 数据库文件路径(存入挂载目录随 ./data 持久化)
VIKUNJA_DATABASE_PATH=/app/vikunja/files/vikunja.db若通过
http://<ip>:3456等非标准端口访问,VIKUNJA_SERVICE_PUBLICURL必须带上端口,否则注册账号时会报 "unauthorized" 错误。
2. 启动
docker compose up -d访问 http://<host>:3456 即可打开页面,首次使用需注册账号。
3. 权限说明
Vikunja 容器以用户 1000 运行,若上传附件或修改项目背景报 permission denied,需先修正数据目录属主:
mkdir -p ./data
chown -R 1000 ./data注意:镜像基于
scratch,容器内没有 shell(docker exec -it vikunja sh不可用),也不支持PUID/PGID环境变量;如需以其他用户运行,请使用 compose 的user:指令。
使用 SQLite(默认)
默认方式,单容器即可运行,无需额外的数据库服务。上方「部署教程」即基于 SQLite,完整配置如下:
.env 配置:
# CUSTOM
TZ=Asia/Shanghai
SERV_PORT=3456
# Vikunja
# 公开访问地址(含端口,用于邮件链接、OAuth 回调等)
VIKUNJA_SERVICE_PUBLICURL=http://localhost:3456
# JWT 认证密钥,必须修改,使用 `openssl rand -hex 32` 生成
VIKUNJA_SERVICE_JWT_SECRET=<VIKUNJA_SERVICE_JWT_SECRET>
# SQLite 数据库文件路径(存入挂载目录随 ./data 持久化)
VIKUNJA_DATABASE_PATH=/app/vikunja/files/vikunja.dbcompose.yaml 配置:
---
# https://hub.docker.com/r/vikunja/vikunja
services:
vikunja:
container_name: vikunja
env_file:
- path: ./.env
required: false
image: vikunja/vikunja:latest
ports:
- ${SERV_PORT:-3456}:3456
volumes:
- ./data:/app/vikunja/files
restart: unless-stopped注意:不可将宿主目录挂载到
/app/vikunja—— 可执行文件位于/app/vikunja/vikunja,覆盖该目录会导致容器报exec: "/app/vikunja/vikunja": no such file or directory无法启动。官方镜像预置了
VIKUNJA_DATABASE_PATH=/db/vikunja.db(数据库默认存放在/db),.env中的VIKUNJA_DATABASE_PATH=/app/vikunja/files/vikunja.db是对该预置值的显式覆盖,使数据库文件与上传附件统一存放在./data挂载目录中。若保持官方默认,也可将挂载改为./data:/db。
SQLite 数据库文件(vikunja.db)与上传附件均存放在 ./data 目录中,备份方式见数据备份。
使用 PostgreSQL
如需使用 PostgreSQL,在 .env 中追加数据库配置:
# Database (PostgreSQL)
VIKUNJA_DATABASE_TYPE=postgres
VIKUNJA_DATABASE_HOST=db
VIKUNJA_DATABASE_USER=vikunja
VIKUNJA_DATABASE_PASSWORD=<VIKUNJA_DATABASE_PASSWORD>
VIKUNJA_DATABASE_DATABASE=vikunja并在 compose.yaml 中增加 db 服务:
---
# https://hub.docker.com/r/vikunja/vikunja
services:
vikunja:
container_name: vikunja
env_file:
- path: ./.env
required: false
image: vikunja/vikunja:latest
# ports:
# - ${SERV_PORT:-3456}:3456
volumes:
- ./data/files:/app/vikunja/files
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:18
environment:
POSTGRES_USER: ${VIKUNJA_DATABASE_USER}
POSTGRES_PASSWORD: ${VIKUNJA_DATABASE_PASSWORD}
POSTGRES_DB: ${VIKUNJA_DATABASE_DATABASE}
volumes:
- ./data/db:/var/lib/postgresql
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER"]
interval: 2s
start_period: 30s首次启动时数据库容器就绪较慢,Vikunja 可能连接失败退出,
restart: unless-stopped会自动重启并恢复。
使用 MySQL / MariaDB
如需使用 MySQL,在 .env 中追加数据库配置:
# Database (MySQL)
VIKUNJA_DATABASE_TYPE=mysql
VIKUNJA_DATABASE_HOST=db
VIKUNJA_DATABASE_USER=vikunja
VIKUNJA_DATABASE_PASSWORD=<VIKUNJA_DATABASE_PASSWORD>
VIKUNJA_DATABASE_DATABASE=vikunja并在 compose.yaml 中增加 db 服务:
---
# https://hub.docker.com/r/vikunja/vikunja
services:
vikunja:
container_name: vikunja
env_file:
- path: ./.env
required: false
image: vikunja/vikunja:latest
# ports:
# - ${SERV_PORT:-3456}:3456
volumes:
- ./data/files:/app/vikunja/files
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: mariadb:11
environment:
MYSQL_ROOT_PASSWORD: ${VIKUNJA_DATABASE_PASSWORD}
MYSQL_USER: ${VIKUNJA_DATABASE_USER}
MYSQL_PASSWORD: ${VIKUNJA_DATABASE_PASSWORD}
MYSQL_DATABASE: ${VIKUNJA_DATABASE_DATABASE}
volumes:
- ./data/db:/var/lib/mysql
restart: unless-stopped
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 2s
start_period: 30s使用 MySQL 时若报
Migration failed: commands out of sync,需停止容器后删除./data/db目录再重新启动。
数据备份
Vikunja 中删除项目是永久且不可恢复的,没有回收站,请确保有可靠的备份策略。
需备份两部分:数据库与附件文件。
SQLite:直接复制数据库文件(./data/vikunja.db)即可。
PostgreSQL:
# 备份
docker compose exec db pg_dump -U vikunja vikunja > vikunja-backup.sql
# 恢复
docker compose exec -T db psql -U vikunja vikunja < vikunja-backup.sqlMySQL / MariaDB:
# 备份
docker compose exec db sh -c 'exec mariadb-dump -uvikunja -p"$MYSQL_PASSWORD" vikunja' > vikunja-backup.sql
# 恢复
docker compose exec -T db sh -c 'exec mariadb -uvikunja -p"$MYSQL_PASSWORD" vikunja' < vikunja-backup.sql附件文件:直接复制 ./data/files/ 目录(files.basepath 相对于 service.rootpath,即容器内 /app/vikunja/files)。
也可配合项目根目录的 backup.sh 模板,将 ./data 打包为 .tar.xz 归档。
反向代理(NGINX)
假设 Vikunja 运行在本机 3456 端口,server_name 按实际域名调整:
# WebSocket 升级所需,映射 $connection_upgrade
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name vikunja.example.com;
location / {
proxy_pass http://127.0.0.1:3456;
# 与 Vikunja 最大上传大小保持一致,调大上传限制时需同步修改
client_max_body_size 20M;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持(/api/v2/ws),缺少会导致实时更新连接失败
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
}
}反向代理后 Vikunja 默认记录到的是代理的地址,若需要让日志与限流识别真实客户端 IP,在 .env 中追加:
# 从 X-Forwarded-For 头提取客户端 IP
VIKUNJA_SERVICE_IPEXTRACTIONMETHOD=xff
# 仅信任代理来源地址,范围越小越安全,不要写成 10.0.0.0/8 这类宽网段
VIKUNJA_SERVICE_TRUSTEDPROXIES=127.0.0.1/32