Developer Tools AWS

ByteStash Self-Hosted Code Snippet Manager on AWS User Guide

| Product: ByteStash

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/bytestash holding the SQLite datastore
  • bytestash.service and nginx.service as 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.

ByteStash sign-in page served over TLS

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

ByteStash snippet dashboard

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.

Create a new snippet in ByteStash

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.

A ByteStash snippet with syntax highlighting

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:5000 and 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_ENABLED plus 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.