How do you use HedgeDoc?

I would love to know how you are using HedgeDoc. This question goes out in all directions, it is meant for admins, users and contributors alike!

To illustrate this a little bit better, I’ll go first:

I’ve been using it for a long time (since its roots in HackMD and CodiMD), I switched over from other tools like etherpad and hackpad. I was looking for something that I could run on my own machine. Right now, I run two HedgeDoc servers and am a user on a third one.

The two instances I run are very different. One is a private installation that perhaps 3 people know about. The other one has somewhere around 50 users.

I mainly use this to prepare a text or document something in a group, occasionally we organize an event in a group using these pads. I’m planning on converting presentations over to slide mode (Currently using LibreOffice).

1 Like

Let’s get this moving!

I’m running this very small CodiMD instance available at demo.codimd.org.

The instance serves between 10 and 50 (in avg. 24) actively editing users per 10 seconds every day. The number of notes went from 3.4k up to over 6k within the past 3 months and it’s growing around 30 notes per day. It’s running one of the latest versions directly of the master branch and seems to provide a quite stable experience. According to StatusCake which I use to monitor the instance, it had an availability of 99.96% within the past 30 days. Downtimes usually appear when the containers are recreated to deploy the new images. This takes just a few seconds.

Online Users

Live editing notes

The two red bars that you see there are deployment events. The instances are deployed using the official docker-compose.yml with small modifications to simplify builds of the latest master behind a Traefik reverse proxy (not included in the docker-compose.yml):

version: '2'
services:
  database:
    image: postgres:9.6
    mem_limit: 256mb
    memswap_limit: 512mb
    read_only: true
    tmpfs:
      - /run/postgresql:size=512K
      - /tmp:size=128K
    environment:
      - POSTGRES_USER=<hidden>
      - POSTGRES_PASSWORD=<hidden>
      - POSTGRES_DB=codimd
    volumes:
      - ./database:/var/lib/postgresql/data
    networks:
      backend:
    restart: always
  codimd:
    build:
      context: https://github.com/codimd/container.git
      dockerfile: ./debian/Dockerfile
    image:  quay.io/codimd/server:master
    mem_limit: 256mb
    memswap_limit: 512mb
    read_only: true
    tmpfs:
      - /tmp:size=10M
    environment:
      - "CMD_DB_URL=postgres://<hidden>:<hidden>@database:5432/codimd"
      - "CMD_MINIO_PORT=443"
      - "CMD_DOMAIN=demo.codimd.org"
      - "CMD_MINIO_SECRET_KEY=<hidden>"
      - "CMD_USECDN=false"
      - "CMD_PROTOCOL_USESSL=true"
      - "CMD_MINIO_ENDPOINT=codimd.s3.shivering-isles.com"
      - "CMD_S3_BUCKET=demo"
      - "CMD_IMAGE_UPLOAD_TYPE=minio"
      - "CMD_MINIO_ACCESS_KEY=<hidden>"
      - "CMD_ALLOW_FREE_URL=false"
      - "CMD_URL_ADDPORT=false"
      - "CMD_MINIO_SECURE=true"
      - "CMD_EMAIL=true"
      - "CMD_GITHUB_CLIENTID=<hidden>"
      - "CMD_GITHUB_CLIENTSECRET=<hidden>"
      - "CMD_SESSION_SECRET=<hidden>"
      - "CMD_ALLOW_PDF_EXPORT=false"
      - "CMD_CSP_REPORTURI=https://codimd.report-uri.com/r/d/csp/enforce"
      - "CMD_OPENID=true"

    labels:
      - "traefik.frontend.rule=Host:demo.codimd.org;PathPrefix:/"
      - "traefik.frontend.headers.STSSeconds=63072000"
      - "traefik.frontend.headers.browserXSSFilter=true"
      - "traefik.frontend.headers.contentTypeNosniff=true"
      - "traefik.frontend.headers.customResponseHeaders=alt-svc:h2=l3sb47bzhpbelafss42pspxzqo3tipuk6bg7nnbacxdfbz7ao6semtyd.onion:443; ma=2592000"
      - "traefik.enable=true"
      - "traefik.port=3000"
      - "traefik.docker.network=proxy"

    volumes:
      - './privacy.md:/codimd/public/docs/privacy.md:ro'

    networks:
      backend:
      proxy:

    restart: always
networks:
  backend:
  proxy:
    external: true

The whole setup is running on CentOS 7 on a small server with full disk encryption in order to make sure there is no data left once I decide to move somewhere else. Encrypted backups are done 3 times a week using LVM snapshots and duplicity to an external storage. And that’s it.

That’s how I run the CodiMD demo instance. I run two other CodiMD instances using the regular release versions, but I think they are less interesting to checkout :wink:

Hope this got you inspired and encourages you to share your setup story :slight_smile:

Oh and if you wonder what I do with this instance, I develop CodiMD and mainly write documents for the community there :smile:

1 Like

I use CodiMD for drafting blog posts (published with Jekyll), collaborating with others, and for taking notes in class. With the last use, MathJax integration has been absolutely wonderful. It took me a long time to get up to speed but I can take realtime notes in calculus with it and share them with the rest of the class.

