CodiMD

CodiMD lets you create real-time collaborative markdown notes on all platforms. Inspired by Hackpad, with more focus on speed and flexibility, and built from HackMD source code.


Note

For this guide you should be familiar with the basic concepts of

Prerequisites

You’ll need your MySQL credentials. Get them with my_print_defaults:

[isabell@stardust ~]$ my_print_defaults client
--default-character-set=utf8mb4
--user=isabell
--password=MySuperSecretPassword
[isabell@stardust ~]$

We’re using Node in the stable version 8:

[isabell@stardust ~]$ uberspace tools version show node
Using 'Node.js' version: '8'
[isabell@stardust ~]$

Your blog URL needs to be setup:

[isabell@stardust ~]$ uberspace web domain list
isabell.uber.space
[isabell@stardust ~]$

Installation

You need a special database for CodiMD:

Create Database

[isabell@stardust ~]$ mysql -e "CREATE DATABASE ${USER}_codimd CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
[isabell@stardust ~]$

Download Sources

go to the release-site and download the latest version

[isabell@stardust ~]$ wget https://github.com/hackmdio/codimd/archive/6.6.66.zip
--2018-10-17 18:50:29--  https://github.com/hackmdio/codimd/archive/6.6.66.zip
Resolving github.com (github.com)... 192.30.253.112, 192.30.253.113
Connecting to github.com (github.com)|192.30.253.112|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/hackmdio/codimd/zip/1.2.1 [following]
--2018-10-17 18:50:29--  https://codeload.github.com/hackmdio/codimd/zip/1.2.1
Resolving codeload.github.com (codeload.github.com)... 192.30.253.121, 192.30.253.120
Connecting to codeload.github.com (codeload.github.com)|192.30.253.121|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: ‘6.6.66.zip’

    [     <=>                                                                                                                                        ] 7,090,453   6.28MB/s   in 1.1s

2018-10-17 18:50:31 (6.28 MB/s) - ‘6.6.66.zip’ saved [7090453]
[isabell@stardust ~]$ unzip 6.6.66.zip
[...]
[isabell@stardust ~]$ mv codimd-6.6.66/ codimd
[isabell@stardust ~]$ rm 6.6.66.zip
[isabell@stardust ~]$ cd codimd
[isabell@stardust codimd]$ bin/setup
copy config files
install npm packages
[...]
[isabell@stardust codimd]$

Remove UglifyJS

The UglifyJS plugin freezes the compilation step, because it tries to compile everything in parallel and then reaches the maximum memory-limit/user of uberspace. And since it’s apparently not necessary, we’ll just remove it.

Open webpack.production.js and comment out this line (currently line 6):

var ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')

So that it looks like this:

//var ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')

And comment out this block (currently line 15 - 26):

new ParallelUglifyPlugin({
  uglifyJS: {
    compress: {
      warnings: false
    },
    output: {
      max_line_len: 1000000
    },
    mangle: false,
    sourceMap: false
  }
}),

So that it looks like this:

/*new ParallelUglifyPlugin({
    uglifyJS: {
      compress: {
        warnings: false
      },
      output: {
        max_line_len: 1000000
      },
      mangle: false,
      sourceMap: false
    }
  }),*/

Note

The details were such at the time of writing, they might be different for the version you downloaded. If they are different, just comment out any blocks mentioning UglifyPlugin.

Compilation

[isabell@stardust codimd]$ npm run build
[...]
[isabell@stardust codimd]$

Configuration

Create config file

I don’t know why, but when I tried it, CodiMD ignored the config files. So we’ll make this very short and replace the content of config.json with this:

{
  "production": {}
}

That’s all. The actual configuration will be done through environment!

Configure Database

enter your sql credetials in .sequelizerc:

var path = require('path');

module.exports = {
    'config':          path.resolve('config.json'),
    'migrations-path': path.resolve('lib', 'migrations'),
    'models-path':     path.resolve('lib', 'models'),
    'url':             'mysql://<username>:<mysql_pw>@127.0.0.1:3306/<username>_codimd'
}

In our example this would be:

var path = require('path');

module.exports = {
    'config':          path.resolve('config.json'),
    'migrations-path': path.resolve('lib', 'migrations'),
    'models-path':     path.resolve('lib', 'models'),
    'url':             'mysql://isabell:MySuperSecretPassword@127.0.0.1:3306/isabell_codimd'
}

