Skip to content

Deploying BinPastes

BinPastes is a lightweight, self-hosted pastebin application that allows you to securely share code snippets, text, and configuration files. Built with simplicity and privacy in mind, BinPastes provides a clean interface for creating, sharing, and managing pastes without relying on third-party services. Perfect for developers, system administrators, and teams who need a private, customizable pastebin solution that they fully control.

Why BinPastes?

BinPastes stands out as a pastebin solution with its focus on simplicity, privacy, and control:

  • Self-Hosted: Run your own pastebin server—keep all pastes private and under your control
  • Lightweight: Minimal resource requirements and fast performance
  • Syntax Highlighting: Support for hundreds of programming languages and syntax highlighting themes
  • Simple Interface: Clean, intuitive UI for quick paste creation and sharing
  • Private Pastes: Option to create private pastes that require authentication
  • Expiration Control: Set automatic expiration for pastes (never, hours, days, weeks, months)
  • API Support: Programmatic access for creating and retrieving pastes
  • Download Pastes: Download pastes as plain text or with syntax highlighting
  • Search Functionality: Search through your pastes for quick retrieval
  • Multi-Language Support: Syntax highlighting for 100+ programming languages
  • No Database Required: Some configurations use flat files for paste storage
  • Docker Ready: Easy containerization for deployment
  • Open Source: MIT licensed with full source code available
  • Customizable: Modify themes, appearance, and functionality to match your needs

BinPastes is ideal for development teams, technical documentation, code sharing, incident response, and organizations that need a private alternative to public pastebin services. With persistent storage on Klutch.sh, all your pastes are securely stored and always accessible.

Prerequisites

Before deploying BinPastes, ensure you have:

  • A Klutch.sh account
  • A GitHub repository with your BinPastes deployment configuration
  • Basic familiarity with Docker and Git
  • A domain name (recommended for production)
  • Understanding of how pastebin applications work

Important Considerations