I’m also the admin that runs the instance so I’ll share a little bit about infrastructure as well :wink:

It’s just a manual installation on a server that runs 17 other applications (there’s a list with descriptions at nixnet.xyz). The OS is Debian Stable ,though I may go with Unstable next time, and I run CodiMD as a systemd service. That way, I don’t have to worry about starting it every time my server reboots; it’s automatic. The application is also run by its own user, codimd, so there’s little risk of it messing with other components of my system.

~ $ cat /etc/systemd/system/codimd.service

[Unit]
Description=Application service for collaborative markdown notes
After=systemd-networkd.service network.target

[Service]
Type=simple
#Environment=NODE_ENV=production
ExecStart=/usr/bin/npm start --production
RuntimeDirectory=codimd
WorkingDirectory=/home/codimd/codimd
StandardOutput=null
StandardError=null
User=codimd
RestartSec=15
Restart=always

[Install]
WantedBy=multi-user.target

Here’s my config file as well in case you’re curious:

{
    "production": {
        "domain": "codi.nixnet.xyz",
        "loglevel": "info",
        "hsts": {
            "enable": true,
            "maxAgeSeconds": 31536000,
            "includeSubdomains": true,
            "preload": true
        },
        "csp": {
            "enable": true,
            "directives": {
            },
            "upgradeInsecureRequests": false,
            "addDefaults": true,
            "addDisqus": false,
            "addGoogleAnalytics": false
        },
        "db": {
            "username": "codimd",
            "password": "<redacted>",
            "database": "codimd",
            "host": "localhost",
            "port": "3306",
            "dialect": "mysql"
        },
        "protocolUseSSL": true,
        "useCDN": false,
        "allowAnonymousEdits": true,
        "defaultPermission": "locked",
        "email": true,
        "allowEmailRegister": true,
        "allowGravatar": false,
        "imageUploadType": "filesystem",
        "port": "3000",
        "sessionSecret": "<redacted>"
    }
}
2 Likes

Hi,
I recently got very interested in CodiMD while looking for an alternative to tiddlywiki (TW) that could handle concurrent editing.

I’m currently porting my personal notes from TW to CodiMD because I like to have a powerful markdown editor (+ Vim mode), but I’ll try to stick to TW paradigm : chop everything in the smallest unit of knowledge and then navigate across them using tags.

The second usage I’d like to be able to achieve (and CodiMD seems not too far away from being able to handle it) is to use it at work to create a knowledge base. The team I work in (around 80 people, mostly tech but not only) is very distributed and with a huge range of skills/levels. It would allow to aggregate lots of interesting resources about programming & computer science and let everyone dig into / contribute to it according to their needs or wants.
My checklist was :

  • self-hosted
  • ACL
  • quick edition
  • oauth
  • tag navigation
  • not too bloated

Since the tech setup seems relevant, I just deployed the quay.io/codimd/server image to clever cloud tweaking just a few env vars in order to get it running there.

1 Like

Hei,

I have codimd running using traefik for routing and use acme to automagically generate ssl certificates from letsencrypt for each container defined domain name.

here is my docker-compose.yml:

version: '3'
services:
  database:
    image: postgres:9.6-alpine
    environment:
      - POSTGRES_USER=****
      - POSTGRES_PASSWORD=****
      - POSTGRES_DB=****
    volumes:
      - /live/storage/codimd/postgresql/data:/var/lib/postgresql/data/
    networks:
      - backend
    restart: always

  app:
    image: quay.io/codimd/server:1.5.0
    labels:
     - traefik.frontend.rule=Host:domain.tld
     - traefik.enable=true
     - traefik.port=3000
     - traefik.docker.network=world
    environment:
      - CMD_DB_URL=postgres://****:****@database:5432/hackmd
      - CMD_USECDN=false
      - CMD_IMAGE_UPLOAD_TYPE=filesystem
      - CMD_DOMAIN=domain.tld
      - CMD_PROTOCOL_USESSL=true
      - CMD_URL_ADDPORT=false
      - CMD_ALLOW_PDF_EXPORT=true
      - CMD_ALLOW_GRAVATAR=false
      - CMD_ALLOW_FREEURL=true
      - CMD_DEFAULT_PERMISSION=private
    networks:
      - backend
      - world
    volumes:
      - /live/storage/codimd/uploads:/hackmd/public/uploads
      - ./config.json:/hackmd/config.json:ro
    restart: always
    depends_on:
      - database

networks:
  backend:
  world:
     external: true
1 Like

Hi folks,

Hosting codimd and mariadb using docker-compose on a local linux server.
Getting image from linuxserver/codimd:latest

codimd is proxied behind traefik, getting ssl certs from letsencrypt for its subdomain.

Main use is for mocking all sorts of notes at work, personal notes/documentation + sharing docs with friends.

