GooseNotes

Run your own GooseNotes server.

The server is one file. It includes the requests portal, the admin dashboard and the sync service for the desktop app, and it keeps everything in a single database file. You don't need to install Node.js, a database server or Docker.

Putting it on the internet for a whole team? Read put it online safely and back it up before you invite anyone.

download it

Pick the file for the computer that will run the server. Each download is between 35 and 47 MB.

Your machineDownload
Windows 10/11 (64-bit)goosenote-server-windows-x64.zip
Windows on ARMgoosenote-server-windows-arm64.zip
Mac with Apple silicon (M1 and newer)goosenote-server-macos-arm64.tar.gz
Mac with an Intel chipgoosenote-server-macos-x64.tar.gz
Linux (most servers and PCs)goosenote-server-linux-x64.tar.gz
Linux on ARM (Raspberry Pi 4/5 64-bit, Graviton, Ampere)goosenote-server-linux-arm64.tar.gz

Unpack it into its own folder, for example C:\GooseNotes\ or ~/goosenotes/. Your data is saved next to the program, in a goosenote-data folder.

You can check a download against the published checksums: shasum -a 256 -c SHA256SUMS --ignore-missing on macOS and Linux, or Get-FileHash in PowerShell.

start it

Windows

Right-click the zip, choose Extract All, then double-click goosenote-server-windows-x64.exe. If SmartScreen says "Windows protected your PC", click More info, then Run anyway. Allow it on private networks if the firewall asks. Keep the window open while the server runs.

macOS

Open Terminal in the folder with the download. macOS blocks programs downloaded from the internet until you clear the flag:

tar xzf goosenote-server-macos-arm64.tar.gz
xattr -d com.apple.quarantine goosenote-server-macos-arm64
./goosenote-server-macos-arm64

Linux

tar xzf goosenote-server-linux-x64.tar.gz
./goosenote-server-linux-x64

When it's running, it prints the addresses to use:

  GooseNotes server 0.1.1 is running

  Requests portal   http://localhost:8787/portal/
  Admin dashboard   http://localhost:8787/admin/
  Desktop app URL   http://localhost:8787
  On your network   http://192.168.1.20:8787

Other options: --port 9000 to use another port, --data-dir /srv/goosenotes to keep the data somewhere else, --version and --help.

make an admin

The first time you start the server, give it an email and password for the first admin. It only does this when there are no users yet, so leaving the settings in place later does nothing.

macOS and Linux:

ADMIN_EMAIL=you@company.com ADMIN_PASSWORD='a-long-password' ./goosenote-server-linux-x64

Windows (PowerShell):

$env:ADMIN_EMAIL="you@company.com"; $env:ADMIN_PASSWORD="a-long-password"; .\goosenote-server-windows-x64.exe

