Previous Page

nihilist - 00 / 00 / 00

CodiMD Installation

In this tutorial we're going to setup a CodiMD instance behind a reverse NGINX proxy:

Initial Setup

We're going to setup codimd via Docker, so install it like that:

root@docker0:~# apt search
Sorting... Done
Full Text Search... Done
docker-doc/stable,stable 18.09.1+dfsg1-7.1+deb10u2 all
  Linux container runtime -- documentation,stable,now 18.09.1+dfsg1-7.1+deb10u2 amd64 [installed]
  Linux container runtime

python-docker/stable 3.4.1-4 all
  Python wrapper to access's control socket

python3-docker/stable,now 3.4.1-4 all [installed,automatic]
  Python 3 wrapper to access's control socket

ruby-docker-api/stable 1.22.2-1 all
  Ruby gem to interact with remote API

root@docker0:~# apt install -y
root@docker0:~# curl -sSL | CHANNEL=stable bash 

Once that's done, you can use docker from the commandline:

root@docker0:~# docker search codimd
NAME                                 DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
linuxserver/codimd                                                                   27
fabiodcorreia/codimd                 A custom CodiMD image build with Alpine Linux   1
hachikoapp/codimd                                                                    0
perspectivedaily/codimd                                                              0
rwthacs/codimd                                                                       0
proelbtn/codimd-exporter                                                             0
mbergent/codimd-pandoc               Docker Images to transform codimd-Notes with…   0
liquidinvestigations/codimd-server                                                   0
chouhongming/codimd                  Forked from hackmdio/codimd and build some n…   0
tarlety/codimd                       codimd/feature-metrics                          0
freitagsrunde/codimd                                                                 0
jinetes/codimd                       A codimd's image with arm support and non ro…   0
kishitat/codimd                      containerized codimd. Thank you, codiMD comu…   0
lsiodev/codimd                                                                       0
eoleteam/codimd                      Adaptation pour               0
zknt/codimd                                                                          0
lspipepr/codimd                                                                      0
luzifer/codimd                                                                       0
jbonjean/codimd                                                                      0
azyobuzin/codimd                               0
hitochan777/codimd4growi             CodiMD image for Growi integration              0
jokebox90/codimd                                                                     0
vinado/codimd                        CodiMD Dockerfile                               0
indiehosters/codimd                                                                  0
renefritze/codimd_cli                docker image for…   0

We're going to pick the first one, but instead of pulling the containers with docker pull containername we will use the docker-compose yaml file:

root@docker0:~# ls -lsh
total 12K
4.0K drwxr-xr-x 11 root root 4.0K Apr 18 08:03 dillinger
4.0K drwxr-xr-x  7 root root 4.0K Apr 18 08:03 kutt
4.0K drwxr-xr-x  2 root root 4.0K Apr 18 08:56 neko
root@docker0:~# mkdir codimd
root@docker0:~# cd codimd/
root@docker0:~/codimd# vim docker-compose.yaml

Edit the passwords if you want:

version: "3"
  image: postgres:11.6-alpine
   - POSTGRES_USER=codimd
   - POSTGRES_PASSWORD=change_password
   - POSTGRES_DB=codimd
   - "database-data:/var/lib/postgresql/data"
  restart: always
  image: hackmdio/hackmd:2.3.2
   - CMD_DB_URL=postgres://codimd:change_password@database/codimd
   - CMD_USECDN=false
   - database
   - "3333:3000"
   - upload-data:/home/hackmd/app/public/uploads
  restart: always
 database-data: {}
 upload-data: {}

Here i just changed the 3000 port to be 3333 because i already have another container using port 30000:wq to save and quit out of vim, then simply run the docker-compose up -d command to get the container running:

root@docker0:~/codimd# docker-compose up -d
codimd_database_1 is up-to-date
Recreating codimd_codimd_1 ... done

root@docker0:~/codimd# docker container ls
CONTAINER ID        IMAGE                   COMMAND                  CREATED              STATUS              PORTS                                                          NAMES
8120b1a3503e        hackmdio/hackmd:2.3.2   "/home/hackmd/app/do…"   6 seconds ago        Up 4 seconds>3000/tcp                                         codimd_codimd_1
cf01b3f17b03        postgres:11.6-alpine    "docker-entrypoint.s…"   About a minute ago   Up About a minute   5432/tcp                                                       codimd_database_1

And there you go! We have been able to start a codimd docker instance, let's check it out at port 3333:

Once you've registered and signed in, click 'New Note'

And there you go! you can now share the above link to another local coworker, if you want to use this publicly, you will need to setup a reverse nginx proxy to serve this service ( publicly, ideally behind a domain name and free TLS1.3 Certificates.

Reverse NGINX proxy setup

Right now i'm going to setup a reverse nginx proxy to my codimd docker instance on my main debian node at (where port 80 and 443 are publicly accessible):

[ ] [ /dev/pts/3 ] [blog/servers/codimd]
→ ssh root@
root@'s password:
Linux home 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Apr 18 18:20:35 2021 from
root@home:~# vim /etc/nginx/sites-available/ 

Doing a reverse nginx proxy is going to make the previously http only service have HTTPS and we can choose to force TLS1.2 or 1.3:

upstream codibackend {

server {
        listen 80;
        listen [::]:80;
        return 301 https://$server_name$request_uri;

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        ssl_certificate /root/;
        ssl_trusted_certificate /root/;
        ssl_certificate_key /root/;

        ssl_protocols TLSv1.3 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_session_tickets off;
        ssl_ecdh_curve auto;
        ssl_stapling on;
        ssl_stapling_verify on;
        resolver valid=300s;
        resolver_timeout 10s;

        add_header X-XSS-Protection "1; mode=block"; #Cross-site scripting
        add_header X-Frame-Options "SAMEORIGIN" always; #clickjacking
        add_header X-Content-Type-Options nosniff; #MIME-type sniffing
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

        location / {
                proxy_pass http://codibackend;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";


:wq to save and quit out of vim, then enable the website like so:

root@home:/var/www/ ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/
root@home:/var/www/ nginx -t
nginx: [emerg] BIO_new_file("/root/") failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/root/','r') error:2006D080:BIO routines:BIO_new_file:no such file)
nginx: configuration file /etc/nginx/nginx.conf test failed

Here you see nginx fail. That's because we need the TLS certificates, and we can use to get them:

root@home:/var/www/ systemctl stop nginx
root@home:/var/www/ --issue --standalone -d -k 4096

root@home:/var/www/ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Once you got the TLS certificates, enable nginx once again and see the result:

root@home:/var/www/ systemctl start nginx

Testing CodiMD

See the result: we have TLS encryption! and this time we can collaborate our .md file with other people publicly:

simply give them the URL from where you can collaborate with them:

And that's it! We have been able to get users to collaborate on .md files online thanks to our codimd instance.


Until there is Nothing left.

About nihilist

Donate XMR: 8AUYjhQeG3D5aodJDtqG499N5jXXM71gYKD8LgSsFB9BUV1o7muLv3DXHoydRTK4SZaaUBq4EAUqpZHLrX2VZLH71Jrd9k8

Contact: (PGP)