Deploying BinPastes

  1. Create a New Project

    Log in to your Klutch.sh dashboard and create a new project for your BinPastes deployment.

  2. Prepare Your Repository

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

    binpastes-deploy/
    ├─ Dockerfile
    ├─ .env.example
    ├─ nginx.conf
    ├─ docker-entrypoint.sh
    ├─ .gitignore
    └─ README.md

    Here’s a Dockerfile for BinPastes:

    FROM php:8.1-fpm-alpine
    # Install required dependencies
    RUN apk add --no-cache \
    nginx \
    curl \
    git \
    composer \
    sqlite \
    php81-sqlite3 \
    php81-pdo \
    php81-pdo_sqlite \
    php81-json \
    php81-mbstring \
    php81-openssl \
    supervisor
    # Set working directory
    WORKDIR /var/www/html
    # Clone BinPastes repository
    RUN git clone https://github.com/UprightPath/BinPastes.git . && \
    composer install --no-dev --optimize-autoloader
    # Create necessary directories
    RUN mkdir -p /var/www/html/storage \
    /var/www/html/public/pastes \
    /var/www/html/logs && \
    chown -R www-data:www-data /var/www/html
    # Copy nginx configuration
    COPY nginx.conf /etc/nginx/http.d/default.conf
    # Copy entrypoint script
    COPY docker-entrypoint.sh /
    RUN chmod +x /docker-entrypoint.sh
    # Expose port
    EXPOSE 8080
    # Health check
    HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
    CMD curl -f http://localhost:8080/ || exit 1
    # Run entrypoint
    ENTRYPOINT ["/docker-entrypoint.sh"]
    CMD ["start"]

    Create a docker-entrypoint.sh file:

    #!/bin/sh
    # Set proper permissions
    chown -R www-data:www-data /var/www/html
    # Initialize application
    if [ ! -f /var/www/html/storage/initialized ]; then
    echo "Initializing BinPastes..."
    php artisan key:generate --force 2>/dev/null || true
    php artisan migrate --force 2>/dev/null || true
    touch /var/www/html/storage/initialized
    fi
    if [ "$1" = "start" ]; then
    # Start PHP-FPM
    php-fpm &
    # Start Nginx
    nginx -g "daemon off;"
    else
    exec "$@"
    fi

    Create an nginx.conf file:

    server {
    listen 8080;
    server_name _;
    root /var/www/html/public;
    index index.php index.html;
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
    gzip_min_length 1000;
    gzip_vary on;
    # Static files caching
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|webp)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
    }
    # PHP handling
    location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    }
    # Prevent access to hidden files
    location ~ /\. {
    deny all;
    }
    # Prevent direct access to storage
    location ~ /storage/ {
    deny all;
    }
    # URL rewriting for pretty URLs
    location / {
    try_files $uri $uri/ /index.php?$query_string;
    }
    }

    Create a .env.example file:

    Terminal window
    # Application Configuration
    APP_NAME="BinPastes"
    APP_URL=https://yourdomain.com
    APP_ENV=production
    APP_DEBUG=false
    APP_KEY=base64:YOUR_APP_KEY_HERE
    # Database Configuration (if using database)
    DB_CONNECTION=sqlite
    DB_DATABASE=/var/www/html/storage/database.sqlite
    # Session Configuration
    SESSION_DRIVER=file
    SESSION_LIFETIME=120
    # Paste Configuration
    PASTE_STORAGE_PATH=/var/www/html/storage/pastes
    PASTE_MAX_SIZE=1048576
    PASTE_EXPIRATION_DEFAULT=604800
    PASTE_EXPIRATION_MAX=2592000
    # Features
    ENABLE_SYNTAX_HIGHLIGHTING=true
    ENABLE_REGISTRATION=false
    ENABLE_DOWNLOAD=true
    ENABLE_API=true
    # Security
    REQUIRE_HTTPS=true
    ALLOW_PUBLIC_PASTES=true

    Commit and push to your GitHub repository:

    Terminal window
    git init
    git add .
    git commit -m "Initial BinPastes deployment"
    git remote add origin https://github.com/yourusername/binpastes-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 these essential environment variables in your Klutch.sh dashboard:

    VariableDescriptionExample
    APP_NAMEApplication nameBinPastes
    APP_URLYour application domainhttps://pastes.example.com
    APP_ENVEnvironment (production or development)production
    APP_DEBUGDebug mode (false for production)false
    APP_KEYLaravel application key (base64 encoded)base64:randomstring
    DB_CONNECTIONDatabase typesqlite
    SESSION_DRIVERSession storage driverfile
    PASTE_STORAGE_PATHPath to store pastes/var/www/html/storage/pastes
    PASTE_MAX_SIZEMaximum paste size in bytes1048576
    PASTE_EXPIRATION_DEFAULTDefault expiration in seconds604800
    ENABLE_SYNTAX_HIGHLIGHTINGEnable code syntax highlightingtrue
    ENABLE_REGISTRATIONAllow user registrationfalse
    ENABLE_DOWNLOADEnable paste downloadstrue
    ENABLE_APIEnable API accesstrue
    ALLOW_PUBLIC_PASTESAllow public pastestrue
  5. Configure Persistent Storage

    BinPastes requires persistent storage for pastes and application data. Add persistent volumes:

    Mount PathDescriptionRecommended Size
    /var/www/html/storagePastes and application data100GB+
    /var/www/html/logsApplication logs10GB

    In the Klutch.sh dashboard:

    • Navigate to your app settings
    • Go to the “Volumes” section
    • Click “Add Volume” for each mount path
    • Set mount paths and sizes as specified above
  6. Set Network Configuration

    Configure your app’s network settings:

    • Select traffic type: HTTP (BinPastes uses standard web ports)
    • Recommended internal port: 8080 (as specified in Dockerfile)
    • Klutch.sh will automatically handle HTTPS termination via reverse proxy
    • Ensure ports 80 and 443 are accessible from your domain
  7. Configure Custom Domain

    BinPastes works best with a custom domain:

    • Navigate to your app’s “Domains” section in Klutch.sh
    • Click “Add Custom Domain”
    • Enter your domain (e.g., pastes.yourdomain.com)
    • Configure DNS with a CNAME record to point to your Klutch.sh app
    • Update APP_URL environment variable to match your domain
    • Klutch.sh will automatically provision SSL certificates
  8. Deploy Your App

    • Review all settings and environment variables
    • Click “Deploy”
    • Klutch.sh will build the Docker image and start your BinPastes instance
    • Wait for the deployment to complete (typically 5-10 minutes)
    • Access your BinPastes instance at your configured domain
    • Begin creating and sharing pastes