Are there anyone that knows the differences between image hosted by linuxserver and the one at ```
quay.io/codimd/server


/Frode
1 Like

A post was split to a new topic: Docker + Subdirectory

I’m able to take advantage of the multi-arch codimd container made by the linuxserver.io project.

I deploy CodiMD via hashicorp nomad. It runs on x64, arm, arm64 nodes depending on what the scheduler decides. I front-end the service with the fabiolb load balancer using TLS.

It’s great to be able to use it from home and work to quickly enter notes. I’d been searching for something like CodiMD to fluidly manage markdown documents, and its been a perfect. It’s a great tool to draft MD documents as well and paste into repos.

Thanks for CodiMD!

1 Like

Setup for docker-compose-letsencrypt-nginx-proxy-companion

Environment

Using CodiMD on Debian with a running a nginx-proxy-companion by evertramos as nginx server and letsencrypt bridge.

CodiMD config

I’m using the docker-compose config, with this docker-compose.yml. I deleted all unnecessary comments, but this is mainly an extended version of the example.

version: '3'
services:
  database:
    # Don't upgrade PostgreSQL by simply changing the version number
    # You need to migrate the Database to the new PostgreSQL version
    image: postgres:9.6-alpine
    environment:
      - POSTGRES_USER=hackmd
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=hackmd
    volumes:
      - database:/var/lib/postgresql/data
    networks:
      backend:
    restart: always

  app:
    image: quay.io/codimd/server:1.6.0
    tmpfs:
     # Make sure you remove this when you use filesystem as upload type
     - /codimd/public/uploads:size=10M
    environment:
      # DB_URL is formatted like: <databasetype>://<username>:<password>@<hostname>/<database>
      - CMD_DB_URL=postgres://hackmd:${POSTGRES_PASSWORD}@database:5432/hackmd
      # Environment for docker-compose-letsencrypt-companion
      - LETSENCRYPT_HOST=${MAIN_DOMAIN}
      - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
      - VIRTUAL_HOST=${MAIN_DOMAIN}
      - VIRTUAL_PORT=${VIRTUAL_PORT}
      # Environment for CodiMD
      - CMD_DOMAIN=${MAIN_DOMAIN}
      - CMD_URL_ADDPORT=false
      - CMD_PROTOCOL_USESSL=true
      - CMD_HSTS_ENABLE=false #will be manged by letsencrypt nginx
      - CMD_ALLOW_PDF_EXPORT=true
      - NODE_ENV=production
      - CMD_ALLOW_GRAVATAR=false
      - CMD_USECDN=false
      - CMD_ALLOW_ANONYMOUS=true
      - CMD_ALLOW_FREEURL=true
      - CMD_ALLOW_EMAIL_REGISTER=false
      - CMD_IMAGE_UPLOAD_TYPE=filesystem
    networks:
      backend:
      webproxy:
    restart: always
    depends_on:
      - database

# Define networks to allow best isolation
networks:
  # Internal network for communication with PostgreSQL/MySQL
  backend:
  webproxy:
     external: true

# Define named volumes so data stays in place
volumes:
  # Volume for PostgreSQL/MySQL database
  database:

In an .env file, there are some things specifies:

# Database Login
POSTGRES_PASSWORD=secretpw

# Path to container
PWD=/path/to/codimd-container/

# For use with proxy companion
DOMAINS=md.example.tld
MAIN_DOMAIN=md.example.tld
LETSENCRYPT_EMAIL=webmaster@example.tld
VIRTUAL_PORT=3000
# Default name, not used yet in config
NETWORK=webproxy

Your Questions & Comments

Feel free to contact me, if you have questions or recommendations.

Cheers,
Laenan

3 posts were split to a new topic: How to monitor CodiMD?

Hail the FOSS communities showing interest in understanding how the software ist being used :slight_smile:

How we are using it

Many of the abovementioned: we love the markdown and immediate preview, collaboration option, well-designed output, table of contents for quick navigation, slideshow support …

I am vastly using HedgeDoc in my company and in three different associations, the latter all FOSS-related. We collaboratively write meeting minutes, document drafts, priority lists, checklists, presentations, …

More important: why we are using it

I’d like to put the spotlight on how we promote using HedgeDoc: We noticed that many FOSS communities on the one hand are very good in explaining the advantages of using FOSS compared to proprietary solutions. On the other hand, however, the FOSS evangelism stops all too early when it comes to software decisions beyond that. Renonwned FOSS organizations hold their meetings on Zoom, use Google to organize their backoffice or buy Jira licenses, all because “it just works so nicely”.

In CMS Garden for example we decided that such decisions do not help marketing our “own” free and open source solutions. And yes, we had some pain on the way. Ten years back we used etherpad. And look what an improvement to that HedgeDoc is!

Being able to showcase a FOSS, self-hostable toolset nowadays helps our mission a lot. Managing our members, invoices, time-tracking, documents, media assets, communications on FOSS is possible and hassle-free. Thank you HedgeDoc community for contributing to that vision!

Example for one of our public slide decks - note slide 12.3 :wink:

Three downers, however

  • Major accessibility issues for screen reader users
  • Hard for users to keep in mind that their overview is not what everyone else will be seeing (“Didn’t you see the pad I started?”)
  • “Can you send me a PDF of this?”

But those pain points belong elsewhere.

I’m using HackMD for my notes taking, and to work in a small company. Now I’m trying to use HedgeDoc self-hosted.