What is PortNote?
PortNote gives you a clear, organized view of your entire port landscape. Add your servers and VMs via a sleek web interface, assign and document port usage across all systems, and avoid conflicts before they happen. PortNote brings structure, clarity, and control to one of the most overlooked parts of your infrastructure.
📋 Prerequisites
- A Debian 11 or Debian 12 VPS with root access
- Domain name (optional, but recommended for HTTPS)
- Basic command-line knowledge
- Docker and Docker Compose (PortNote is containerized)
🛠️ How to Install and Run PortNote on Debian VPS (Self-Hosted)
To install and run PortNote on Debian VPS, follow the steps below:
-
🔐 Update and Secure Your VPS
sudo apt update && sudo apt upgrade -y
Optionally, add a firewall like
ufw
:sudo apt install ufw -y sudo ufw allow ssh sudo ufw enable
-
🐳 Install Docker & Docker Compose
Install Docker:
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh
Install Docker Compose (v2):
sudo apt install docker-compose-plugin -y
Verify:
docker --version docker compose version
-
📦 Configure Docker Compose
Edit
docker-compose.yml
:services: web: image: haedlessdev/portnote:latest ports: - "3000:3000" environment: JWT_SECRET: RANDOM_SECRET # Replace with a secure random string USER_SECRET: RANDOM_SECRET # Replace with a secure random string LOGIN_USERNAME: username # Replace with a username LOGIN_PASSWORD: mypassword # Replace with a custom password DATABASE_URL: "postgresql://postgres:postgres@db:5432/postgres" depends_on: db: condition: service_started agent: image: haedlessdev/portnote-agent:latest environment: DATABASE_URL: "postgresql://postgres:postgres@db:5432/postgres" depends_on: db: condition: service_started db: image: postgres:17 restart: always environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres volumes: - postgres_data:/var/lib/postgresql/data volumes: postgres_data:
-
⚙️ Configure
.env
FileMake a copy of the example environment:
cp .env.example .env
Edit the
.env
file to set the admin email, domain, and optionally change the database password and JWT secret:nano .env
Key variables to customize:
JWT_SECRET: RANDOM_SECRET # Replace with a secure random string USER_SECRET: RANDOM_SECRET # Replace with a secure random string LOGIN_USERNAME: username # Replace with a username LOGIN_PASSWORD: mypassword # Replace with a custom password
-
🔧 Configure Reverse Proxy (Optional for Custom Domain)
If using a custom domain, it’s best to enable HTTPS with a reverse proxy like Nginx and Let’s Encrypt.
You can use Nginx Proxy Manager or set up your own Nginx + Certbot manually.
Otherwise, skip to the next step to run it on localhost with port binding.
-
🚀 Launch PortNote with Docker Compose
Make sure you’re in the root
portnote/
folder:docker compose up -d
Wait for containers to initialize. You can check logs with:
docker compose logs -f
-
🧪 Access PortNote
- If using a domain:
- Visit
http://yourdomain.com
- If using localhost or IP:
- Visit
http://YOUR_SERVER_IP:3000
-
🔄 Optional: Set Up System Auto-Start
To ensure PortNote starts on reboot:
sudo systemctl enable docker.service sudo systemctl enable containerd.service
If you’re using a custom Docker Compose service script, you can enable it as a
systemd
service. -
(Optional) Configure Backups
To back up your PortNote data:
docker exec -it portnote-db pg_dump -U postgres portnote > portnote_backup.sql
Store this securely or use remote backup automation.
🔚 Done!
Your self-hosted PortNote instance is now live and secured.
📎 Helpful Commands
# Stop the app docker compose down # Restart the app docker compose up -d # View running containers docker ps
🔐 Security Tips
- Change default JWT and DB secrets
- Keep VPS and Docker updated
- Set up a firewall and fail2ban
- Use HTTPS with a trusted certificate
Secure PortNote with Free SSL Certificate
To install and secure PortNote with free SSL certificate, follow the steps below:
- Install Nginx and Certbot:
sudo apt update sudo apt install nginx certbot python3-certbot-nginx -y
- Configure Ngnix:
sudo nano /etc/nginx/sites-available/portnote
Enter the following:
server { listen 80; server_name portnote.raddemo.host; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }
- Enable the site:
sudo ln -s /etc/nginx/sites-available/portnote /etc/nginx/sites-enabled/
- Test and reload:
sudo nginx -t sudo systemctl reload nginx
- Request the SSL using Certbot:
sudo certbot --nginx -d portnote.raddemo.host
Output:
root@portnote:~# sudo certbot --nginx -d portnote.raddemo.host Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator nginx, Installer nginx Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): xxxxxxxx@xxxxxxx.xxxx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.5-February-24-2025.pdf. You must agree in order to register with the ACME server. Do you agree? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: Y - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing, once your first certificate is successfully issued, to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: n Account registered. Requesting a certificate for portnote.raddemo.host Performing the following challenges: http-01 challenge for portnote.raddemo.host Waiting for verification... Cleaning up challenges Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/portnote Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/portnote - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations! You have successfully enabled https://portnote.raddemo.host - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/portnote.raddemo.host/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/portnote.raddemo.host/privkey.pem Your certificate will expire on 2025-09-27. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le root@portnote:~#
- Enable Auto-Renewal (Optional):
Certbot adds this automatically via systemd timer, but you can test it with:sudo certbot renew --dry-run
- Access PortNote Securely:
https://portnote.raddemo.host
You should see your PortNote login screen, served securely via HTTPS.
🧰 Nginx + Certbot Reference Commands
Action | Command |
---|---|
Check Nginx config | sudo nginx -t |
Reload Nginx | sudo systemctl reload nginx |
Force renew SSL | sudo certbot renew |
Test renew | sudo certbot renew --dry-run |
Nginx log (access) | sudo tail -f /var/log/nginx/access.log |
Nginx log (error) | sudo tail -f /var/log/nginx/error.log |
Conclusion
You now know how to install and run PortNote on Debian VPS. You also learned how to install and secure PortNote with free SSL certificate.