How to Install Wekan (Open Source Kanban) on Ubuntu 16.04

Published on: Mon, Jan 8, 2018 at 1:35 pm EST
This article is a port of "How to Install Wekan (Open Source Kanban) on CentOS 7" for Ubuntu 16.04.

Wekan is a kanban board built with the Meteor JavaScript framework. It is considered an open source and self-hosted alternative to Trello, providing nearly the same features. It allows you to create card based "to-do" management lists. Wekan is very helpful to increase productivity when working in a collaborative environment. Wekan has a fully responsive web interface, and it is actively translated in many languages.

Prerequisites

  • A Vultr Ubuntu 16.04 server instance.
  • A sudo user.

For this tutorial, we will use wekan.example.com as the domain name pointed towards the Vultr instance. Please make sure to replace all occurrences of the example domain name with the actual one.

Update your base system using the guide How to Update Ubuntu 16.04. Once your system has been updated, proceed to install the dependencies.

Install Node.js

Wekan only supports Node.js LTS version 4.8. To install Node.js, we will use the node version manager. Install nvm by running the installer script.

wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.4/install.sh | bash

To immediately start using nvm, run this.

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

If nvm has installed successfully, then you should be able to check its version.

user@vultr:~$ nvm --version
0.33.4

Install Node.js.

nvm install v4.8

Set the default version of Node.js.

nvm use node

If Node.js has installed successfully, then you should be able to check its version.

node -v

You will see this output.

user@vultr:~$ node -v
v4.8.4

NVM installs Node.js for the current user only. For Node.js to be accessible globally, run this.