Initial Setup and Configuration

After deployment completes, access your BinPastes instance to begin using it.

Accessing BinPastes

Navigate to your app’s domain: https://yourdomain.com

You’ll see the BinPastes interface with options to:

  • Create a new paste
  • View recent pastes
  • Search existing pastes
  • Access settings and configuration

Creating Your First Paste

  1. Click “Create New Paste” or navigate to the home page
  2. Enter your code or text in the editor
  3. Select the language for syntax highlighting
  4. Set paste expiration (optional):
    • Never
    • 1 hour
    • 1 day
    • 1 week
    • 1 month
  5. Toggle privacy settings:
    • Public (anyone can view)
    • Private (requires unique URL)
  6. Click “Create Paste”
  7. Share the generated URL with others

Sharing Pastes

Share pastes through various methods:

  • Copy the unique URL and share directly
  • Download paste as plain text file
  • Get API endpoint for programmatic access
  • Generate QR code for mobile sharing

Searching and Managing Pastes

  1. Use the search function to find previous pastes
  2. View paste metadata (created date, language, size)
  3. Edit existing pastes (if owner)
  4. Delete pastes (if owner)
  5. Download pastes as files

Environment Variable Examples

Basic Configuration

Terminal window
APP_NAME="BinPastes"
APP_URL=https://pastes.yourdomain.com
APP_ENV=production
APP_DEBUG=false
APP_KEY=base64:YOUR_BASE64_ENCODED_KEY
DB_CONNECTION=sqlite
SESSION_DRIVER=file
ENABLE_SYNTAX_HIGHLIGHTING=true
ENABLE_REGISTRATION=false
ENABLE_DOWNLOAD=true
ENABLE_API=true
ALLOW_PUBLIC_PASTES=true

Advanced Configuration

Terminal window
# Application Settings
APP_NAME="BinPastes"
APP_URL=https://pastes.yourdomain.com
APP_ENV=production
APP_DEBUG=false
APP_KEY=base64:YOUR_BASE64_ENCODED_KEY
APP_TIMEZONE=UTC
# Database Configuration
DB_CONNECTION=sqlite
DB_DATABASE=/var/www/html/storage/database.sqlite
# Session Configuration
SESSION_DRIVER=file
SESSION_LIFETIME=120
SESSION_SECURE=true
SESSION_HTTP_ONLY=true
# Paste Configuration
PASTE_STORAGE_PATH=/var/www/html/storage/pastes
PASTE_MAX_SIZE=1048576
PASTE_EXPIRATION_DEFAULT=604800
PASTE_EXPIRATION_MAX=2592000
PASTE_CLEANUP_ENABLED=true
PASTE_CLEANUP_SCHEDULE=daily
# Feature Configuration
ENABLE_SYNTAX_HIGHLIGHTING=true
ENABLE_REGISTRATION=false
ENABLE_DOWNLOAD=true
ENABLE_API=true
ENABLE_API_RATE_LIMITING=true
ALLOW_PUBLIC_PASTES=true
REQUIRE_AUTHENTICATION=false
# Security
REQUIRE_HTTPS=true
CORS_ALLOWED_ORIGINS=https://yourdomain.com
PASTE_DELETE_CONFIRM=true
RATE_LIMIT_ENABLED=true
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_PERIOD=3600

Sample Code and Getting Started

cURL - Creating Pastes via API

