ByteStash Self-Hosted Code Snippet Manager on AWS User Guide
Overview
ByteStash is a free, open source, self-hosted code-snippet manager for developers and teams: store, organise, tag and full-text search reusable code snippets with syntax highlighting for dozens of languages, Markdown and Mermaid rendering, multi-file snippets, and shareable links with optional expiry. This cloudimg image runs ByteStash built from source as a Node.js service under systemd, bound to the loopback address 127.0.0.1:5000 and fronted by an nginx reverse proxy on port 443 with a self-signed certificate generated per instance. The embedded SQLite datastore lives on a dedicated data volume mounted at /var/lib/bytestash, and a unique administrator account, JWT signing secret and TLS certificate are generated on the first boot of every instance, so no shared or default credential and no world-open signup window ship in the image. Backed by 24/7 cloudimg support.
What is included:
- ByteStash 1.5.12 (Node.js server + React client) managed by systemd, serving a full web UI
- nginx on port 443 (TLS) fronting the application, which is bound to the loopback address
127.0.0.1:5000; port 80 redirects to 443 - A self-signed TLS certificate generated per instance, ready to be replaced with your own domain certificate
- Open self-registration disabled, so the seeded administrator is the only account until you create more
- A unique admin password and JWT signing secret generated on first boot and recorded in a root-only file
- A dedicated data volume at
/var/lib/bytestashholding the SQLite datastore bytestash.serviceandnginx.serviceas systemd units, enabled and active- 24/7 cloudimg support
Prerequisites
An AWS account, an EC2 key pair in the target region, and a VPC with a public subnet. m5.large (2 vCPU / 8 GiB RAM) is the recommended instance type. Security group inbound: allow 22/tcp from your management network for SSH and 443/tcp for the HTTPS web UI. The application port 5000 is bound to loopback only and is never exposed.
Step 1 - Launch the AMI
Subscribe to the listing in AWS Marketplace, choose Continue to Launch, and launch through the EC2 console or the AWS CLI. Select the m5.large instance type, your key pair, and a security group that opens ports 22 and 443. On first boot the instance generates its per-VM JWT secret and TLS certificate, seeds the administrator account, brings up ByteStash behind nginx, and writes your credential to a root-only file.
Step 2 - Connecting to your instance
Connect over SSH as the default login user for the OS variant you launched:
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i /path/to/your-key.pem ubuntu@<public-ip>
Step 3 - Read your per-instance credential
The administrator username and password are unique to each instance and written to a root-only file:
sudo cat /root/bytestash-credentials.txt
BYTESTASH_URL=https://<instance-public-ip>/
BYTESTASH_USERNAME=admin
BYTESTASH_ADMIN_PASSWORD=<your-per-vm-password>
NOTE=Log in at BYTESTASH_URL with BYTESTASH_USERNAME and BYTESTASH_ADMIN_PASSWORD. Rotate the password from the account menu after first login.
Step 4 - Confirm the services and the loopback binding
Both units should be active, the application should be listening on loopback only, and nginx should hold ports 80 and 443:
systemctl is-active bytestash nginx
active
active
sudo ss -tlnp | grep -E ':5000|:443'
LISTEN 0 511 127.0.0.1:5000 0.0.0.0:*
LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
The application is reachable only through the nginx TLS proxy; nothing is served from 5000 to the network.
Step 5 - Confirm authentication from the command line
The image ships secure by default: unauthenticated API requests are refused, and the per-instance admin credential authenticates end-to-end. The self-signed certificate means curl needs -k (or your own trusted certificate):
# Unauthenticated requests are refused
curl -ks -o /dev/null -w '%{http_code}\n' https://127.0.0.1/api/snippets # -> 401
# Log in with your per-instance credential and capture the JWT
PW=$(sudo grep '^BYTESTASH_ADMIN_PASSWORD=' /root/bytestash-credentials.txt | cut -d= -f2-)
TOK=$(curl -ks -X POST https://127.0.0.1/api/auth/login \
-H 'Content-Type: application/json' \
-d "{\"username\":\"admin\",\"password\":\"$PW\"}" | python3 -c 'import json,sys;print(json.load(sys.stdin)["token"])')
# The token is valid and carries admin authorization
curl -ks https://127.0.0.1/api/auth/verify -H "bytestashauth: Bearer $TOK" # -> {"valid":true,...,"is_admin":true}
# Authenticated snippet listing succeeds
curl -ks -o /dev/null -w '%{http_code}\n' https://127.0.0.1/api/snippets -H "bytestashauth: Bearer $TOK" # -> 200
Step 6 - Sign in to the web UI
Open https://<instance-public-ip>/ in your browser. Because the certificate is self-signed per instance, your browser will warn on the first visit; proceed (or install the instance's certificate / replace it with your own for production). Sign in with the admin username and the password from the credentials file.

After signing in you land on the snippet dashboard, which lists your snippets with syntax highlighting, tags and full-text search:

Step 7 - Create and view snippets
Click New snippet to add a titled, described and categorised snippet with one or more code fragments. Toggle Make snippet public only if you want an unauthenticated share link.

Open any snippet to view it with language syntax highlighting, copy it to your clipboard, or open the raw content. Use the search box (type # to browse categories) and the language filter to find snippets quickly.

Step 8 - Confirm the dedicated data volume
The SQLite datastore lives on its own EBS volume, separate from the OS disk and independently resizable and snapshottable:
findmnt -no SOURCE,TARGET,FSTYPE /var/lib/bytestash
/dev/nvme1n1 /var/lib/bytestash ext4
Security notes
- No default credentials. The administrator password and the JWT signing secret are generated on each instance's first boot; nothing is baked into the image. Rotate the password from the account menu after first login.
- Open registration disabled. ByteStash permits only the first account to be created; once the admin is seeded, the registration endpoint returns
403, so there is no world-open signup window. - Loopback binding + TLS. The application binds to
127.0.0.1:5000and is reachable only through the nginx TLS proxy; the security group opens only SSH and HTTPS. - Replace the certificate for production. The per-instance certificate is self-signed. Point nginx at your own domain certificate (for example with Certbot, or terminate TLS at an Application Load Balancer) for a trusted connection.
- Optional OIDC single sign-on. ByteStash supports OIDC (
OIDC_ENABLEDplus issuer/client settings in/etc/bytestash/bytestash.env); it ships disabled. Contact support for help enabling it.
Backups
Back up your snippet library with EBS snapshots or AWS Backup against the /var/lib/bytestash data volume, or export snippets from the UI (Settings -> Data management -> Export Snippets).
Support
cloudimg provides 24/7 technical support for this product by email and live chat at support@cloudimg.co.uk - deployment, replacing the self-signed certificate with your own domain and certificate, OIDC configuration, and backup planning for your snippet library. For refund requests, contact support@cloudimg.co.uk with your AWS account ID and subscription details.