n=$(which node);n=${n%/bin/node}; chmod -R 755 $n/bin/*; sudo cp -r $n/{bin,lib,share} /usr

Node.js is now available as /usr/bin/node.

user@vultr:~$ sudo which node
/usr/bin/node

Install MongoDB

MongoDB is a free and open source NoSQL database server. Unlike traditional databases which use tables to organize their data, MongoDB is document-oriented and uses JSON-like documents without schemas. Wekan uses MongoDB to store its data.

Wekan is compatible only with MongoDB version 3.2. Create a new repository file.

echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list

Import the MongoDB public GPG key and update the package list.

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
sudo apt update

Install MongoDB.

sudo apt install -y mongodb-org

Start MongoDB and enable it to start automatically.

sudo systemctl start mongod
sudo systemctl enable mongod

Securing MongoDB instance

By default, there is no authentication enabled in a MongoDB server. Any user that has access to the terminal of the server will have full privileges on the MongoDB installation. To secure the database server and restrict the access of an unprivileged user, we will need to set up authentication on the server.

MongoDB provides a mongo shell which is used to run queries on MongoDB. Switch to the mongo shell.

mongo

Create a new MongoDB user with root privileges. You can use any username of your choice. Please make sure to replace the password.

db.createUser(
  {
    user: "admin",
    pwd: "StrongAdminPassword",
    roles: [ { role: "root", db: "admin" } ]
  }
)

You should see following output.

user@vultr:~$ mongo
MongoDB shell version: 3.2.17
connecting to: test
Welcome to the MongoDB shell.

...

2017-09-30T18:11:40.274+0000 I CONTROL  [initandlisten]
> db.createUser(
...   {
...     user: "admin",
...     pwd: "StrongAdminPassword",
...     roles: [ { role: "root", db: "admin" } ]
...   }
... )
Successfully added user: {
        "user" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}

Exit the MongoDB command interface to the Linux terminal by pressing "Ctrl+C".

Edit the MongoDB configuration file.

sudo nano /etc/mongod.conf

Append the following line at the end of the file.

security:
 authorization: enabled

Restart MongoDB so that the configuration change can take effect.

sudo systemctl restart mongod

Now that security has been enabled, you can test if it is working by switching to the mongo shell again using the mongo command. This time, if you run a query, such as show dbs to show the list of databases, you will see a message reporting failed authorization. Exit to the sudo user again after testing the log-in as the new user you just created.

Log in as the administrator user you just created.

mongo -u admin -p

Provide the password of the user for a successful login. Create a new user for the wekan database which will be used to store Wekan data.

use wekan
db.createUser(
    {
      user: "wekan",
      pwd: "StrongPassword",
      roles: ["readWrite"]
    }
 ) 

Make sure to replace the StrongPassword with a strong password. You will see the following output.

user@vultr:~$ mongo -u admin -p
MongoDB shell version: 3.2.17
Enter password:
connecting to: test

...

2017-09-30T18:13:26.007+0000 I CONTROL  [initandlisten]
>
> use wekan
switched to db wekan
> db.createUser(
...     {
...       user: "wekan",
...       pwd: "StrongPassword",
...       roles: ["readWrite"]
...     }
...  )
Successfully added user: { "user" : "wekan", "roles" : [ "readWrite" ] }

Install Wekan

Check for the latest link to the Wekan release on Github as new releases are very frequent. Download the latest version of Wekan from Github replacing the link to the installer package.

cd ~
wget https://github.com/wekan/wekan/releases/download/v0.44/wekan-0.44.tar.gz

Extract the downloaded archive into a new directory named wekan.

mkdir wekan
tar xzvf wekan-*.tar.gz -C wekan

Install the Node.js dependencies.

cd wekan/bundle/programs/server && npm install

The Wekan server reads configurations from the environment variables. Run the following commands to set the configurations as environment variables.

export MONGO_URL='mongodb://wekan:StrongPassword@127.0.0.1:27017/wekan?authSource=wekan'
export ROOT_URL='http://wekan.example.com'
export MAIL_URL='smtp://user:pass@mail.example.com:25/'
export MAIL_FROM='wekan@example.com'
export PORT=4000

Make sure to replace the MongoDB password for the wekan user you have created. Also, update the mail URL according to your SMTP server settings. If you do not have an email server ready, you can always change this configuration later.

To immediately start the application.

cd ~/wekan/bundle
node main.js

You can now access the application by going to http://wekan.example.com:4000. You will see the interface to log-in into the Wekan kanban board.

For production use, it is recommended to set up a reverse proxy to serve the application on the standard HTTP port and a systemd service to manage the application process. In this tutorial, we will use the Nginx web server as a reverse proxy, secured with a Let's Encrypt free SSL.

Setting up the Nginx Reverse Proxy

Add the Certbot PPA repository to the system.

sudo add-apt-repository ppa:certbot/certbot
sudo apt update

Install Nginx and Certbot, which is the client application for Let's Encrypt CA.

sudo apt -y install certbot nginx

Note: The domain name which you are using to obtain the certificates from the Let's Encrypt CA must be pointed towards the server. The client verifies the domain authority before issuing the certificates.

Generate the SSL certificates.

sudo certbot certonly --standalone -d wekan.example.com

The generated certificates are likely to be stored in the /etc/letsencrypt/live/wekan.example.com/ directory. The SSL certificate will be stored as fullchain.pem, and private key will be stored as privkey.pem.

Let's Encrypt certificates expire in 90 days, so it is recommended to set up auto-renewal of the certificates using Cronjob. Cron is a system service which is used to run periodic tasks.

Open the cron job file.

sudo crontab -e

Add the following line at the end of the file.

30 5 * * * /usr/bin/certbot renew --quiet

The above cron job will run every day at 5:30 AM. If the certificates are due for expiration, it will automatically renew them.

Create a new virtual host.

sudo nano /etc/nginx/sites-available/wekan.example.com.conf

Populate the file with the following.

upstream wekan {
        server 127.0.0.1:4000;
}
server {
        listen  80;
        listen [::]:80;
        server_name  wekan.example.com;

        location / {
                if ($ssl_protocol = "") {
                        rewrite     ^   https://$server_name$request_uri? permanent;
                }
        }
}

server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name wekan.example.com;

        add_header Strict-Transport-Security "max-age=15768000";

        ssl_certificate /etc/letsencrypt/live/wekan.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/wekan.example.com/privkey.pem;

        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
        ssl_prefer_server_ciphers on;

        ssl_stapling on;
        ssl_stapling_verify on;

        error_page 497  https://$host:$server_port$request_uri;
        location / {
            proxy_pass http://wekan;
            proxy_http_version 1.1;
            proxy_set_header Host $host:$server_port;
            proxy_set_header Referer $http_referer;
            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 https;
            proxy_set_header X-Forwarded-Ssl on;
            proxy_set_header X-Nginx-Proxy true;

            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";

            proxy_redirect off;

            proxy_send_timeout 86400;
            proxy_read_timeout 86400;
        }
}

Replace wekan.example.com with your actual domain name in the above configuration.

Enable the newly added site.

sudo ln -s /etc/nginx/sites-available/wekan.example.com.conf /etc/nginx/sites-enabled/wekan.example.com.conf

Restart Nginx so that the changes can take effect.

sudo systemctl restart nginx

Enable Nginx to automatically start at boot time.

sudo systemctl enable nginx

Setup Systemd Service

Create a new user for the process to run.

sudo adduser wekan --shell /usr/sbin/nologin --home /opt/wekan

Now move all the files to the /opt/wekan directory.

sudo mv ~/wekan/* /opt/wekan/

Provide ownership of the files to the newly created user.

sudo chown -R wekan:wekan /opt/wekan

Wekan does not take data from any configuration file. Instead, it accesses it from environment variables. We will create a new file to store the environment variables. The file containing the environment variables will be passed through the Systemd service.

Create a new file to store environment variables.

 sudo nano /opt/wekan/config.env

Populate the file with the following content.

MONGO_URL='mongodb://wekan:StrongPassword@127.0.0.1:27017/wekan?authSource=wekan'
ROOT_URL='http://wekan.example.com'
MAIL_URL='smtp://user:pass@mail.example.com:25/'
MAIL_FROM='wekan@example.com'
PORT=4000
HTTP_FORWARDED_COUNT=1

Please make sure to replace the username and password.

Provide the ownership to the wekan user by running.

sudo chown -R wekan:wekan /opt/wekan/config.env

Create a new service file for the Wekan systemd service.

sudo nano /etc/systemd/system/wekan.service

Populate the file with the following.

[Unit]
Description=Wekan Server
After=syslog.target
After=network.target

[Service]
Type=simple
Restart=on-failure
StartLimitInterval=86400
StartLimitBurst=5
RestartSec=10
ExecStart=/usr/bin/node /opt/wekan/bundle/main.js
EnvironmentFile=/opt/wekan/config.env
ExecReload=/bin/kill -USR1 $MAINPID
RestartSec=10
User=wekan
Group=wekan
WorkingDirectory=/opt/wekan
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=Wekan

[Install]
WantedBy=multi-user.target

Save the file and exit from the editor. Now you can easily start Wekan.

sudo systemctl start wekan

To enable Wekan to automatically start at boot time.

sudo systemctl enable wekan

To check the status of Wekan service.

sudo systemctl status wekan

Wrapping Up

You can now access the Wekan instance on https://wekan.example.com. Start by creating a new account. Once you have created the account, you can enable administrative access to the newly created user. Login to the MongoDB shell as the administrative user.

mongo -u wekan -p --authenticationDatabase "wekan"

Now select the wekan database and update the object to promote the user to the admin user.

use wekan
db.users.update({username:'admin_user'},{$set:{isAdmin:true}})

Please make sure to replace admin_user with the actual username of the user you created. From the admin interface, you will be able to disable self-registration and update SMTP settings.

Congratulations, you have successfully installed the Wekan Kanban board on your Vultr Ubuntu instance.