No description
- HTML 83.8%
- JavaScript 15.9%
- Dockerfile 0.3%
| backend | ||
| frontend | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.yaml | ||
| LICENSE | ||
| nginx.conf | ||
| README.md | ||
SecureNotes
A self-hosted, browser-encrypted personal notes app.
How it works
- All AES-256-GCM encryption/decryption happens in the browser
- The backend only stores an opaque encrypted string — it never sees plaintext
- Your password never leaves your device
- PBKDF2 (310,000 iterations, SHA-256) is used for key derivation
Setup on VPS with Docker + YunoHost
1. Clone / copy files to your VPS
scp -r ./securenotes user@your-vps:~/securenotes
# or just git clone your repo
2. Configure environment variables
cd ~/securenotes
cp .env.example .env
Edit .env to customize ports or images if needed:
# Frontend
FRONTEND_IMAGE=nginx:alpine
FRONTEND_PORT=8765
# Backend
BACKEND_PORT=3000
3. Start the containers
docker compose up -d --build
This starts:
frontendcontainer on port 8765 (nginx serving HTML + proxying /api/)backendcontainer on internal port 3000 (not exposed to host)
4. Configure YunoHost reverse proxy
In YunoHost admin panel:
- Go to Apps → Add app → search for a custom app, OR use the YunoHost CLI
- Or manually add an nginx reverse proxy config:
Create /etc/nginx/conf.d/securenotes.conf:
server {
listen 443 ssl;
server_name notes.yourdomain.com;
# YunoHost manages SSL certs automatically (Let's Encrypt)
include /etc/nginx/conf.d/yunohost_panel.conf.inc;
location / {
proxy_pass http://127.0.0.1:8765;
proxy_http_version 1.1;
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 https;
}
}
Then reload nginx:
sudo nginx -t && sudo systemctl reload nginx
5. Add DNS record
Point notes.yourdomain.com → your VPS IP in your DNS provider.
6. (Optional) Restrict access by IP
Add inside the nginx server block to limit to your IP only:
allow YOUR.IP.ADDRESS.HERE;
deny all;
First use
- Open
https://notes.yourdomain.com - Enter a strong password — this IS your encryption key
- If no notes exist yet, it creates a new encrypted note on first save
- If you forget your password, your notes are unrecoverable. Store it in a password manager.
File locations
| Path | Purpose |
|---|---|
frontend/index.html |
The entire frontend app |
backend/server.js |
Minimal API (read/write encrypted blob) |
nginx.conf |
Nginx config inside the frontend container |
.env.example |
Default environment variables (copy to .env) |
docker-compose.yaml |
Orchestration |
Docker volume notes_data |
Where notes.enc is stored |
Backup
# Export the encrypted blob
docker run --rm -v securenotes_notes_data:/data alpine cat /data/notes.enc > backup.enc
# Restore
cat backup.enc | docker run --rm -i -v securenotes_notes_data:/data alpine sh -c 'cat > /data/notes.enc'