selfhosting-blogposts/codimd/index.md

254 lines
11 KiB
Markdown

---
search:
exclude: true
---
# 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 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:
![](1.png) ![](2.png) ![](3.png)
Once you've registered and signed in, click 'New Note'
![](4.png) ![](5.png)
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.
## **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 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
## **Testing CodiMD**
See the result: we have TLS encryption! and this time we can collaborate our .md file with other people publicly:
![](7.png)
simply give them the URL from where you can collaborate with them:
![](8.png) ![](9.png)
And that's it! We have been able to get users to collaborate on .md files online thanks to our codimd instance.