Skip to content

Deploying ByteStash

ByteStash is a self-hosted web application designed to store, organize, and manage your code snippets efficiently with an intuitive React-based interface and robust Node.js backend. Built with security and usability in mind, ByteStash provides comprehensive snippet management capabilities including creating and editing code snippets with syntax highlighting support, powerful filtering by programming language and content, secure SQLite database storage with optional encryption, multi-user support with JWT-based authentication, account management with login/registration, flexible token expiry configuration, optional single sign-on via OIDC integration, RESTful API with complete Swagger documentation, and customizable branding and paths. Whether you’re managing personal code repositories for quick reference, organizing team-shared code snippets for collaboration, maintaining documentation code examples for knowledge bases, tracking utility scripts and automation tools, or building a centralized code library for your organization, ByteStash provides the infrastructure for secure and accessible snippet management.

Why ByteStash?

ByteStash stands out as a premier self-hosted snippet management solution:

  • Code Snippet Storage: Securely store and organize code snippets
  • Multiple Language Support: Filter and manage snippets by programming language
  • Intuitive Interface: React-based frontend with Tailwind CSS styling
  • Full CRUD Operations: Create, read, update, and delete snippets easily
  • User Authentication: JWT-based multi-user support with login/registration
  • Secure Database: SQLite storage with optional encryption support
  • Account Management: User registration and account administration
  • Token Configuration: Flexible token expiry and refresh settings
  • API Documentation: Complete REST API with Swagger/OpenAPI documentation
  • Single Sign-On: Optional OIDC integration for enterprise SSO
  • Self-hosted: Full control over data and deployment
  • Docker Support: Easy containerized deployment
  • Syntax Highlighting: Language-specific code formatting and display
  • Search and Filter: Find snippets by language, keywords, or content
  • Export/Import: Backup and migrate snippets easily
  • Keyboard Shortcuts: Power user features for faster snippet management
  • Mobile Responsive: Access snippets from any device
  • No Tracking: Privacy-focused with no analytics or telemetry
  • Active Community: Regular updates and community support

ByteStash is ideal for developers managing personal code libraries, teams collaborating on code snippets, organizations maintaining centralized code repositories, developers maintaining cheatsheets and references, teams sharing reusable code patterns, and technical teams documenting solutions. With persistent storage on Klutch.sh, your code snippets are always available, organized, and secure.

Prerequisites

Before deploying ByteStash, ensure you have:

  • A Klutch.sh account
  • A GitHub repository with your ByteStash deployment configuration
  • Basic familiarity with Docker and Git
  • Node.js/npm for local testing (optional)
  • Custom domain for your snippet manager (recommended)
  • HTTPS enabled for secure access
  • Sufficient storage for snippet database (typically 1-10GB)
  • Understanding of user authentication concepts
  • Time for initial configuration and team setup

Important Considerations

