README covers what CodeNavigator is, screenshots of each view, quick start, configuration, keyboard shortcuts and links to docs/: a city guide (what every visual means, getting around), architecture (indexer, sessions, GitHub, rendering passes, routing), the HTTP API, GitHub App setup including the alert permissions, deployment (Docker, systemd, nginx, limits, security notes) and development (tests, layout, conventions, design notes).
3.4 KiB
3.4 KiB
Deployment
Docker
./build.sh [tag] # default codenavigator:latest; runs go test inside the build
docker run -d --name codenavigator -p 127.0.0.1:4177:4177 \
--env-file /etc/codenavigator/app.env \
--memory 2g --cpus 4 --pids-limit 512 \
codenavigator:latest
The image is a static binary on Alpine with git and CA certificates, running as a non-root user,
with a HEALTHCHECK on /api/health. Workspaces live in the container's /tmp and disappear with
it.
app.env (keep it chmod 600):
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_APP_SLUG=
# SHOW_LOCAL=true # only if visitors should be able to upload local folders
systemd
/etc/systemd/system/codenavigator.service:
[Unit]
Description=CodeNavigator (docker container)
After=docker.service network-online.target
Requires=docker.service
Wants=network-online.target
[Service]
Restart=always
RestartSec=5
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker rm -f codenavigator
ExecStart=/usr/bin/docker run --rm --name codenavigator \
--env-file /etc/codenavigator/app.env \
-p 127.0.0.1:4177:4177 \
--memory 2g --cpus 4 --pids-limit 512 \
codenavigator:latest
ExecStop=/usr/bin/docker stop -t 30 codenavigator
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now codenavigator
Redeploy: ./build.sh && sudo systemctl restart codenavigator.
nginx
server {
listen 80;
server_name codenav.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name codenav.example.com;
ssl_certificate /etc/letsencrypt/live/codenav.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/codenav.example.com/privkey.pem;
# Local folder uploads send one file per request; the frontend skips files over 8 MB.
client_max_body_size 10m;
location / {
proxy_pass http://127.0.0.1:4177;
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 $scheme;
# Indexing progress is a server-sent event stream: don't buffer it.
proxy_buffering off;
proxy_read_timeout 300s;
}
}
X-Forwarded-Proto: https makes the session cookie Secure. Certificates: certbot certonly --nginx -d codenav.example.com.
Operating limits
| Limit | Value |
|---|---|
| Concurrent indexing | 2 jobs; others queue |
| Snapshots held | 8 in total, 1 per session, least recently used evicted |
| Idle expiry | 1 hour for snapshots, finished jobs and abandoned uploads |
| Clone timeout | 10 minutes |
| File size | files over 8 MB are skipped; uploads capped at 64 MB |
| GitHub tokens | in memory, 8 hours |
All state is in memory. A restart clears snapshots and signs everyone out.
Security notes
- Local folders are off unless
SHOW_LOCAL=true. With them on, anyone who can reach the site can upload files to the server's temporary workspace. - Anyone who can reach the site can clone public repositories through it. Put it behind authentication if that matters to you.
- Visitors' GitHub tokens never reach the browser, git arguments or logs. Host git config and credential helpers are ignored, so the server's own credentials can't be used by a visitor.