Docker
Deploy SSHIFT using Docker containers for easy installation and isolation.
Quick Start
Pull and Run
# Pull the image from GitHub Packages
docker pull ghcr.io/lethevimlet/sshift:latest
# Run the container
docker run -d \
--name sshift \
-p 8022:8022 \
ghcr.io/lethevimlet/sshift:latest
# Access the application
# Open https://localhost:8022 in your browser
Using Docker Compose
# Download docker-compose.yml
curl -O https://raw.githubusercontent.com/lethevimlet/sshift/main/docker/docker-compose.yml
# Start the service
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the service
docker-compose down
Configuration
Environment Variables
Configure SSHIFT using environment variables:
| Variable | Default | Description |
|---|---|---|
PORT |
8022 |
Port to bind the server |
BIND |
0.0.0.0 |
Address to bind (use 127.0.0.1 for localhost only) |
NODE_ENV |
production |
Node environment |
# Run with custom port
docker run -d \
-p 9000:8022 \
-e PORT=8022 \
ghcr.io/lethevimlet/sshift:latest
# Bind to localhost only
docker run -d \
-p 127.0.0.1:8022:8022 \
-e BIND=127.0.0.1 \
ghcr.io/lethevimlet/sshift:latest
Volumes
The Docker image uses volumes for persistent data:
/app/config: Configuration files (bookmarks, settings)/app/data: Data files (certificates, keys)
# Use named volumes
docker run -d \
-p 8022:8022 \
-v sshift-config:/app/config \
-v sshift-data:/app/data \
ghcr.io/lethevimlet/sshift:latest
# Use host directories
docker run -d \
-p 8022:8022 \
-v /path/to/config:/app/config \
-v /path/to/data:/app/data \
ghcr.io/lethevimlet/sshift:latest
Custom Configuration File
Mount a custom configuration file:
docker run -d \
-p 8022:8022 \
-v /path/to/config.json:/app/config.json:ro \
ghcr.io/lethevimlet/sshift:latest
Environment File
Create a .env file:
PORT=8022
BIND=0.0.0.0
NODE_ENV=production
Use with Docker Compose:
docker-compose --env-file .env up -d
Docker Compose
Complete docker-compose.yml example:
version: '3.8'
services:
sshift:
image: ghcr.io/lethevimlet/sshift:latest
container_name: sshift
ports:
- "${PORT:-8022}:8022"
environment:
- NODE_ENV=production
- PORT=8022
- BIND=0.0.0.0
volumes:
- sshift-config:/app/config
- sshift-data:/app/data
restart: unless-stopped
healthcheck:
test: ["CMD", "node", "-e", "require('https').get('https://localhost:8022/', {rejectUnauthorized: false}, (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
volumes:
sshift-config:
driver: local
sshift-data:
driver: local
Image Variants
Latest Version
docker pull ghcr.io/lethevimlet/sshift:latest
Specific Version
docker pull ghcr.io/lethevimlet/sshift:0.2.0
Version Tags
latest- Latest stable release0.2.0- Specific version0.2- Latest patch version for 0.2.x
Multi-Architecture Support
The Docker images are built for multiple architectures:
linux/amd64(x86_64)linux/arm64(ARM64/Apple Silicon)linux/arm/v7(ARM32/Raspberry Pi)
Docker automatically pulls the correct image for your architecture.
# Pull for your architecture (automatic)
docker pull ghcr.io/lethevimlet/sshift:latest
# Pull specific architecture
docker pull --platform linux/amd64 ghcr.io/lethevimlet/sshift:latest
docker pull --platform linux/arm64 ghcr.io/lethevimlet/sshift:latest
docker pull --platform linux/arm/v7 ghcr.io/lethevimlet/sshift:latest
Security Features
The Docker image includes several security features:
Non-Root User
The container runs as a non-root user (sshift:sshift):
# Verify user
docker exec sshift whoami
# Output: sshift
Read-Only Filesystem
The container uses a read-only filesystem with tmpfs for /tmp:
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
No New Privileges
Prevents privilege escalation:
security_opt:
- no-new-privileges:true
Health Checks
Built-in health checks monitor the application:
# Check container health
docker inspect --format='' sshift
# View health check logs
docker inspect --format='' sshift | jq
Reverse Proxy
Nginx
server {
listen 80;
server_name sshift.example.com;
location / {
proxy_pass https://localhost:8022;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Traefik
version: '3.8'
services:
sshift:
image: ghcr.io/lethevimlet/sshift:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.sshift.rule=Host(`sshift.example.com`)"
- "traefik.http.routers.sshift.entrypoints=web"
- "traefik.http.services.sshift.loadbalancer.server.port=8022"
Caddy
sshift.example.com {
reverse_proxy localhost:8022
}
Building from Source
Build Locally
# Clone the repository
git clone https://github.com/lethevimlet/sshift.git
cd sshift
# Build the image
docker build -f docker/Dockerfile -t sshift:local .
# Run the image
docker run -d -p 8022:8022 --name sshift sshift:local
Build Arguments
# Build with specific Node.js version
docker build --build-arg NODE_VERSION=22 -f docker/Dockerfile -t sshift:local .
Troubleshooting
Container Won’t Start
# Check logs
docker logs sshift
# Run interactively for debugging
docker run -it --rm -p 8022:8022 ghcr.io/lethevimlet/sshift:latest sh
# Check health status
docker inspect --format='' sshift
Permission Issues
# Fix volume permissions
docker exec -u root sshift chown -R sshift:sshift /app/config /app/data
Connection Refused
# Verify port binding
docker port sshift
# Check if port is already in use
netstat -tulpn | grep 8022
# Try different port
docker run -d -p 9000:8022 ghcr.io/lethevimlet/sshift:latest
Image Pull Errors
# For private repositories, authenticate first
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
# Pull the image
docker pull ghcr.io/lethevimlet/sshift:latest
Advanced Usage
Custom Port Mapping
# Map to different port
docker run -d \
-p 9000:8022 \
-e PORT=8022 \
ghcr.io/lethevimlet/sshift:latest
# Access at https://localhost:9000
Multiple Instances
# Instance 1
docker run -d \
--name sshift-1 \
-p 8022:8022 \
ghcr.io/lethevimlet/sshift:latest
# Instance 2
docker run -d \
--name sshift-2 \
-p 8023:8022 \
ghcr.io/lethevimlet/sshift:latest
Resource Limits
# Limit CPU and memory
docker run -d \
-p 8022:8022 \
--cpus="0.5" \
--memory="512m" \
ghcr.io/lethevimlet/sshift:latest
Network Isolation
# Create isolated network
docker network create sshift-network
# Run container in isolated network
docker run -d \
--name sshift \
--network sshift-network \
-p 8022:8022 \
ghcr.io/lethevimlet/sshift:latest
Updates
Update to Latest Version
# Pull latest image
docker pull ghcr.io/lethevimlet/sshift:latest
# Stop and remove old container
docker stop sshift
docker rm sshift
# Start new container
docker run -d \
--name sshift \
-p 8022:8022 \
-v sshift-config:/app/config \
-v sshift-data:/app/data \
ghcr.io/lethevimlet/sshift:latest
Update with Docker Compose
# Pull latest image
docker-compose pull
# Restart services
docker-compose up -d
Backup and Restore
Backup Volumes
# Backup config
docker run --rm \
-v sshift-config:/data \
-v $(pwd):/backup \
alpine tar czf /backup/sshift-config-backup.tar.gz -C /data .
# Backup data
docker run --rm \
-v sshift-data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/sshift-data-backup.tar.gz -C /data .
Restore Volumes
# Restore config
docker run --rm \
-v sshift-config:/data \
-v $(pwd):/backup \
alpine sh -c "cd /data && tar xzf /backup/sshift-config-backup.tar.gz"
# Restore data
docker run --rm \
-v sshift-data:/data \
-v $(pwd):/backup \
alpine sh -c "cd /data && tar xzf /backup/sshift-data-backup.tar.gz"
See Also
- Installation Guide - Other installation methods
- Configuration Guide - Detailed configuration options
- API Reference - API documentation