Hotaru's Notebook

用 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 容器一般会被分配到这个地址
    ufw allow from 172.0.0.0/8
    
  4. 执行命令重新启动 MongoDB 使上面修改过的设置生效: systemctl restart mongodb.service

安装 & 配置 Wekan Docker Image

  1. 安装 / 更新 docker-compose, 参考 这里
  2. 创建文件 docker-compose.yml, 内容如下
    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, 输出内容大概是这样的:
    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 并编辑
    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. 创建软链接
    ln -s /etc/nginx/sites-available/todo.example.com /etc/nginx/sites-enabled/todo.example.com
    
  5. 重启 Nginx systemctl restart nginx
  6. 执行命令来生成 SSL 证书
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
    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
    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:

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

#Linux #Docker #Nginx #Wekan #Todo-list