Deploying ByteStash

  1. Create a New Project

    Log in to your Klutch.sh dashboard and create a new project for your ByteStash code snippet manager.

  2. Prepare Your Repository

    Create a GitHub repository with the following structure for your ByteStash deployment:

    bytestash-deploy/
    ├─ Dockerfile
    ├─ .env.example
    ├─ entrypoint.sh
    ├─ .gitignore
    └─ README.md

    Here’s a Dockerfile for ByteStash:

    FROM node:18-alpine
    WORKDIR /app
    # Install system dependencies
    RUN apk add --no-cache \
    curl \
    git \
    make \
    python3
    # Clone ByteStash repository
    RUN git clone --depth 1 https://github.com/jordan-dalby/ByteStash.git /tmp/bytestash && \
    cp -r /tmp/bytestash/* . && \
    rm -rf /tmp/bytestash
    # Install dependencies
    RUN npm ci && \
    npm run build
    # Create data directory
    RUN mkdir -p /data/snippets && \
    chmod -R 755 /data
    # Expose port
    EXPOSE 5000
    # Health check
    HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
    CMD curl -f http://localhost:5000/ || exit 1
    # Copy entrypoint script
    COPY entrypoint.sh /
    RUN chmod +x /entrypoint.sh
    # Run entrypoint
    ENTRYPOINT ["/entrypoint.sh"]
    CMD ["npm", "start"]

    Create an .env.example file:

    Terminal window
    # ByteStash Configuration
    NODE_ENV=production
    DEBUG=false
    # Server Configuration
    PORT=5000
    BASE_PATH=
    ALLOWED_HOSTS=localhost,yourdomain.com
    # Database Configuration
    SNIPPETS_PATH=/data/snippets
    # Authentication
    JWT_SECRET=your-secret-key-here-min-32-chars
    TOKEN_EXPIRY=24h
    ALLOW_NEW_ACCOUNTS=true
    DISABLE_ACCOUNTS=false
    DISABLE_INTERNAL_ACCOUNTS=false
    # Optional: OIDC Single Sign-On
    OIDC_ENABLED=false
    OIDC_DISPLAY_NAME=
    OIDC_ISSUER_URL=
    OIDC_CLIENT_ID=
    OIDC_CLIENT_SECRET=
    OIDC_SCOPES=openid profile email

    Create an entrypoint.sh file:

    #!/bin/sh
    set -e
    echo "Starting ByteStash..."
    # Create necessary directories
    mkdir -p /data/snippets
    # Set environment variables
    export NODE_ENV=${NODE_ENV:-production}
    export PORT=${PORT:-5000}
    export JWT_SECRET=${JWT_SECRET:-$(head -c 32 /dev/urandom | base64)}
    export SNIPPETS_PATH=${SNIPPETS_PATH:-/data/snippets}
    echo "ByteStash configuration:"
    echo "- Environment: $NODE_ENV"
    echo "- Port: $PORT"
    echo "- Snippets Path: $SNIPPETS_PATH"
    echo "- Debug: $DEBUG"
    # Start ByteStash
    exec "$@"

    Create a .gitignore file:

    .env
    node_modules/
    dist/
    build/
    .DS_Store
    .idea/
    *.log
    .venv/
    venv/
    env/
    /data/
    /snippets/
    .next/
    .cache/
    *.swp
    *.swo

    Commit and push to your GitHub repository:

    Terminal window
    git init
    git add .
    git commit -m "Initial ByteStash code snippet manager deployment"
    git remote add origin https://github.com/yourusername/bytestash-deploy.git
    git push -u origin main
  3. Create a New App

    In the Klutch.sh dashboard:

    • Click “Create New App”
    • Select your GitHub repository containing the Dockerfile
    • Choose the branch (typically main or master)
    • Klutch.sh will automatically detect the Dockerfile in the root directory
  4. Configure Environment Variables

    Set up ByteStash configuration in your Klutch.sh dashboard:

    VariableDescriptionExample
    NODE_ENVEnvironment modeproduction
    PORTServer port5000
    DEBUGDebug modefalse
    JWT_SECRETJWT signing secret (min 32 chars)your-secure-random-string-32-chars-min
    TOKEN_EXPIRYToken expiration time24h
    ALLOW_NEW_ACCOUNTSAllow new account registrationtrue
    DISABLE_ACCOUNTSDisable all accountsfalse
    SNIPPETS_PATHSnippets database path/data/snippets
    ALLOWED_HOSTSAllowed hostnamesyourdomain.com,www.yourdomain.com
    BASE_PATHBase URL path“ (empty) or /snippets
    OIDC_ENABLEDEnable OIDC SSOfalse
  5. Configure Persistent Storage

    ByteStash requires persistent storage for the SQLite database. Add persistent volumes:

    Mount PathDescriptionRecommended Size
    /data/snippetsSQLite database and snippets5GB

    In the Klutch.sh dashboard:

    • Navigate to your app settings
    • Go to the “Volumes” section
    • Click “Add Volume”
    • Set mount path to /data/snippets
    • Set size to 5GB (adjust based on expected usage)
    • Ensure persistent volume is properly configured
  6. Set Network Configuration

    Configure your app’s network settings:

    • Select traffic type: HTTP
    • Recommended internal port: 5000 (ByteStash default)
    • Klutch.sh will handle HTTPS termination via reverse proxy
    • Application will be accessible via your custom domain
  7. Configure Custom Domain

    Set up custom domain for your snippet manager:

    • Navigate to your app’s “Domains” section in Klutch.sh
    • Add custom domain (e.g., snippets.yourdomain.com or bytestash.yourdomain.com)
    • Configure DNS with CNAME record pointing to your Klutch.sh app
    • Update ALLOWED_HOSTS environment variable with domain
    • Wait for DNS propagation (typically 5-15 minutes)
    • Klutch.sh will automatically provision SSL certificate
  8. Deploy Your App

    • Review all settings and environment variables carefully
    • Verify JWT_SECRET is set to secure random value
    • Verify custom domain is configured
    • Ensure persistent volume is properly configured
    • Click “Deploy”
    • Klutch.sh will build the Docker image and start your ByteStash instance
    • Wait for deployment to complete (typically 15-20 minutes)
    • Access ByteStash at your configured domain
    • Create your first user account
    • Verify snippet creation and management works

Initial Setup and Configuration

After deployment completes, configure your snippet manager.

Accessing ByteStash

Navigate to your domain: https://snippets.yourdomain.com

ByteStash will display a login page. Create an account or use the demo credentials if configured.

Creating Your First Account

Set up your user account:

  1. Click “Create Account” on login page
  2. Enter username and password
  3. Confirm password
  4. Click “Register”
  5. Log in with your credentials
  6. Begin creating snippets

Creating Code Snippets

Add your first code snippet:

  1. Click “New Snippet” button
  2. Enter snippet title
  3. Select programming language
  4. Enter or paste code content
  5. Add tags or description (optional)
  6. Click “Save”
  7. Snippet now appears in your library

Managing Snippets

Organize and maintain your snippets:

  1. Search: Use search bar to find snippets by keyword
  2. Filter: Filter by programming language
  3. Edit: Click snippet to open editor and modify
  4. Delete: Click delete icon to remove snippet
  5. Copy: Click code to copy to clipboard
  6. Tags: Add tags for organization
  7. Export: Export snippets for backup

User Authentication and Tokens

Understand token management:

  1. JWT Tokens: Automatically generated on login
  2. Token Expiry: Configured via TOKEN_EXPIRY environment variable
  3. Token Refresh: Tokens refresh automatically before expiry
  4. Logout: Clears token from session storage
  5. API Access: Use token for programmatic access

Programming Language Support

ByteStash supports syntax highlighting for:

  • Python
  • JavaScript
  • TypeScript
  • Java
  • C++
  • C#
  • Go
  • Rust
  • PHP
  • Ruby
  • Bash
  • SQL
  • HTML
  • CSS
  • JSON
  • YAML
  • Markdown
  • And many more…

Accessing the API

Use ByteStash REST API:

  1. Navigate to /api-docs for Swagger documentation
  2. All endpoints require JWT token authentication
  3. Token passed in Authorization: Bearer <token> header
  4. Example endpoints:
    • GET /api/v1/snippets - List snippets
    • POST /api/v1/snippets - Create snippet
    • GET /api/v1/snippets/:id - Get snippet
    • PUT /api/v1/snippets/:id - Update snippet
    • DELETE /api/v1/snippets/:id - Delete snippet

Setting Up OIDC Single Sign-On

Configure optional OIDC authentication:

  1. Set OIDC_ENABLED=true
  2. Configure OIDC provider settings:
    • OIDC_ISSUER_URL: Your OIDC provider URL
    • OIDC_CLIENT_ID: Application client ID
    • OIDC_CLIENT_SECRET: Application client secret
    • OIDC_DISPLAY_NAME: Display name for SSO button
  3. Users can log in via OIDC provider
  4. Accounts automatically created on first login
  5. Email from OIDC provider used for account

Managing User Accounts

Administer user access:

  1. As admin user, access admin panel
  2. View all registered accounts
  3. Disable or enable accounts as needed
  4. Reset user passwords if necessary
  5. Configure registration settings
  6. Monitor account activity

Customizing Base Path

Deploy under a subpath:

  1. Set BASE_PATH=/snippets for deployment at /snippets
  2. All routes will be prefixed with base path
  3. Update DNS/domain configuration accordingly
  4. Update links in documentation
  5. Verify all resources load correctly

Backing Up Your Snippets

Protect your data:

  1. Export via Web UI: Download snippets as JSON/CSV
  2. Persistent Volume Backup: Klutch.sh maintains volume backups
  3. API Backup: Use API to programmatically export
  4. Database Backup: Copy /data/snippets directory
  5. Version Control: Commit exported snippets to Git

Monitoring and Logging

Track application activity:

  1. Check application logs in Klutch.sh dashboard
  2. Monitor database size usage
  3. Track API request patterns
  4. Review authentication logs
  5. Monitor error rates
  6. Set up alerts for issues

Environment Variable Examples

Basic Configuration

Terminal window
NODE_ENV=production
PORT=5000
JWT_SECRET=your-secure-random-string-32-chars-minimum
ALLOW_NEW_ACCOUNTS=true
SNIPPETS_PATH=/data/snippets

Complete Production Configuration

Terminal window
# Environment
NODE_ENV=production
DEBUG=false
# Server
PORT=5000
BASE_PATH=
ALLOWED_HOSTS=snippets.yourdomain.com,snippets.yourdomain.net
# Database
SNIPPETS_PATH=/data/snippets
# Authentication
JWT_SECRET=your-very-secure-random-string-minimum-32-characters-long
TOKEN_EXPIRY=24h
ALLOW_NEW_ACCOUNTS=true
DISABLE_ACCOUNTS=false
DISABLE_INTERNAL_ACCOUNTS=false
# OIDC Configuration (if using SSO)
OIDC_ENABLED=false
OIDC_DISPLAY_NAME=Corporate Login
OIDC_ISSUER_URL=https://sso.yourdomain.com
OIDC_CLIENT_ID=your_client_id
OIDC_CLIENT_SECRET=your_client_secret
OIDC_SCOPES=openid profile email

Sample Code and Getting Started

JavaScript - API Integration Example

// ByteStash API Integration Example
class ByteStashClient {
constructor(baseURL, token) {
this.baseURL = baseURL;
this.token = token;
}
async request(method, endpoint, data = null) {
const options = {
method,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`
}
};
if (data) {
options.body = JSON.stringify(data);
}
const response = await fetch(`${this.baseURL}/api/v1${endpoint}`, options);
if (!response.ok) {
throw new Error(`API error: ${response.statusText}`);
}
return response.json();
}
async listSnippets() {
return this.request('GET', '/snippets');
}
async getSnippet(id) {
return this.request('GET', `/snippets/${id}`);
}
async createSnippet(snippet) {
return this.request('POST', '/snippets', {
title: snippet.title,
language: snippet.language,
content: snippet.content,
tags: snippet.tags || [],
description: snippet.description || ''
});
}
async updateSnippet(id, snippet) {
return this.request('PUT', `/snippets/${id}`, snippet);
}
async deleteSnippet(id) {
return this.request('DELETE', `/snippets/${id}`);
}
async searchSnippets(query) {
return this.request('GET', `/snippets/search?q=${encodeURIComponent(query)}`);
}
async getByLanguage(language) {
return this.request('GET', `/snippets/language/${language}`);
}
}
// Usage example
const client = new ByteStashClient('https://snippets.yourdomain.com', 'your-jwt-token');
// List all snippets
const snippets = await client.listSnippets();
console.log('Snippets:', snippets);
// Create new snippet
const newSnippet = await client.createSnippet({
title: 'React Hooks Example',
language: 'javascript',
content: 'const [count, setCount] = useState(0);',
tags: ['react', 'hooks', 'example']
});
console.log('Created:', newSnippet);
// Search snippets
const results = await client.searchSnippets('useState');
console.log('Search results:', results);

Bash - Backup and Maintenance Script

#!/bin/bash
# ByteStash Backup and Maintenance Script
BACKUP_DIR="/backups/bytestash"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
SNIPPETS_PATH="/data/snippets"
API_URL="${API_URL:-https://snippets.yourdomain.com}"
API_TOKEN="${API_TOKEN:-your-token}"
RETENTION_DAYS=30
# Create backup directory
mkdir -p "$BACKUP_DIR"
echo "Starting ByteStash backup..."
# Backup database directory
echo "Backing up snippets database..."
tar -czf "$BACKUP_DIR/snippets_$TIMESTAMP.tar.gz" "$SNIPPETS_PATH" 2>/dev/null || true
# Export snippets via API
echo "Exporting snippets via API..."
curl -s -H "Authorization: Bearer $API_TOKEN" \
"$API_URL/api/v1/snippets" | jq > "$BACKUP_DIR/snippets_export_$TIMESTAMP.json"
# Cleanup old backups
echo "Cleaning up old backups..."
find "$BACKUP_DIR" -name "snippets_*" -mtime +$RETENTION_DAYS -delete
# Get backup statistics
echo "Backup Statistics:"
BACKUP_COUNT=$(find "$BACKUP_DIR" -name "snippets_$TIMESTAMP*" | wc -l)
TOTAL_SIZE=$(du -sh "$BACKUP_DIR" | awk '{print $1}')
SNIPPET_COUNT=$(jq 'length' "$BACKUP_DIR/snippets_export_$TIMESTAMP.json" 2>/dev/null || echo "N/A")
echo "✓ Backup files created: $BACKUP_COUNT"
echo "✓ Total snippets: $SNIPPET_COUNT"
echo "✓ Total backup size: $TOTAL_SIZE"
echo "✓ Backup location: $BACKUP_DIR"
echo "✓ Backup completed at: $TIMESTAMP"

cURL - REST API Examples

Terminal window
# ByteStash REST API Examples
# Set variables
API_URL="https://snippets.yourdomain.com/api/v1"
TOKEN="your-jwt-token-here"
# List all snippets
curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/snippets" | jq
# Get specific snippet
curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/snippets/1" | jq
# Create new snippet
curl -X POST "$API_URL/snippets" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Python List Comprehension",
"language": "python",
"content": "squares = [x**2 for x in range(10)]",
"tags": ["python", "list-comprehension"],
"description": "Example of Python list comprehension"
}'
# Update existing snippet
curl -X PUT "$API_URL/snippets/1" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Python Example",
"content": "squares = [x**2 for x in range(20)]"
}'
# Delete snippet
curl -X DELETE "$API_URL/snippets/1" \
-H "Authorization: Bearer $TOKEN"
# Search snippets
curl -s -H "Authorization: Bearer $TOKEN" \
"$API_URL/snippets/search?q=python" | jq
# Get snippets by language
curl -s -H "Authorization: Bearer $TOKEN" \
"$API_URL/snippets/language/javascript" | jq
# Export all snippets
curl -s -H "Authorization: Bearer $TOKEN" \
"$API_URL/snippets" | jq > snippets_backup.json
# Get API documentation (no auth required)
curl -s "$API_URL/../docs" | head -50

Code Snippet Best Practices

Organization

Keep snippets organized:

  1. Naming: Use clear, descriptive snippet titles
  2. Tagging: Apply consistent tags for categorization
  3. Language: Always select correct language for syntax highlighting
  4. Description: Add context about when/how to use snippet
  5. Comments: Include explanatory comments in code
  6. Version Control: Track changes via description field

Content Management

Maintain quality snippets:

  1. Accuracy: Verify code is correct before saving
  2. Dependencies: Note required libraries or imports
  3. Usage Example: Include how to use the snippet
  4. Platform Notes: Specify OS or platform requirements
  5. License: Note if snippet has specific license
  6. Source: Credit original source if applicable

Team Collaboration

Share snippets effectively:

  1. Common Library: Create shared snippets for team
  2. Documentation: Use snippets as code examples
  3. Standards: Maintain consistent code style
  4. Review: Have peers review important snippets
  5. Export/Import: Share snippet collections easily

Security

Protect sensitive information:

  1. No Credentials: Never store passwords or keys
  2. PII: Avoid personal identifiable information
  3. Access Control: Restrict accounts appropriately
  4. Backups: Secure backup storage
  5. Encryption: Use HTTPS for all access

Troubleshooting

Common Issues and Solutions

Issue: Cannot log in to ByteStash

Solutions:

  • Verify username and password are correct
  • Check if account creation is enabled
  • Clear browser cookies and cache
  • Verify HTTPS certificate is valid
  • Check application logs for errors

Issue: Snippets not persisting after restart

Troubleshooting:

  • Verify persistent volume is mounted
  • Check volume mount path in configuration
  • Ensure volume has sufficient disk space
  • Verify file permissions on persistent volume
  • Check application logs for database errors

Issue: API requests returning 401 Unauthorized

Solutions:

  • Verify JWT token is valid and not expired
  • Check Authorization header format: Bearer <token>
  • Ensure token is included in request
  • Verify user account is enabled
  • Check token in authentication logs

Issue: Slow snippet search or listing

Troubleshooting:

  • Monitor database size
  • Consider archiving old snippets
  • Check database indexes
  • Review query performance
  • Export and reimport snippets to optimize

Issue: OIDC login not working

Solutions:

  • Verify OIDC configuration is correct
  • Check OIDC provider credentials
  • Ensure issuer URL is accessible
  • Verify client ID and secret
  • Check redirect URI configuration

Updating ByteStash

To update ByteStash to a newer version:

  1. Update Dockerfile with latest version/tag
  2. Commit and push to GitHub
  3. Klutch.sh automatically rebuilds
  4. Review release notes for breaking changes
  5. Test snippet creation and retrieval
  6. Verify API functionality
  7. Confirm backups are accessible

Use Cases

Personal Code Library

  • Store frequently used code snippets
  • Build personal cheatsheets
  • Organize code templates
  • Quick reference for common patterns

Team Collaboration

  • Share reusable code snippets
  • Document best practices
  • Maintain coding standards
  • Build team knowledge base

Documentation

  • Code examples for documentation
  • Tutorial code samples
  • API endpoint examples
  • Configuration templates

Development Tools

  • Integration with IDEs via API
  • CLI tools for snippet management
  • Custom workflow automation
  • CI/CD integration

Additional Resources

Conclusion

Deploying ByteStash on Klutch.sh provides you with a powerful, self-hosted code snippet management solution that keeps your code organized, searchable, and secure. With comprehensive features including snippet creation and editing, language-based filtering, multi-user authentication with JWT tokens, optional OIDC single sign-on, complete REST API with Swagger documentation, persistent SQLite storage, and an intuitive React-based interface, ByteStash enables you to build a centralized, organized repository of your most valuable code. Klutch.sh’s managed infrastructure ensures your snippet database is always available, backed up, and performant, allowing you to focus on sharing and organizing your most useful code without worrying about infrastructure management.

Start organizing your code snippets today by deploying ByteStash on Klutch.sh and experience the efficiency of having all your code in one secure, searchable location.