Terminal window
# Create a simple text paste
curl -X POST https://pastes.yourdomain.com/api/pastes \
-H "Content-Type: application/json" \
-d '{
"content": "Hello, World!",
"language": "text",
"expiration": 604800,
"is_private": false
}'
# Create a code paste with syntax highlighting
curl -X POST https://pastes.yourdomain.com/api/pastes \
-H "Content-Type: application/json" \
-d '{
"content": "function hello() {\n console.log(\"Hello, World!\");\n}",
"language": "javascript",
"expiration": 2592000,
"is_private": false,
"title": "Hello World Function"
}'
# Retrieve a paste by ID
curl -X GET https://pastes.yourdomain.com/api/pastes/{paste_id} \
-H "Accept: application/json"
# Delete a paste
curl -X DELETE https://pastes.yourdomain.com/api/pastes/{paste_id}
# Get raw paste content
curl https://pastes.yourdomain.com/api/pastes/{paste_id}/raw

JavaScript - Creating Pastes Programmatically

const API_URL = 'https://pastes.yourdomain.com/api';
// Create a new paste
async function createPaste(content, language = 'text', options = {}) {
try {
const response = await fetch(`${API_URL}/pastes`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: content,
language: language,
expiration: options.expiration || 604800,
is_private: options.isPrivate || false,
title: options.title || '',
tags: options.tags || []
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('Paste created:', data);
return data;
} catch (error) {
console.error('Error creating paste:', error);
throw error;
}
}
// Retrieve a paste
async function getPaste(pasteId) {
try {
const response = await fetch(`${API_URL}/pastes/${pasteId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('Paste retrieved:', data);
return data;
} catch (error) {
console.error('Error retrieving paste:', error);
throw error;
}
}
// Get raw paste content
async function getRawPaste(pasteId) {
try {
const response = await fetch(`${API_URL}/pastes/${pasteId}/raw`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const content = await response.text();
console.log('Paste content:', content);
return content;
} catch (error) {
console.error('Error retrieving raw paste:', error);
throw error;
}
}
// Delete a paste
async function deletePaste(pasteId) {
try {
const response = await fetch(`${API_URL}/pastes/${pasteId}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
console.log('Paste deleted successfully');
} catch (error) {
console.error('Error deleting paste:', error);
throw error;
}
}
// Usage examples
(async () => {
// Create a paste
const newPaste = await createPaste(
'console.log("Hello, BinPastes!");',
'javascript',
{
title: 'Hello World',
isPrivate: false,
expiration: 2592000 // 30 days
}
);
// Retrieve the paste
const paste = await getPaste(newPaste.id);
// Get raw content
const rawContent = await getRawPaste(newPaste.id);
// Delete the paste
// await deletePaste(newPaste.id);
})();

Python - Pastebin API Client

import requests
import json
from datetime import datetime, timedelta
class BinPastesClient:
def __init__(self, base_url):
self.base_url = base_url
self.api_url = f'{base_url}/api'
self.headers = {'Content-Type': 'application/json'}
def create_paste(self, content, language='text', expiration=None,
is_private=False, title='', tags=None):
"""Create a new paste"""
try:
payload = {
'content': content,
'language': language,
'expiration': expiration or 604800, # Default 7 days
'is_private': is_private,
'title': title,
'tags': tags or []
}
response = requests.post(
f'{self.api_url}/pastes',
headers=self.headers,
json=payload
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error creating paste: {e}")
return None
def get_paste(self, paste_id):
"""Retrieve a paste by ID"""
try:
response = requests.get(
f'{self.api_url}/pastes/{paste_id}',
headers=self.headers
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error retrieving paste: {e}")
return None
def get_raw_paste(self, paste_id):
"""Get raw paste content"""
try:
response = requests.get(
f'{self.api_url}/pastes/{paste_id}/raw'
)
response.raise_for_status()
return response.text
except requests.exceptions.RequestException as e:
print(f"Error retrieving raw paste: {e}")
return None
def delete_paste(self, paste_id):
"""Delete a paste"""
try:
response = requests.delete(
f'{self.api_url}/pastes/{paste_id}',
headers=self.headers
)
response.raise_for_status()
return True
except requests.exceptions.RequestException as e:
print(f"Error deleting paste: {e}")
return False
def search_pastes(self, query, limit=10):
"""Search for pastes"""
try:
response = requests.get(
f'{self.api_url}/pastes/search',
headers=self.headers,
params={'q': query, 'limit': limit}
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error searching pastes: {e}")
return None
def get_languages(self):
"""Get list of supported languages"""
try:
response = requests.get(
f'{self.api_url}/languages',
headers=self.headers
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error retrieving languages: {e}")
return None
# Usage example
if __name__ == "__main__":
client = BinPastesClient('https://pastes.yourdomain.com')
# Create a paste
code_snippet = '''def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
result = fibonacci(10)
print(f"Fibonacci(10) = {result}")
'''
new_paste = client.create_paste(
content=code_snippet,
language='python',
title='Fibonacci Function',
expiration=2592000, # 30 days
is_private=False
)
if new_paste:
print(f"Paste created: {new_paste}")
paste_id = new_paste['id']
# Retrieve the paste
paste = client.get_paste(paste_id)
print(f"Retrieved paste: {paste}")
# Get raw content
raw_content = client.get_raw_paste(paste_id)
print(f"Raw content:\n{raw_content}")
# Search for pastes
results = client.search_pastes('fibonacci', limit=5)
print(f"Search results: {results}")
# Get supported languages
languages = client.get_languages()
print(f"Supported languages: {languages}")
# Delete the paste
# deleted = client.delete_paste(paste_id)
# print(f"Paste deleted: {deleted}")

Bash - Script Integration

#!/bin/bash
# BinPastes Command Line Interface
# Usage: ./binpastes.sh create|retrieve|delete [options]
API_URL="${BINPASTES_URL:-https://pastes.yourdomain.com/api}"
# Create a paste from file
create_from_file() {
local file=$1
local language=${2:-text}
local expiration=${3:-604800}
if [ ! -f "$file" ]; then
echo "Error: File not found: $file"
exit 1
fi
local content=$(cat "$file")
local title=$(basename "$file")
curl -s -X POST "$API_URL/pastes" \
-H "Content-Type: application/json" \
-d "{
\"content\": \"$(echo "$content" | sed 's/"/\\"/g')\",
\"language\": \"$language\",
\"title\": \"$title\",
\"expiration\": $expiration
}"
}
# Create a paste from stdin
create_from_stdin() {
local language=${1:-text}
local expiration=${2:-604800}
read -r -d '' content
curl -s -X POST "$API_URL/pastes" \
-H "Content-Type: application/json" \
-d "{
\"content\": \"$(echo "$content" | sed 's/"/\\"/g')\",
\"language\": \"$language\",
\"expiration\": $expiration
}"
}
# Retrieve a paste
retrieve_paste() {
local paste_id=$1
local format=${2:-json}
if [ "$format" = "raw" ]; then
curl -s -X GET "$API_URL/pastes/$paste_id/raw"
else
curl -s -X GET "$API_URL/pastes/$paste_id"
fi
}
# Delete a paste
delete_paste() {
local paste_id=$1
curl -s -X DELETE "$API_URL/pastes/$paste_id"
}
# Main command handler
case "$1" in
create-file)
create_from_file "$2" "$3" "$4"
;;
create-stdin)
create_from_stdin "$2" "$3"
;;
retrieve|get)
retrieve_paste "$2" "$3"
;;
delete|remove)
delete_paste "$2"
;;
*)
echo "Usage: $0 {create-file|create-stdin|retrieve|delete} [options]"
echo ""
echo "Commands:"
echo " create-file FILE [LANGUAGE] [EXPIRATION] Create paste from file"
echo " create-stdin [LANGUAGE] [EXPIRATION] Create paste from stdin"
echo " retrieve ID [FORMAT] Retrieve paste (json|raw)"
echo " delete ID Delete paste"
echo ""
echo "Examples:"
echo " $0 create-file script.js javascript 2592000"
echo " cat config.txt | $0 create-stdin text 604800"
echo " $0 retrieve abc123"
echo " $0 delete abc123"
exit 1
;;
esac