Setup daemon

Create a file ~/etc/services.d/codimd.ini and put the following in it:

[supervisord]
loglevel=warn

[program:codimd]
environment=
      CMD_SESSION_SECRET="<random>",
      CMD_DOMAIN="<domain>",
      CMD_PORT=60101,
      NODE_ENV="production",
      CMD_USECDN=false,
      CMD_ALLOW_ANONYMOUS=false,
      CMD_ALLOW_ANONYMOUS_EDITS=true,
      CMD_ALLOW_FREEURL=true,
      CMD_DEFAULT_PERMISSION=private,
      CMD_SESSION_LIFE=1209600000,
      CMD_EMAIL=true,
      CMD_ALLOW_EMAIL_REGISTER=false,
    CMD_IMAGE_UPLOAD_TYPE=filesystem,
      CMD_PROTOCOL_USESSL=true,
      CMD_DB_URL="mysql://<username>:<mysql_pw>@localhost:3306/<username>_codimd",

directory=%(ENV_HOME)s/codimd
command=node app.js

In our example this would be:

[supervisord]
loglevel=warn

[program:codimd]
environment=
      CMD_SESSION_SECRET="extremerandom",
      CMD_DOMAIN="isabell.uber.space",
      CMD_PORT=60101,
      NODE_ENV="production",
      CMD_USECDN=false,
      CMD_ALLOW_ANONYMOUS=false,
      CMD_ALLOW_ANONYMOUS_EDITS=true,
      CMD_ALLOW_FREEURL=true,
      CMD_DEFAULT_PERMISSION=private,
      CMD_SESSION_LIFE=1209600000,
      CMD_EMAIL=true,
      CMD_ALLOW_EMAIL_REGISTER=false,
      CMD_IMAGE_UPLOAD_TYPE=filesystem,
      CMD_PROTOCOL_USESSL=true,
      CMD_DB_URL="mysql://isabell:MySuperSecretPassword@localhost:3306/isabell_codimd",

directory=%(ENV_HOME)s/codimd
command=node app.js

Replace the values in CMD_SESSION_SECRET, CMD_DOMAIN, and CMD_DB_URL and you’re good to go!

See here for a detailed look at what these options do.

Once you run the following step, this will create a CodiMD instance without reliance on third-party CDN servers, which is private to people who had an account created via CLI.

Finishing installation

[isabell@stardust ~]$ supervisorctl reread
codimd: available
[isabell@stardust ~]$ supervisorctl update
codimd: added process group
[isabell@stardust ~]$

Add a user

Since we don’t want to run a public instance and have disabled registration, we use the CLI to add a user:

[isabell@stardust ~]$ cd ~/codimd
[isabell@stardust codimd]$ CMD_DB_URL="mysql://<username>:<mysql_pw>@127.0.0.1:3306/<username>_codimd" bin/manage_users --add isabell@uber.space
[isabell@stardust codimd]$

It will prompt you for a password now.

Warning

Don’t forget your password, neither the site nor the CLI currently seem to offer a way to reset it!

Configure web server

To make the application accessible from the outside, configure a web backend:

[isabell@stardust ~]$ uberspace web backend set / --http --port <port>
Set backend for / to port <port>; please make sure something is listening!
You can always check the status of your backend using "uberspace web backend list".
[isabell@stardust ~]$

Note

CodiMD is running on port 60101.

And you’re done!

Updates

Note

Check the changelog regularly to stay informed about new updates and releases.

[isabell@stardust ~]$ cd ~
[isabell@stardust ~]$ supervisorctl stop codimd
codimd: stopped
[isabell@stardust ~]$ mv codimd codimd-old
[isabell@stardust ~]$

Redo these steps:

if everything is fine.

[isabell@stardust ~]$ node_modules/.bin/sequelize db:migrate
[...]
[isabell@stardust ~]$ supervisorctl start codimd
codimd: started
[isabell@stardust ~]$ rm codimd-old -rf
[isabell@stardust ~]$

if you are having problems remove the ~/codimd/ and move ~/codimd-old/ back to its place.


Manual derived from this blog

Tested with CodiMD 1.2.1, Uberspace 7.1.13

Written by: stunkymonkey <http://stunkymonkey.de>