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
Create a New Project
Log in to your Klutch.sh dashboard and create a new project for your ByteStash code snippet manager.
Prepare Your Repository
Create a GitHub repository with the following structure for your ByteStash deployment:
bytestash-deploy/├─ Dockerfile├─ .env.example├─ entrypoint.sh├─ .gitignore└─ README.mdHere’s a Dockerfile for ByteStash:
FROM node:18-alpineWORKDIR /app# Install system dependenciesRUN apk add --no-cache \curl \git \make \python3# Clone ByteStash repositoryRUN git clone --depth 1 https://github.com/jordan-dalby/ByteStash.git /tmp/bytestash && \cp -r /tmp/bytestash/* . && \rm -rf /tmp/bytestash# Install dependenciesRUN npm ci && \npm run build# Create data directoryRUN mkdir -p /data/snippets && \chmod -R 755 /data# Expose portEXPOSE 5000# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \CMD curl -f http://localhost:5000/ || exit 1# Copy entrypoint scriptCOPY entrypoint.sh /RUN chmod +x /entrypoint.sh# Run entrypointENTRYPOINT ["/entrypoint.sh"]CMD ["npm", "start"]Create an
.env.examplefile:Terminal window # ByteStash ConfigurationNODE_ENV=productionDEBUG=false# Server ConfigurationPORT=5000BASE_PATH=ALLOWED_HOSTS=localhost,yourdomain.com# Database ConfigurationSNIPPETS_PATH=/data/snippets# AuthenticationJWT_SECRET=your-secret-key-here-min-32-charsTOKEN_EXPIRY=24hALLOW_NEW_ACCOUNTS=trueDISABLE_ACCOUNTS=falseDISABLE_INTERNAL_ACCOUNTS=false# Optional: OIDC Single Sign-OnOIDC_ENABLED=falseOIDC_DISPLAY_NAME=OIDC_ISSUER_URL=OIDC_CLIENT_ID=OIDC_CLIENT_SECRET=OIDC_SCOPES=openid profile emailCreate an
entrypoint.shfile:#!/bin/shset -eecho "Starting ByteStash..."# Create necessary directoriesmkdir -p /data/snippets# Set environment variablesexport 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 ByteStashexec "$@"Create a
.gitignorefile:.envnode_modules/dist/build/.DS_Store.idea/*.log.venv/venv/env//data//snippets/.next/.cache/*.swp*.swoCommit and push to your GitHub repository:
Terminal window git initgit add .git commit -m "Initial ByteStash code snippet manager deployment"git remote add origin https://github.com/yourusername/bytestash-deploy.gitgit push -u origin mainCreate a New App
In the Klutch.sh dashboard:
- Click “Create New App”
- Select your GitHub repository containing the Dockerfile
- Choose the branch (typically
mainormaster) - Klutch.sh will automatically detect the Dockerfile in the root directory
Configure Environment Variables
Set up ByteStash configuration in your Klutch.sh dashboard:
Variable Description Example NODE_ENVEnvironment mode productionPORTServer port 5000DEBUGDebug mode falseJWT_SECRETJWT signing secret (min 32 chars) your-secure-random-string-32-chars-minTOKEN_EXPIRYToken expiration time 24hALLOW_NEW_ACCOUNTSAllow new account registration trueDISABLE_ACCOUNTSDisable all accounts falseSNIPPETS_PATHSnippets database path /data/snippetsALLOWED_HOSTSAllowed hostnames yourdomain.com,www.yourdomain.comBASE_PATHBase URL path “ (empty) or /snippetsOIDC_ENABLEDEnable OIDC SSO falseConfigure Persistent Storage
ByteStash requires persistent storage for the SQLite database. Add persistent volumes:
Mount Path Description Recommended Size /data/snippetsSQLite database and snippets 5GB 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
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
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.comorbytestash.yourdomain.com) - Configure DNS with CNAME record pointing to your Klutch.sh app
- Update
ALLOWED_HOSTSenvironment variable with domain - Wait for DNS propagation (typically 5-15 minutes)
- Klutch.sh will automatically provision SSL certificate
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:
- Click “Create Account” on login page
- Enter username and password
- Confirm password
- Click “Register”
- Log in with your credentials
- Begin creating snippets
Creating Code Snippets
Add your first code snippet:
- Click “New Snippet” button
- Enter snippet title
- Select programming language
- Enter or paste code content
- Add tags or description (optional)
- Click “Save”
- Snippet now appears in your library
Managing Snippets
Organize and maintain your snippets:
- Search: Use search bar to find snippets by keyword
- Filter: Filter by programming language
- Edit: Click snippet to open editor and modify
- Delete: Click delete icon to remove snippet
- Copy: Click code to copy to clipboard
- Tags: Add tags for organization
- Export: Export snippets for backup
User Authentication and Tokens
Understand token management:
- JWT Tokens: Automatically generated on login
- Token Expiry: Configured via
TOKEN_EXPIRYenvironment variable - Token Refresh: Tokens refresh automatically before expiry
- Logout: Clears token from session storage
- 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:
- Navigate to
/api-docsfor Swagger documentation - All endpoints require JWT token authentication
- Token passed in
Authorization: Bearer <token>header - Example endpoints:
GET /api/v1/snippets- List snippetsPOST /api/v1/snippets- Create snippetGET /api/v1/snippets/:id- Get snippetPUT /api/v1/snippets/:id- Update snippetDELETE /api/v1/snippets/:id- Delete snippet
Setting Up OIDC Single Sign-On
Configure optional OIDC authentication:
- Set
OIDC_ENABLED=true - Configure OIDC provider settings:
OIDC_ISSUER_URL: Your OIDC provider URLOIDC_CLIENT_ID: Application client IDOIDC_CLIENT_SECRET: Application client secretOIDC_DISPLAY_NAME: Display name for SSO button
- Users can log in via OIDC provider
- Accounts automatically created on first login
- Email from OIDC provider used for account
Managing User Accounts
Administer user access:
- As admin user, access admin panel
- View all registered accounts
- Disable or enable accounts as needed
- Reset user passwords if necessary
- Configure registration settings
- Monitor account activity
Customizing Base Path
Deploy under a subpath:
- Set
BASE_PATH=/snippetsfor deployment at/snippets - All routes will be prefixed with base path
- Update DNS/domain configuration accordingly
- Update links in documentation
- Verify all resources load correctly
Backing Up Your Snippets
Protect your data:
- Export via Web UI: Download snippets as JSON/CSV
- Persistent Volume Backup: Klutch.sh maintains volume backups
- API Backup: Use API to programmatically export
- Database Backup: Copy
/data/snippetsdirectory - Version Control: Commit exported snippets to Git
Monitoring and Logging
Track application activity:
- Check application logs in Klutch.sh dashboard
- Monitor database size usage
- Track API request patterns
- Review authentication logs
- Monitor error rates
- Set up alerts for issues
Environment Variable Examples
Basic Configuration
NODE_ENV=productionPORT=5000JWT_SECRET=your-secure-random-string-32-chars-minimumALLOW_NEW_ACCOUNTS=trueSNIPPETS_PATH=/data/snippetsComplete Production Configuration
# EnvironmentNODE_ENV=productionDEBUG=false
# ServerPORT=5000BASE_PATH=ALLOWED_HOSTS=snippets.yourdomain.com,snippets.yourdomain.net
# DatabaseSNIPPETS_PATH=/data/snippets
# AuthenticationJWT_SECRET=your-very-secure-random-string-minimum-32-characters-longTOKEN_EXPIRY=24hALLOW_NEW_ACCOUNTS=trueDISABLE_ACCOUNTS=falseDISABLE_INTERNAL_ACCOUNTS=false
# OIDC Configuration (if using SSO)OIDC_ENABLED=falseOIDC_DISPLAY_NAME=Corporate LoginOIDC_ISSUER_URL=https://sso.yourdomain.comOIDC_CLIENT_ID=your_client_idOIDC_CLIENT_SECRET=your_client_secretOIDC_SCOPES=openid profile emailSample 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 exampleconst client = new ByteStashClient('https://snippets.yourdomain.com', 'your-jwt-token');
// List all snippetsconst snippets = await client.listSnippets();console.log('Snippets:', snippets);
// Create new snippetconst 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 snippetsconst 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 directorymkdir -p "$BACKUP_DIR"
echo "Starting ByteStash backup..."
# Backup database directoryecho "Backing up snippets database..."tar -czf "$BACKUP_DIR/snippets_$TIMESTAMP.tar.gz" "$SNIPPETS_PATH" 2>/dev/null || true
# Export snippets via APIecho "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 backupsecho "Cleaning up old backups..."find "$BACKUP_DIR" -name "snippets_*" -mtime +$RETENTION_DAYS -delete
# Get backup statisticsecho "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
# ByteStash REST API Examples
# Set variablesAPI_URL="https://snippets.yourdomain.com/api/v1"TOKEN="your-jwt-token-here"
# List all snippetscurl -s -H "Authorization: Bearer $TOKEN" "$API_URL/snippets" | jq
# Get specific snippetcurl -s -H "Authorization: Bearer $TOKEN" "$API_URL/snippets/1" | jq
# Create new snippetcurl -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 snippetcurl -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 snippetcurl -X DELETE "$API_URL/snippets/1" \ -H "Authorization: Bearer $TOKEN"
# Search snippetscurl -s -H "Authorization: Bearer $TOKEN" \ "$API_URL/snippets/search?q=python" | jq
# Get snippets by languagecurl -s -H "Authorization: Bearer $TOKEN" \ "$API_URL/snippets/language/javascript" | jq
# Export all snippetscurl -s -H "Authorization: Bearer $TOKEN" \ "$API_URL/snippets" | jq > snippets_backup.json
# Get API documentation (no auth required)curl -s "$API_URL/../docs" | head -50Code Snippet Best Practices
Organization
Keep snippets organized:
- Naming: Use clear, descriptive snippet titles
- Tagging: Apply consistent tags for categorization
- Language: Always select correct language for syntax highlighting
- Description: Add context about when/how to use snippet
- Comments: Include explanatory comments in code
- Version Control: Track changes via description field
Content Management
Maintain quality snippets:
- Accuracy: Verify code is correct before saving
- Dependencies: Note required libraries or imports
- Usage Example: Include how to use the snippet
- Platform Notes: Specify OS or platform requirements
- License: Note if snippet has specific license
- Source: Credit original source if applicable
Team Collaboration
Share snippets effectively:
- Common Library: Create shared snippets for team
- Documentation: Use snippets as code examples
- Standards: Maintain consistent code style
- Review: Have peers review important snippets
- Export/Import: Share snippet collections easily
Security
Protect sensitive information:
- No Credentials: Never store passwords or keys
- PII: Avoid personal identifiable information
- Access Control: Restrict accounts appropriately
- Backups: Secure backup storage
- 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:
- Update Dockerfile with latest version/tag
- Commit and push to GitHub
- Klutch.sh automatically rebuilds
- Review release notes for breaking changes
- Test snippet creation and retrieval
- Verify API functionality
- 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
- ByteStash GitHub Repository - Source code and issues
- ByteStash Wiki - Documentation and guides
- ByteStash Live Demo - Try it before deploying
- PikaPods Hosting - One-click deployment option
- Klutch.sh Getting Started Guide
- Klutch.sh Volumes Documentation
- Klutch.sh Custom Domains Guide
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.