# Deploy Hedgedoc on a remote server
Warning: CentOS 7 is too old to run Hedgedoc!
1, install npm
```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
source ~/.nvm/nvm.sh
```
2, Install Node.js
```
nvm install 22
# Verify Installation
node -v
npm -v
```
3, Build Hedgedoc
```
# check the latest version before git clone
git clone -b 1.10.0 https://github.com/hedgedoc/hedgedoc.git
cd hedgehoc
./bin/setup
yarn install --immutable
yarn build
```
4, Open aaPanel and create a database
5, Modify the config.json file, fill out the database password
```
{
"test": {
"db": {
"dialect": "sqlite",
"storage": "./db.hedgedoc.sqlite"
},
"urlAddPort": false,
"domain": "pad.wofost.com",
"sessionSecret": "wofost"
},
"production": {
"urlAddPort": false, # this should be false if you are using a domain
"domain": "pad.wofost.com",
"sessionSecret": "wofost",
"protocolUseSSL":true,
"loglevel": "info",
"hsts": {
"enable": true,
"maxAgeSeconds": 31536000,
"includeSubdomains": true,
"preload": true
},
"csp": {
"enable": true,
"directives": {},
"upgradeInsecureRequests": "auto",
"addDefaults": true,
"addDisqus": true,
"addGoogleAnalytics": true
},
"cookiePolicy": "lax",
"db": {
"username":"***",
"password":"***",
"database":"***",
"dialect": "mysql"
}
}
}
```
6, testing
```
NODE_ENV=production yarn start
```
7, lunch the hedgedoc
```
The nohup is no use, the hedgedoc shutdown after you turn off the terminal
```
have to set up a systemd service
```
nano /etc/systemd/system/hedgedoc.service
```
set the parn's evironment or it will not work
```
[Unit]
Description=HedgeDoc - The best platform to write and share markdown.
Documentation=https://docs.hedgedoc.org/
After=network.target
# Uncomment if you use MariaDB/MySQL
After=mysql.service
# Uncomment if you use PostgreSQL
# After=postgresql.service
[Service]
Type=exec
Environment="PATH=/root/.nvm/versions/node/v22.11.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Environment=NODE_ENV=production
Restart=always
RestartSec=2s
ExecStart=/root/.nvm/versions/node/v22.11.0/bin/yarn start
CapabilityBoundingSet=no
NewPrivileges=true
PrivateDevices=true
RemoveIPC=true
LockPersonality=true
ProtectControlGroups=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectClock=true
ProtectHostname=true
ProtectProc=noaccess
RestrictRealtime=true
RestrictSUIDSGID=true
RestrictNamespaces=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
ProtectSystem=no
ProtectHome=no
PrivateTmp=no
SystemCallArchitectures=native
SystemCallFilter=@system-service
# You may have to adjust these settings
User=root
Group=root
WorkingDirectory=/sites/hedgedoc
# Example: local storage for uploads and SQLite
ReadWritePaths=/sites/hedgedoc/public/uploads /sites/hedgedoc/db
[Install]
WantedBy=multi-user.target
```
launch service
```
systemctl daemon-reload
systemctl start hedgedoc.service
# or
systemctl restart hedgedoc.service
systemctl status hedgedoc.service
# debug
journalctl -u hedgedoc.service -e
```
8, create a static web in aaPanel, site path is
```
/your_hedgedoc_path/public
```
9, modify the site config
```
# add this to the very top
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# add this to the last but wihin the bracket
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /socket.io/ {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
```
**Some reminder:**
make sure the user to run hedgedoc is the user own the public, otherwise you can not upload images even if you run as root, so just change the owner of public to root