Then sign in at /admin/, add your team, and point the desktop app at the Desktop app URL the server printed (or your HTTPS address once it's online).

Just want to try it?

Load the demo data instead: sample requests, projects, tickets and time entries, with ready-made accounts. Sign in as admin@goosenote.dev / admin123, or try the requests portal as priya@goosenote.dev / request123. Don't do this on a server you use for real work.

./goosenote-server-macos-arm64 seed
./goosenote-server-macos-arm64

change settings

Set these as environment variables, or put them in a .env file next to the program, one KEY=value per line.

SettingDefaultWhat it does
PORT8787The port the server listens on.
HOST0.0.0.0The address it listens on. Use 127.0.0.1 when a reverse proxy sits in front.
GOOSENOTE_DATA_DIRgoosenote-data next to the programFolder for the database and generated files.
DATABASE_PATH<data folder>/goosenote.dbExact database file. Overrides the data folder.
JWT_SECRETgenerated and saved in the data folderSigns logins. If you set it, use 32 or more random characters and never change it, or everyone gets signed out.
ADMIN_EMAIL, ADMIN_PASSWORD, ADMIN_NAMEnoneThe first admin, created only when there are no users.
CORS_ORIGINS*Comma-separated list of allowed web origins for production. Keep tauri://localhost and http://tauri.localhost for the desktop app.
TRUST_PROXYtrueSet to false when there's no reverse proxy in front.
LOG_LEVELinfodebug, info, warn or error.
NODE_ENVnoneproduction makes JWT_SECRET required.

If the program's folder isn't writable (for example under Program Files or /usr/local/bin), the data goes to %LOCALAPPDATA%\GooseNotes Server on Windows, ~/Library/Application Support/GooseNotes Server on macOS, or ~/.local/share/goosenote-server on Linux. The startup message shows which folder is in use. Run only one server per database file.

keep it running

For a team, run the server as a service so it starts when the machine boots and restarts if it stops.

Linux (systemd)
sudo useradd --system --home /var/lib/goosenotes --create-home goosenotes
sudo install -m 755 goosenote-server-linux-x64 /usr/local/bin/goosenote-server
sudo tee /etc/systemd/system/goosenotes.service >/dev/null <<'EOF'
[Unit]
Description=GooseNotes server
After=network-online.target
Wants=network-online.target

[Service]
User=goosenotes
Environment=GOOSENOTE_DATA_DIR=/var/lib/goosenotes
Environment=PORT=8787
EnvironmentFile=-/etc/goosenotes.env
ExecStart=/usr/local/bin/goosenote-server
Restart=on-failure
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/goosenotes
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable --now goosenotes

See the logs with journalctl -u goosenotes -f. Put secrets in /etc/goosenotes.env (readable only by root).

Windows

The program is a console app, so wrap it with NSSM. Run these in PowerShell as administrator:

mkdir C:\GooseNotes\data
copy goosenote-server-windows-x64.exe C:\GooseNotes\goosenote-server.exe
nssm install GooseNotes C:\GooseNotes\goosenote-server.exe
nssm set GooseNotes AppDirectory C:\GooseNotes
nssm set GooseNotes AppEnvironmentExtra GOOSENOTE_DATA_DIR=C:\GooseNotes\data PORT=8787
nssm set GooseNotes AppStdout C:\GooseNotes\goosenotes.log
nssm set GooseNotes AppStderr C:\GooseNotes\goosenotes.log
nssm set GooseNotes Start SERVICE_AUTO_START
nssm start GooseNotes
New-NetFirewallRule -DisplayName "GooseNotes" -Direction Inbound -Protocol TCP -LocalPort 8787 -Action Allow

No NSSM? A scheduled task that starts at boot also works:

$a = New-ScheduledTaskAction -Execute "C:\GooseNotes\goosenote-server.exe" -Argument "--data-dir C:\GooseNotes\data" -WorkingDirectory C:\GooseNotes
$t = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask -TaskName GooseNotes -Action $a -Trigger $t -User "SYSTEM" -RunLevel Highest
macOS (launchd)

Save this as ~/Library/LaunchAgents/app.goosenotes.server.plist and change the paths to match your folder. It runs while you're logged in; for a Mac without anyone logged in, put it in /Library/LaunchDaemons/ and add a UserName key.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>app.goosenotes.server</string>
  <key>ProgramArguments</key>
  <array><string>/Users/you/goosenotes/goosenote-server-macos-arm64</string></array>
  <key>EnvironmentVariables</key>
  <dict>
    <key>GOOSENOTE_DATA_DIR</key><string>/Users/you/goosenotes/data</string>
    <key>PORT</key><string>8787</string>
  </dict>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>StandardOutPath</key><string>/Users/you/goosenotes/goosenotes.log</string>
  <key>StandardErrorPath</key><string>/Users/you/goosenotes/goosenotes.log</string>
</dict>
</plist>
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/app.goosenotes.server.plist

put it online safely

Use HTTPS whenever people connect over the internet, because passwords and sign-in tokens travel with every request. Two easy ways:

Caddy

Caddy gets free certificates on its own. Point a DNS record such as notes.example.com at the server, open ports 80 and 443, run GooseNotes with HOST=127.0.0.1, and use this Caddyfile:

notes.example.com {
  reverse_proxy 127.0.0.1:8787
}

Cloudflare Tunnel

No open ports or public IP address needed, so it works from an office or home network:

cloudflared tunnel login
cloudflared tunnel create goosenotes
cloudflared tunnel route dns goosenotes notes.example.com
cloudflared tunnel run --url http://127.0.0.1:8787 goosenotes

Desktop apps then sign in with https://notes.example.com. Live updates (WebSockets) work through both. If you use Cloudflare Access, don't put it in front of /api/ and /ws: the desktop app can't complete an interactive login.

back it up

Everything lives in goosenote.db in the data folder. Don't copy that file while the server is running: recent changes may still be in the -wal file next to it. Take a consistent snapshot instead, while the server keeps running:

sqlite3 /var/lib/goosenotes/goosenote.db "VACUUM INTO '/backups/goosenotes-$(date +%F).db'"

Every night at 3:15, keeping two weeks of copies:

15 3 * * * sqlite3 /var/lib/goosenotes/goosenote.db "VACUUM INTO '/backups/goosenotes-$(date +\%F).db'" && find /backups -name 'goosenotes-*.db' -mtime +14 -delete

Keep a copy on another machine or in cloud storage, and back up .jwt-secret from the data folder too, or everyone has to sign in again after a restore. On Windows, run the same VACUUM INTO command with sqlite3.exe from a scheduled task.

Restoring: stop the server, replace goosenote.db with the backup, delete any goosenote.db-wal and goosenote.db-shm files, then start it again.

upgrade

  1. Back up first.
  2. Stop the server and replace the program with the new download. Keep the same file name if a service points at it.
  3. Start it again. Database changes and the web pages update on their own at startup.

Check which version is running with --version. To go back to an older version, put the old program back and restore the backup you made before upgrading, because database changes can't be undone.

fix problems

ProblemFix
EADDRINUSESomething else is using the port. Start with --port 8790.
macOS says the developer can't be verified, or the program closes right awayRun xattr -d com.apple.quarantine on the file, or right-click it and choose Open once.
Linux: Permission deniedRun chmod +x on the file, and check the folder isn't on a noexec mount.
The desktop app can't connect from another computerUse the On your network address and allow the port through the firewall.
Everyone was signed out after a restartJWT_SECRET changed or .jwt-secret was deleted. Keep it the same.
JWT_SECRET must be set when NODE_ENV=productionSet JWT_SECRET, or don't set NODE_ENV.
The portal or admin pages are blank after an upgradeDelete the .static folder in the data folder and restart.
Alpine LinuxThe program needs glibc. Use Debian, Ubuntu, Fedora, RHEL or similar.

Still stuck? Get in touch and include what the server printed when it started.