Docker Compose for Local Development

For local testing before deploying to Klutch.sh:

version: '3.8'
services:
binpastes:
build: .
container_name: binpastes-app
environment:
APP_NAME: BinPastes
APP_URL: http://localhost:8080
APP_ENV: development
APP_DEBUG: "true"
APP_KEY: base64:GENERATEANEWKEYHERE
DB_CONNECTION: sqlite
SESSION_DRIVER: file
ENABLE_SYNTAX_HIGHLIGHTING: "true"
ENABLE_REGISTRATION: "false"
ENABLE_API: "true"
ports:
- "8080:8080"
volumes:
- ./:/var/www/html
- ./storage:/var/www/html/storage
- ./logs:/var/www/html/logs
restart: unless-stopped

To run locally:

Terminal window
# Generate app key if needed
php artisan key:generate
# Start containers
docker-compose up -d
# View logs
docker-compose logs -f binpastes

Access BinPastes at http://localhost:8080

Syntax Highlighting Configuration

Supported Languages

BinPastes supports syntax highlighting for 100+ languages including:

  • Web: HTML, CSS, JavaScript, TypeScript, PHP, Python, Ruby, Java, C++, Go, Rust
  • Scripting: Bash, Zsh, PowerShell, Perl, Lua, Python
  • Configuration: JSON, YAML, TOML, XML, INI, Nginx, Apache
  • Database: SQL, MySQL, PostgreSQL, MongoDB
  • Markup: Markdown, LaTeX, AsciiDoc
  • And many more…

