oing9179 的笔记本儿

用 Docker 和 Nginx 搭建 Wekan(Kanban-like todo-list)

Preface

明明有那么多事情还没做,为何偏偏不断的去查看手机上有哪些新消息呢?那就把还没做事都具化出来,用肉眼看到自己还有哪些事情没做,以此来督促自己啊。
今天上午找了一些 Todo-List 软件,然后发现了这个:wekan/wekan - github.com, 已经有 10k+ 个 Star 了。
想试用的话,打开 wekan.github.io 然后点击 “Try on Sandstorm”。
下面将介绍具体的搭建过程。

安装 & 配置 MongoDB

  1. 执行命令 apt-get install mongodb-server
  2. 编辑 /etc/mongodb.conf, 主要修改下面两个参数就够了, 其它的目前用不到.
    • bind_ip=0.0.0.0: 让 MongoDB 监听所有IP, 方便 Docker 容器访问
    • port=27017: 这条配置默认是注释掉的, 取消注释即可
    • 防火墙不要对外开放 27017 端口, 免得被别人乱搞 MongoDB
  3. 执行命令,允许来自 172.0.0.0/8 IP段的连接,docker 容器一般会被分配到这个地址

    1
    ufw allow from 172.0.0.0/8
  4. 执行命令重新启动 MongoDB 使上面修改过的设置生效: systemctl restart mongodb.service

安装 & 配置 Wekan Docker Image

  1. 安装 / 更新 docker-compose, 参考 这里
  2. 创建文件 docker-compose.yml, 内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    version: "3"
    services:
    wekan-app:
    image: wekanteam/wekan:latest
    # 稍后要借助下面这个 command 进入 docker 容器
    # command: "/bin/cat /dev/stdout > /dev/null"
    container_name: wekan-app
    ports:
    # 把容器内的 80 端口映射到主机的 127.0.0.1:18081
    - "127.0.0.1:18081:80/tcp"
    environment:
    MONGO_URL: "mongodb://host-ip:27017/wekan"
    ROOT_URL: "https://todo.example.com"
  3. docker-compose.yml 的同一目录下运行命令 docker-compose up -d

  4. 上一条命令运行完成后再运行 docker ps -a 如果看到 wekan-app 这个容器的状态是 Exited, 说明上面的 docker-compose.yml 里的 MONGO_URL 是有问题的, 因为现在还不知道 docker 容器被分配的 IP 地址, 也就没法给 host-ip 一个正确的值
  5. 为了让 docker 容器能保持运行 好让我进入容器执行一些命令来获知容器的 IP 地址, 把 docker-compose.yml 里面的 # command 那行取消注释, 然后再运行 docker-compose up -d, 现在这个容器就处于运行中的状态了
  6. 运行命令 docker exec -it wekan-app /bin/bash -il 获得容器内的 interactive shell
  7. 运行命令获取分配给容器的 IP 地址: ip route show default, 输出内容大概是这样的:

    1
    2
    default via 172.17.0.1 dev eth0 
    172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2

    那段 default via 172.17.0.1172.17.0.1 就是这个 docker 容器的网关(Gateway)了, 用它替换掉 docker-compose.yml 里的 host-ip, 然后再运行 docker-compose up -d

  8. 执行命令 curl -i http://127.0.0.1:18081, 如果有HTML输出说明这个 docker 容器已经运行起来了.

至此,Wekan 的 Docker 容器就搭建好了。

配置 Nginx & SSL 证书

申请 SSL 证书

  1. 安装 letsencrypt apt-get install letsencrypt
  2. 创建静态网站的目录 mkdir --parents /var/www/todo.example.com,稍后 Let’s Encrypt 会用到它
  3. 创建文件 /etc/nginx/sites-available/todo.example.com 并编辑

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    server {
    # 域名
    server_name todo.example.com;
    # 监听 IPv4/6 80 端口
    listen 80;
    listen [::]:80;
    # 静态网站根目录
    root /var/www/todo.example.com;
    # 提供静态文件服务
    location / {
    try_files $uri $uri/ =404;
    }
    }
  4. 创建软链接

    1
    ln -s /etc/nginx/sites-available/todo.example.com /etc/nginx/sites-enabled/todo.example.com
  5. 重启 Nginx systemctl restart nginx

  6. 执行命令来生成 SSL 证书
    1
    letsencrypt certonly --webroot -w /var/www/todo.example.com --domain "todo.example.com"

至此,SSL 证书已经申请好了,接下来将配置 Nginx 使用刚刚申请的 SSL 证书。

配置 SSL 证书

  1. 参考 Install Wekan Docker in production 编辑配置文件 /etc/nginx/sites-available/todo.example.com

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    upstream websocket {
    server 127.0.0.1:18081;
    }
    map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
    }
    server {
    server_name todo.example.com;
    listen 443;
    listen [::]:443;
    access_log /var/log/nginx/todo.example.com_access.log;

    ssl off;
    ssl_certificate /etc/letsencrypt/live/todo.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/todo.example.com/privkey.pem;
    # index index.html index.php;
    location / {
    proxy_read_timeout 300;
    proxy_connect_timeout 300;
    proxy_redirect off;
    proxy_pass http://127.0.0.1:18081;

    proxy_set_header Host $http_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;
    }
    location ~ websocket$ {
    proxy_pass http://websocket;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    }
    }
  2. 验证配置文件语法 并 重启 Nginx

    1
    2
    nginx -t
    systemctl restart nginx
  3. 用网页浏览器打开地址 https://todo.example.com 查看效果

Q & A

  1. Q:在 Wekan 里点击某个卡片后,网页会重新载入 并打开刚才点击的卡片.
    A:docker-compose.yml 里的 ROOT_URL 必须与实际访问这个站点用的URL完全一致。5
    比如 docker-compose.yml 里有 ROOT_URL: "http://todo.example.com",用浏览器访问的地址是 https://todo.example.com,这种情况下 点击卡片就会导致页面重新载入。解决方法就是把 ROOT_URL: "http://todo.example.com" 改成 ROOT_URL: "https://todo.example.com",然后执行命令 docker-compse up -d 使更改生效。

结语

至此,Wekan 的搭建过程就结束了,首次登录到页面需要自己注册一个帐号,第一个注册的帐号将成为管理员帐号。
默认情况下,Wekan 的帐号注册是公开的,可以在管理员设置页面把公开注册关掉。

更新历史

19 Aug 2017: 首次发布
24 Aug 2017:

  • 修复:Wekan 内点击卡片导致页面重新载入后才打开卡片5
  • 改进:参考 Wekan 官方文档来编写 Nginx 配置文件

References

  1. wekan/wekan - github.com
  2. Wekan - open-source kanban - wekan.github.io
  3. docker-compose Releases - github.com
  4. Install Wekan Docker in production - github.com/wekan/wekan
  5. Docker installation; when clicking cards page always reloads #741 - github.com/wekan/wekan/issues