fix: update deployment scripts and resolve backend API communication issue
This commit is contained in:
1 parent
ae023525ec
commit
441560a910
14 files changed
+61
-66
No files matched your search
@@ -1,4 +1,4 @@
|
||||
# StrixWebSSH - Browser-based SSH Client
|
||||
# WebSSH - Browser-based SSH Client
|
||||
|
||||
Multi-connection SSH client that runs in your browser with JWT authentication.
|
||||
|
||||
@@ -40,7 +40,7 @@ Default credentials:
|
||||
Set users via environment variable in `deployment/docker-compose.yml`:
|
||||
```yaml
|
||||
environment:
|
||||
- STRIXWEBSSH_USERS=user1:pass1,user2:pass2
|
||||
- WEBSSH_USERS=user1:pass1,user2:pass2
|
||||
```
|
||||
|
||||
### JWT Secret
|
||||
@@ -184,10 +184,10 @@ your-domain.com {
|
||||
|
||||
:8080 {
|
||||
handle_path /ws* {
|
||||
reverse_proxy strixwebssh:8081
|
||||
reverse_proxy webssh:8081
|
||||
}
|
||||
handle_path /api/* {
|
||||
reverse_proxy strixwebssh:8082
|
||||
reverse_proxy webssh:8082
|
||||
}
|
||||
route {
|
||||
root * /srv
|
||||
@@ -202,8 +202,8 @@ your-domain.com {
|
||||
Pre-built multi-arch images available:
|
||||
|
||||
```bash
|
||||
docker pull danaildr/strixwebssh:latest
|
||||
docker pull danaildr/strixwebssh:0.3.1
|
||||
docker pull danaildr/webssh:latest
|
||||
docker pull danaildr/webssh:0.4.0
|
||||
```
|
||||
|
||||
Supported architectures: `linux/amd64`, `linux/arm64`
|
||||
|
||||
@@ -44,8 +44,7 @@ RUN set -eux; \
|
||||
find /opt/venv -path '*/site-packages/pip*' -print0 | xargs -0 -r rm -rf || true; \
|
||||
find /opt/venv -path '*/site-packages/setuptools*' -print0 | xargs -0 -r rm -rf || true; \
|
||||
find /opt/venv -path '*/site-packages/wheel*' -print0 | xargs -0 -r rm -rf || true; \
|
||||
# Remove static metadata not required for runtime (careful: keep runtime metadata intact)
|
||||
find /opt/venv -type d -name '*.dist-info' -prune -print0 | xargs -0 -r rm -rf || true || true
|
||||
true
|
||||
|
||||
# Download Caddy binary for the build target (multi-arch aware)
|
||||
ARG TARGETARCH
|
||||
@@ -108,12 +107,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
COPY --from=builder /opt/venv /opt/venv
|
||||
ENV PATH="/opt/venv/bin:$PATH"
|
||||
|
||||
# Reinstall runtime dependencies explicitly in the final image to avoid missing package metadata
|
||||
COPY requirements.txt /tmp/requirements.txt
|
||||
RUN /opt/venv/bin/python -m ensurepip --upgrade && /opt/venv/bin/python -m pip install --no-cache-dir --prefer-binary -r /tmp/requirements.txt && rm -f /tmp/requirements.txt
|
||||
|
||||
# Security: Run as non-root user
|
||||
RUN groupadd -r strixwebssh && useradd -r -g strixwebssh strixwebssh
|
||||
RUN groupadd -r webssh && useradd -r -g webssh webssh
|
||||
|
||||
WORKDIR /app/src
|
||||
|
||||
@@ -122,7 +117,7 @@ COPY src/ /app/src/
|
||||
COPY deployment/docker-entrypoint.sh /usr/local/bin/
|
||||
|
||||
# Create .ssh directory for host keys
|
||||
RUN mkdir -p /app/src/.ssh && chown -R strixwebssh:strixwebssh /app/src
|
||||
RUN mkdir -p /app/src/.ssh && chown -R webssh:webssh /app/src
|
||||
|
||||
# Copy entrypoint
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
services:
|
||||
strixwebssh:
|
||||
webssh:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deployment/Dockerfile
|
||||
container_name: strixwebssh-backend
|
||||
container_name: webssh-backend
|
||||
restart: unless-stopped
|
||||
# StrixWebSSH runs internal services; integrated Caddy will expose port 8080 to the host
|
||||
# WebSSH runs internal services; integrated Caddy will expose port 8080 to the host
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
@@ -13,7 +13,7 @@ services:
|
||||
- PYTHONUNBUFFERED=1
|
||||
- LOG_LEVEL=INFO
|
||||
# Configure users: format is username:password,username2:password2
|
||||
- STRIXWEBSSH_USERS=admin:admin
|
||||
- WEBSSH_USERS=admin:admin
|
||||
# Max upload size (supports format like "100M" for 100MB or "50M" for 50MB)
|
||||
- MAX_UPLOAD_SIZE=30M
|
||||
# Session Recording Configuration
|
||||
@@ -34,9 +34,9 @@ services:
|
||||
cpus: '0.25'
|
||||
memory: 128M
|
||||
volumes:
|
||||
- strixwebssh_data:/data
|
||||
- webssh_data:/data
|
||||
# Optionally expose code to other services (read-only)
|
||||
# - ./:/srv/strixwebssh:ro
|
||||
# - ./:/srv/webssh:ro
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/"]
|
||||
interval: 30s
|
||||
@@ -46,4 +46,4 @@ services:
|
||||
|
||||
|
||||
volumes:
|
||||
strixwebssh_data:
|
||||
webssh_data:
|
||||
@@ -7,7 +7,7 @@ if [ "$(id -u)" != "0" ]; then
|
||||
exec python /app/src/run.py
|
||||
fi
|
||||
|
||||
# Create data directory with correct permissions for the StrixWebSSH user
|
||||
# Create data directory with correct permissions for the WebSSH user
|
||||
if [ ! -d "/data" ]; then
|
||||
echo "Creating /data directory..."
|
||||
mkdir -p /data
|
||||
@@ -17,14 +17,14 @@ echo "Current /data permissions:"
|
||||
ls -la /data || true
|
||||
ls -la / | grep data || true
|
||||
|
||||
# Ensure /data is writable and owned by the StrixWebSSH user (UID 999)
|
||||
# Ensure /data is writable and owned by the WebSSH user (UID 999)
|
||||
echo "Setting permissions on /data..."
|
||||
chmod 755 /data
|
||||
chown strixwebssh:strixwebssh /data
|
||||
chown webssh:webssh /data
|
||||
|
||||
# Check if chown worked
|
||||
if [ "$(stat -c %U /data)" != "strixwebssh" ]; then
|
||||
echo "WARNING: Could not change ownership of /data to strixwebssh"
|
||||
if [ "$(stat -c %U /data)" != "webssh" ]; then
|
||||
echo "WARNING: Could not change ownership of /data to webssh"
|
||||
echo "Current owner: $(stat -c %U /data)"
|
||||
echo "This may happen with bind mounts. Ensure host directory is writable."
|
||||
fi
|
||||
@@ -43,5 +43,5 @@ else
|
||||
echo "Caddy binary not found; continuing without reverse proxy"
|
||||
fi
|
||||
|
||||
# Start the application (run as the StrixWebSSH user)
|
||||
exec gosu strixwebssh python /app/src/run.py
|
||||
# Start the application (run as the WebSSH user)
|
||||
exec gosu webssh python /app/src/run.py
|
||||
@@ -7,7 +7,7 @@ set -e
|
||||
|
||||
# Configuration
|
||||
IMAGE_NAME="danaildr/webssh"
|
||||
VERSION="0.3.1"
|
||||
VERSION="0.4.0"
|
||||
PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
|
||||
|
||||
# Colors
|
||||
|
||||
@@ -129,7 +129,7 @@ https://github.com/danaildr/web-ssh
|
||||
## Tags
|
||||
|
||||
- `latest` - Most recent stable build
|
||||
- `0.3.1` - Version-specific tag (Grouped recordings + Bulk operations + Multi-arch support)
|
||||
- `0.4.0` - Version-specific tag (Grouped recordings + Bulk operations + Multi-arch support)
|
||||
- `0.1.9` - Previous version
|
||||
|
||||
Multi-arch: All tags support both `linux/amd64` and `linux/arm64`.
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
StrixWebSSH Backend - Modular SSH and SFTP server.
|
||||
WebSSH Backend - Modular SSH and SFTP server.
|
||||
|
||||
This file is a compatibility wrapper around the StrixWebSSH backend package.
|
||||
This file is a compatibility wrapper around the WebSSH backend package.
|
||||
The actual implementation has been split into modular components in webssh_backend/:
|
||||
|
||||
- config.py: Configuration and constants
|
||||
|
||||
+6
-6
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>StrixWebSSH - Help</title>
|
||||
<title>WebSSH - Help</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
@@ -193,7 +193,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>🔐 StrixWebSSH</h1>
|
||||
<h1>🔐 WebSSH</h1>
|
||||
<p>Secure SSH client that runs entirely in your browser</p>
|
||||
</div>
|
||||
|
||||
@@ -330,7 +330,7 @@
|
||||
<li><code>"500K"</code> - 500 kilobytes</li>
|
||||
</ul>
|
||||
|
||||
<p><strong>STRIXWEBSSH_USERS:</strong> Users in format <code>username:password,username2:password2</code></p>
|
||||
<p><strong>WEBSSH_USERS:</strong> Users in format <code>username:password,username2:password2</code></p>
|
||||
|
||||
<p><strong>JWT_SECRET:</strong> Secret key for JWT tokens (auto-generated if not set)</p>
|
||||
|
||||
@@ -339,12 +339,12 @@
|
||||
<p><strong>RECORDING_RETENTION_DAYS:</strong> Number of days to keep recordings (default: 30)</p>
|
||||
|
||||
<h3>🔒 Auto-Lock & Auto-Disconnect</h3>
|
||||
<p>StrixWebSSH can automatically lock sessions after a period of inactivity and require your StrixWebSSH password to unlock. Sessions can also be automatically disconnected after a longer period.</p>
|
||||
<p>WebSSH can automatically lock sessions after a period of inactivity and require your WebSSH password to unlock. Sessions can also be automatically disconnected after a longer period.</p>
|
||||
<ul>
|
||||
<li><strong>Lock after:</strong> Period of inactivity before locking (5, 15, 30, 60 minutes)</li>
|
||||
<li><strong>Disconnect after:</strong> Period of inactivity before disconnecting (30, 60 minutes, or never)</li>
|
||||
<li><strong>Configuration:</strong> Set per connection in the connection settings</li>
|
||||
<li><strong>Security:</strong> Lock requires StrixWebSSH password only (not SSH password)</li>
|
||||
<li><strong>Security:</strong> Lock requires WebSSH password only (not SSH password)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -381,7 +381,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<p>📧 <strong>Support:</strong> For more information and help, check the project documentation.</p>
|
||||
<p>🔄 <strong>Version:</strong> StrixWebSSH Multi-Connection Terminal v0.3.1</p>
|
||||
<p>🔄 <strong>Version:</strong> WebSSH Multi-Connection Terminal v0.4.0</p>
|
||||
<p>⚡ <strong>Technologies:</strong> Python, Paramiko, WebSockets, HTML5, CSS3, JavaScript</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
+7
-7
@@ -2,7 +2,7 @@
|
||||
<html lang="bg">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>StrixWebSSH - Multi-Connection Terminal</title>
|
||||
<title>WebSSH - Multi-Connection Terminal</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm/css/xterm.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm/lib/xterm.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit/lib/xterm-addon-fit.js"></script>
|
||||
@@ -18,7 +18,7 @@
|
||||
<!-- Login Modal -->
|
||||
<div class="modal-overlay active" id="loginModal">
|
||||
<div class="modal">
|
||||
<h3>StrixWebSSH Login</h3>
|
||||
<h3>WebSSH Login</h3>
|
||||
<form onsubmit="event.preventDefault(); login()">
|
||||
<div class="form-group">
|
||||
<label>Username</label>
|
||||
@@ -271,8 +271,8 @@
|
||||
<h3>Session Locked</h3>
|
||||
<p class="text-muted">Your session has been locked due to inactivity.</p>
|
||||
<div class="form-group" style="margin-top: 20px;">
|
||||
<label>Enter your StrixWebSSH password to unlock</label>
|
||||
<input type="password" id="unlockPassword" placeholder="StrixWebSSH password" onkeydown="if(event.key==='Enter')unlockSession()">
|
||||
<label>Enter your WebSSH password to unlock</label>
|
||||
<input type="password" id="unlockPassword" placeholder="WebSSH password" onkeydown="if(event.key==='Enter')unlockSession()">
|
||||
</div>
|
||||
<div id="unlockError" style="color: #ef4444; margin-top: 10px; display: none;">Incorrect password</div>
|
||||
<div class="modal-actions" style="margin-top: 20px;">
|
||||
@@ -319,8 +319,8 @@
|
||||
<h3>Session Locked</h3>
|
||||
<p class="text-muted">Your session has been locked due to inactivity.</p>
|
||||
<div class="form-group" style="margin-top: 20px;">
|
||||
<label>Enter your StrixWebSSH password to unlock</label>
|
||||
<input type="password" id="unlockPassword" placeholder="StrixWebSSH password" onkeydown="if(event.key==='Enter')unlockSession()">
|
||||
<label>Enter your WebSSH password to unlock</label>
|
||||
<input type="password" id="unlockPassword" placeholder="WebSSH password" onkeydown="if(event.key==='Enter')unlockSession()">
|
||||
</div>
|
||||
<div id="unlockError" style="color: #ef4444; margin-top: 10px; display: none;">Incorrect password</div>
|
||||
<div class="modal-actions" style="margin-top: 20px;">
|
||||
@@ -333,7 +333,7 @@
|
||||
<div class="modal-overlay" id="helpModal">
|
||||
<div class="modal" style="max-width: 90%; max-height: 90%; overflow-y: auto;">
|
||||
<div class="modal-header">
|
||||
<h3>📚 StrixWebSSH Help</h3>
|
||||
<h3>📚 WebSSH Help</h3>
|
||||
<button class="modal-close" onclick="hideHelp()">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* StrixWebSSH Client Styles */
|
||||
/* WebSSH Client Styles */
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
|
||||
+12
-12
@@ -1,9 +1,9 @@
|
||||
// StrixWebSSH Client JavaScript
|
||||
// WebSSH Client JavaScript
|
||||
|
||||
let connections = [];
|
||||
let currentConnectionId = null;
|
||||
let authToken = localStorage.getItem('strixwebssh_token');
|
||||
let currentUser = localStorage.getItem('strixwebssh_user');
|
||||
let authToken = localStorage.getItem('webssh_token');
|
||||
let currentUser = localStorage.getItem('webssh_user');
|
||||
let storedUsers = {}; // Will be loaded from /api/config
|
||||
let maxUploadSize = localStorage.getItem('maxUploadSize') ? parseInt(localStorage.getItem('maxUploadSize')) : 100 * 1024 * 1024;
|
||||
// Dynamically determine API URL based on current host (same origin since everything is in container)
|
||||
@@ -17,7 +17,7 @@ function getWsUrl() {
|
||||
return `${protocol}//${window.location.host}/ws`;
|
||||
}
|
||||
|
||||
const CONNECTIONS_KEY = 'strixwebssh_connections';
|
||||
const CONNECTIONS_KEY = 'webssh_connections';
|
||||
|
||||
// Load connections from server (with encrypted credentials)
|
||||
async function loadSavedConnections() {
|
||||
@@ -256,7 +256,7 @@ async function login() {
|
||||
|
||||
if (response.ok && data.token) {
|
||||
authToken = data.token;
|
||||
localStorage.setItem('strixwebssh_token', authToken);
|
||||
localStorage.setItem('webssh_token', authToken);
|
||||
document.getElementById('loginModal').classList.remove('active');
|
||||
document.getElementById('loggedInUser').textContent = data.username;
|
||||
term.writeln(`[Authenticated as ${data.username}]`);
|
||||
@@ -287,18 +287,18 @@ async function verifyToken() {
|
||||
loadSavedConnections(); // Load encrypted credentials from server
|
||||
setTimeout(loadConfig, 500); // Load configuration after successful token verification with delay
|
||||
} else {
|
||||
localStorage.removeItem('strixwebssh_token');
|
||||
localStorage.removeItem('webssh_token');
|
||||
authToken = null;
|
||||
}
|
||||
} catch (e) {
|
||||
localStorage.removeItem('strixwebssh_token');
|
||||
localStorage.removeItem('webssh_token');
|
||||
authToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
function logout() {
|
||||
localStorage.removeItem('strixwebssh_token');
|
||||
localStorage.removeItem('strixwebssh_api_url');
|
||||
localStorage.removeItem('webssh_token');
|
||||
localStorage.removeItem('webssh_api_url');
|
||||
authToken = null;
|
||||
location.reload();
|
||||
}
|
||||
@@ -773,7 +773,7 @@ function sendResizeForConnection(conn) {
|
||||
|
||||
// Initialize
|
||||
toggleAuthFields();
|
||||
term.writeln('StrixWebSSH Multi-Connection Client');
|
||||
term.writeln('WebSSH Multi-Connection Client');
|
||||
term.writeln('Click "+ New Connection" to get started');
|
||||
|
||||
// ============================================
|
||||
@@ -787,13 +787,13 @@ let sftpUploadQueue = [];
|
||||
let currentSftpConnection = null;
|
||||
// Load configuration from API
|
||||
function loadConfig() {
|
||||
console.log('loadConfig() called, token exists:', !!localStorage.getItem('strixwebssh_token'));
|
||||
console.log('loadConfig() called, token exists:', !!localStorage.getItem('webssh_token'));
|
||||
console.log('apiBaseUrl:', apiBaseUrl);
|
||||
|
||||
fetch(`${apiBaseUrl}/api/config`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('strixwebssh_token')}`
|
||||
'Authorization': `Bearer ${localStorage.getItem('webssh_token')}`
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
StrixWebSSH Backend Package - Modular SSH and SFTP server.
|
||||
WebSSH Backend Package - Modular SSH and SFTP server.
|
||||
|
||||
This package provides a modular SSH and SFTP server with the following components:
|
||||
|
||||
@@ -18,7 +18,7 @@ Usage:
|
||||
from webssh_backend.main import main
|
||||
asyncio.run(main())
|
||||
"""
|
||||
__version__ = "0.3.1"
|
||||
__version__ = "0.4.0"
|
||||
|
||||
# Note: Specific imports are intentionally NOT done at package level
|
||||
# to avoid loading all dependencies when only specific modules are needed.
|
||||
|
||||
@@ -169,9 +169,9 @@ def ensure_storage_dir():
|
||||
ensure_storage_dir()
|
||||
|
||||
# Resolve backend ports, falling back to the next free port when defaults are busy.
|
||||
WS_PORT = _resolve_port(("STRIXWEBSSH_WS_PORT", "WEBSSH_WS_PORT"), 8081)
|
||||
HTTP_PORT = _resolve_port(("STRIXWEBSSH_HTTP_PORT", "WEBSSH_HTTP_PORT"), 8082, reserved_ports={WS_PORT})
|
||||
SFTP_WS_PORT = _resolve_port(("STRIXWEBSSH_SFTP_PORT", "WEBSSH_SFTP_PORT"), 8083, reserved_ports={WS_PORT, HTTP_PORT})
|
||||
WS_PORT = _resolve_port(("WEBSSH_WS_PORT",), 8081)
|
||||
HTTP_PORT = _resolve_port(("WEBSSH_HTTP_PORT",), 8082, reserved_ports={WS_PORT})
|
||||
SFTP_WS_PORT = _resolve_port(("WEBSSH_SFTP_PORT",), 8083, reserved_ports={WS_PORT, HTTP_PORT})
|
||||
|
||||
try:
|
||||
with open(PORT_STATE_FILE, "w") as handle:
|
||||
@@ -186,9 +186,9 @@ except Exception as exc:
|
||||
logger.info(f"Resolved backend ports: ws={WS_PORT}, http={HTTP_PORT}, sftp={SFTP_WS_PORT}")
|
||||
|
||||
# User Configuration (username: password_hash)
|
||||
# Set via environment variable: STRIXWEBSSH_USERS=user1:pass1,user2:pass2
|
||||
# Set via environment variable: WEBSSH_USERS=user1:pass1,user2:pass2
|
||||
USERS = {}
|
||||
users_env = os.environ.get("STRIXWEBSSH_USERS", os.environ.get("WEBSSH_USERS", "admin:admin"))
|
||||
users_env = os.environ.get("WEBSSH_USERS", "admin:admin")
|
||||
for user_cred in users_env.split(","):
|
||||
if ":" in user_cred:
|
||||
u, p = user_cred.split(":", 1)
|
||||
|
||||
@@ -25,7 +25,7 @@ async def periodic_cleanup():
|
||||
|
||||
|
||||
async def main():
|
||||
logger.info(f"StrixWebSSH server starting on ws://{HOST}:{WS_PORT}")
|
||||
logger.info(f"WebSSH server starting on ws://{HOST}:{WS_PORT}")
|
||||
logger.info(f"SFTP server starting on ws://{HOST}:{SFTP_WS_PORT}")
|
||||
logger.info(f"Login API available on http://{HOST}:{HTTP_PORT}")
|
||||
|
||||
|
||||
Reference in new issue
Block a user