Customizing Themes

Customize syntax highlighting appearance:

  1. Navigate to settings
  2. Select preferred theme:
    • Light themes: GitHub, Atom, Solarized Light
    • Dark themes: Monokai, Dracula, Solarized Dark
  3. Preview changes
  4. Apply theme globally

Paste Management Features

Expiration Settings

Control paste lifetime:

  • Never: Paste remains indefinitely
  • Hourly: Expires after 1 hour
  • Daily: Expires after 1 day
  • Weekly: Expires after 7 days
  • Monthly: Expires after 30 days
  • Custom: Set specific expiration

Privacy Controls

Configure paste visibility:

  • Public: Anyone with URL can view
  • Private: Only owner can view
  • Authentication Required: Requires login to view
  • Password Protected: Requires password to view

Paste Metadata

Each paste includes:

  • Unique ID and URL
  • Creation timestamp
  • Language/syntax highlighting
  • File size
  • Expiration time
  • View count
  • Optional title and description

API Features

REST API Endpoints

BinPastes provides comprehensive API:

POST /api/pastes Create new paste
GET /api/pastes/{id} Retrieve paste
GET /api/pastes/{id}/raw Get raw content
DELETE /api/pastes/{id} Delete paste
GET /api/pastes/search Search pastes
GET /api/languages Get supported languages
GET /api/stats Get statistics

Rate Limiting

Protect your instance with rate limiting:

Terminal window
RATE_LIMIT_ENABLED=true
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_PERIOD=3600

Search and Organization

Search Functionality

Find pastes quickly:

  • Search by content keywords
  • Filter by language
  • Filter by date range
  • Filter by author
  • Sort results by relevance or date

Tagging System

Organize pastes with tags:

  • Add custom tags to pastes
  • Browse pastes by tag
  • Search by tag combinations
  • Manage tag hierarchy

Security Best Practices

Authentication and Access Control

  • Disable public registration if not needed: ENABLE_REGISTRATION=false
  • Require authentication for viewing: REQUIRE_AUTHENTICATION=true
  • Use private pastes for sensitive data
  • Implement password protection for sensitive pastes
  • Control API access with authentication tokens

Data Security

  • Always use HTTPS (automatic via Klutch.sh)
  • Configure security headers in nginx configuration
  • Set appropriate file permissions on storage directory
  • Regular backups of paste data
  • Implement data retention policies

Privacy Considerations

  • Review privacy policy for your instance
  • Inform users about data retention
  • Implement GDPR compliance if serving EU users
  • Log access to sensitive pastes
  • Monitor for abuse

Content Security

# In nginx.conf
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline';" always;

Backup and Recovery

