In this tutorial we're going to setup a CodiMD instance behind a reverse NGINX proxy:
We're going to setup codimd via Docker, so install it like that:
root@docker0:~# apt search docker.io
Sorting... Done
Full Text Search... Done
docker-doc/stable,stable 18.09.1+dfsg1-7.1+deb10u2 all
Linux container runtime -- documentation
docker.io/stable,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 docker.io's control socket
python3-docker/stable,now 3.4.1-4 all [installed,automatic]
Python 3 wrapper to access docker.io's control socket
ruby-docker-api/stable 1.22.2-1 all
Ruby gem to interact with docker.io remote API
root@docker0:~# apt install docker.io -y
OR
root@docker0:~# curl -sSL https://get.docker.com/ | 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 apps.education.fr 0
zknt/codimd 0
lspipepr/codimd 0
luzifer/codimd 0
jbonjean/codimd 0
azyobuzin/codimd https://hackmd.azyobuzi.net/ 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 https://github.com/codimd/c… 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"
services:
database:
image: postgres:11.6-alpine
environment:
- POSTGRES_USER=codimd
- POSTGRES_PASSWORD=change_password
- POSTGRES_DB=codimd
volumes:
- "database-data:/var/lib/postgresql/data"
restart: always
codimd:
image: hackmdio/hackmd:2.3.2
environment:
- CMD_DB_URL=postgres://codimd:change_password@database/codimd
- CMD_USECDN=false
depends_on:
- database
ports:
- "3333:3000"
volumes:
- upload-data:/home/hackmd/app/public/uploads
restart: always
volumes:
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 0.0.0.0:3333->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 (192.168.0.200:3333) publicly, ideally behind a domain name and free TLS1.3 Certificates.
Right now i'm going to setup a reverse nginx proxy to my codimd docker instance on my main debian node at 10.0.0.101/16 (where port 80 and 443 are publicly accessible):
[ 10.0.0.10/16 ] [ /dev/pts/3 ] [blog/servers/codimd]
→ ssh root@10.0.0.101
root@10.0.0.101'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 10.0.0.10
root@home:~# vim /etc/nginx/sites-available/codimd.void.yt.conf
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 192.168.0.200:3333;
}
server {
listen 80;
listen [::]:80;
server_name codimd.void.yt;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name codimd.void.yt;
ssl_certificate /root/.acme.sh/codimd.void.yt/fullchain.cer;
ssl_trusted_certificate /root/.acme.sh/codimd.void.yt/codimd.void.yt.cer;
ssl_certificate_key /root/.acme.sh/codimd.void.yt/codimd.void.yt.key;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
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 80.67.188.188 80.67.169.40 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/void.yt/config# ln -s /etc/nginx/sites-available/codimd.void.yt.conf /etc/nginx/sites-enabled/
root@home:/var/www/void.yt/config# nginx -t
nginx: [emerg] BIO_new_file("/root/.acme.sh/codimd.void.yt/fullchain.cer") failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/root/.acme.sh/codimd.void.yt/fullchain.cer','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 acme.sh to get them:
root@home:/var/www/void.yt/config# systemctl stop nginx
root@home:/var/www/void.yt/config# acme.sh --issue --standalone -d codimd.void.yt -k 4096
root@home:/var/www/void.yt/config# 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/void.yt/config# systemctl start nginx
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.
Donate XMR: 8AUYjhQeG3D5aodJDtqG499N5jXXM71gYKD8LgSsFB9BUV1o7muLv3DXHoydRTK4SZaaUBq4EAUqpZHLrX2VZLH71Jrd9k8
Contact: nihilist@contact.nowhere.moe (PGP)