Automated Backups

Regular backup of paste data:

#!/bin/bash
BACKUP_DIR="/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Backup storage directory
tar -czf $BACKUP_DIR/binpastes_data_$TIMESTAMP.tar.gz \
/var/www/html/storage/pastes
# Keep only last 30 days
find $BACKUP_DIR -name "binpastes_*" -mtime +30 -delete
echo "Backup completed: $TIMESTAMP"

Performance Optimization

Caching Configuration

Improve performance with caching:

Terminal window
CACHE_DRIVER=file
CACHE_TTL=3600

Database Optimization

For SQLite deployments, maintain database:

Terminal window
# Optimize database (run periodically)
sqlite3 /var/www/html/storage/database.sqlite "VACUUM;"
sqlite3 /var/www/html/storage/database.sqlite "ANALYZE;"

Static Asset Optimization

Nginx configuration handles:

  • Gzip compression for text content
  • Browser caching for static assets
  • Minification of CSS/JavaScript
  • Lazy loading of syntax highlighting

Monitoring and Maintenance

Health Monitoring

Monitor your BinPastes instance:

  • Check application logs regularly
  • Monitor disk space for paste storage
  • Track system performance
  • Monitor API usage and rate limiting

Regular Maintenance

Terminal window
# Clear expired pastes (if auto-cleanup disabled)
php artisan pastes:cleanup
# Clear application cache
php artisan cache:clear
# Optimize application
php artisan optimize

Troubleshooting

Common Issues and Solutions

Issue: Pastes not saving

Solutions:

  • Verify persistent volume is attached and writable
  • Check disk space availability
  • Verify permissions on /var/www/html/storage directory
  • Check application logs for errors

Issue: Slow paste creation or retrieval

Solutions:

  • Enable caching with CACHE_DRIVER=memory
  • Optimize database indexes
  • Check system resources (CPU, RAM, disk I/O)
  • Review application logs for performance issues

Issue: Syntax highlighting not working

Solutions:

  • Verify ENABLE_SYNTAX_HIGHLIGHTING=true
  • Check language selection is correct
  • Clear browser cache
  • Verify JavaScript is enabled in browser

Issue: API requests failing

Solutions:

  • Check ENABLE_API=true
  • Verify Content-Type headers are correct
  • Check rate limiting is not exceeded
  • Review CORS settings if using from different origin

Issue: Cannot create pastes

Solutions:

  • Verify MAX_PASTE_SIZE is appropriate
  • Check file permissions on storage directory
  • Verify database connection (if using database)
  • Check application logs for errors

Upgrading BinPastes

To update BinPastes to a newer version:

  1. Update your Dockerfile to latest version:

    RUN git clone https://github.com/UprightPath/BinPastes.git . && \
    git checkout latest-version
  2. Commit and push to GitHub

  3. Klutch.sh will automatically rebuild with the latest version

  4. Test updates in development first

  5. Backup paste data before upgrading

Use Cases

Individual Developers

  • Quickly share code snippets with team members
  • Store temporary code during development
  • Share configuration examples

Development Teams

  • Internal code sharing within organization
  • Collaborative debugging and problem-solving
  • Configuration management for projects

System Administrators

  • Share system logs and error messages
  • Document server configurations
  • Distribute patches and scripts
  • Incident response and troubleshooting

Documentation

  • Code examples in technical documentation
  • Configuration samples
  • Installation instructions
  • API request/response examples

Additional Resources

Conclusion

Deploying BinPastes on Klutch.sh provides you with a lightweight, secure, and self-hosted pastebin solution that puts you in complete control of your code sharing and data privacy. With persistent storage for all pastes, comprehensive syntax highlighting, API support, and a clean, intuitive interface, BinPastes enables developers and teams to share code efficiently while maintaining data ownership. Klutch.sh’s managed infrastructure ensures your pastebin is always available, secure, and performant, allowing you to focus on sharing knowledge and collaborating effectively.

Start hosting your own pastebin today by deploying BinPastes on Klutch.sh and enjoy the freedom of a private, self-hosted code sharing platform.