Docker HTTPS by default, smoke test improvements

Docker:
- HTTPS enabled by default (generates self-signed cert)
- Added docker-entrypoint.sh for SSL cert generation
- Gunicorn now starts with --certfile/--keyfile when HTTPS enabled
- Install curl/openssl in web container for healthcheck and certs
- Updated docs to reflect HTTPS default

Smoke Test:
- Moved from rpi/ to scripts/ (works for Pi, Docker, and dev)
- Updated header and examples
- Added to .gitignore exceptions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Aaron D. Lee
2026-01-07 23:45:44 -05:00
parent a00a154a1a
commit 455c6dfd01
7 changed files with 95 additions and 14 deletions

3
.gitignore vendored
View File

@@ -64,9 +64,10 @@ htmlcov/
# Output test files. # Output test files.
test_data/*.png test_data/*.png
# Dev scripts (local convenience scripts - except validate-release.sh) # Dev scripts (local convenience scripts - except these)
scripts/* scripts/*
!scripts/validate-release.sh !scripts/validate-release.sh
!scripts/smoke-test.sh
# Web UI auth database and SSL certs # Web UI auth database and SSL certs
instance/ instance/

View File

@@ -13,7 +13,7 @@ docker-compose ps
``` ```
Access: Access:
- **Web UI**: http://localhost:5000 - **Web UI**: https://localhost:5000 (HTTPS with self-signed cert)
- **REST API**: http://localhost:8000 - **REST API**: http://localhost:8000
## Services ## Services
@@ -36,9 +36,12 @@ STEGASOO_CHANNEL_KEY=XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX
# Web UI authentication (default: enabled) # Web UI authentication (default: enabled)
STEGASOO_AUTH_ENABLED=true STEGASOO_AUTH_ENABLED=true
# HTTPS support (default: disabled) # HTTPS support (default: enabled, generates self-signed cert)
STEGASOO_HTTPS_ENABLED=false STEGASOO_HTTPS_ENABLED=true
STEGASOO_HOSTNAME=localhost STEGASOO_HOSTNAME=localhost
# To disable HTTPS:
# STEGASOO_HTTPS_ENABLED=false
``` ```
### Volume Mounts ### Volume Mounts

View File

@@ -35,6 +35,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libzbar0 \ libzbar0 \
libjpeg-dev \ libjpeg-dev \
zlib1g-dev \ zlib1g-dev \
curl \
openssl \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Install ALL dependencies (slow path) # Install ALL dependencies (slow path)
@@ -57,6 +59,12 @@ FROM base AS web
WORKDIR /app WORKDIR /app
# Install runtime dependencies (curl for healthcheck, openssl for cert generation)
USER root
RUN apt-get update && apt-get install -y --no-install-recommends \
curl openssl \
&& rm -rf /var/lib/apt/lists/*
# Copy application files (this is all that rebuilds normally!) # Copy application files (this is all that rebuilds normally!)
COPY src/ src/ COPY src/ src/
COPY data/ data/ COPY data/ data/
@@ -66,6 +74,10 @@ COPY frontends/web/ frontends/web/
# temp_files is for multi-worker temp file sharing # temp_files is for multi-worker temp file sharing
RUN mkdir -p /tmp/stego_uploads /app/frontends/web/instance /app/frontends/web/certs /app/frontends/web/temp_files RUN mkdir -p /tmp/stego_uploads /app/frontends/web/instance /app/frontends/web/certs /app/frontends/web/temp_files
# Copy and set up entrypoint (before switching to non-root user)
COPY frontends/web/docker-entrypoint.sh /app/frontends/web/
RUN chmod +x /app/frontends/web/docker-entrypoint.sh
# Create non-root user # Create non-root user
RUN useradd -m -u 1000 stego && chown -R stego:stego /app /tmp/stego_uploads RUN useradd -m -u 1000 stego && chown -R stego:stego /app /tmp/stego_uploads
USER stego USER stego
@@ -77,12 +89,12 @@ ENV PYTHONPATH=/app/src
EXPOSE 5000 EXPOSE 5000
# Health check # Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:5000/')" || exit 1 CMD curl -fsk https://localhost:5000/ || curl -fs http://localhost:5000/ || exit 1
# Run with gunicorn # Run with entrypoint (handles HTTPS/HTTP mode)
WORKDIR /app/frontends/web WORKDIR /app/frontends/web
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "--threads", "4", "--timeout", "120", "app:app"] ENTRYPOINT ["/app/frontends/web/docker-entrypoint.sh"]
# ============================================================================ # ============================================================================
# API stage - REST API # API stage - REST API

View File

@@ -105,12 +105,15 @@ ruff check src/ tests/ frontends/
## Docker ## Docker
```bash ```bash
# Quick start # Quick start (HTTPS enabled by default)
docker-compose up -d docker-compose up -d
# Access # Access
# Web UI: http://localhost:5000 # Web UI: https://localhost:5000 (self-signed cert)
# REST API: http://localhost:8000 # REST API: http://localhost:8000
# Disable HTTPS if needed:
STEGASOO_HTTPS_ENABLED=false docker-compose up -d
``` ```
See [DOCKER.md](DOCKER.md) for full documentation. See [DOCKER.md](DOCKER.md) for full documentation.

View File

@@ -18,7 +18,9 @@ services:
FLASK_ENV: production FLASK_ENV: production
# Authentication (v4.0.2) # Authentication (v4.0.2)
STEGASOO_AUTH_ENABLED: ${STEGASOO_AUTH_ENABLED:-true} STEGASOO_AUTH_ENABLED: ${STEGASOO_AUTH_ENABLED:-true}
STEGASOO_HTTPS_ENABLED: ${STEGASOO_HTTPS_ENABLED:-false} # HTTPS enabled by default - generates self-signed cert if none provided
# To disable: STEGASOO_HTTPS_ENABLED=false docker-compose up
STEGASOO_HTTPS_ENABLED: ${STEGASOO_HTTPS_ENABLED:-true}
STEGASOO_HOSTNAME: ${STEGASOO_HOSTNAME:-localhost} STEGASOO_HOSTNAME: ${STEGASOO_HOSTNAME:-localhost}
volumes: volumes:
# Persist auth database and SSL certs (v4.0.2) # Persist auth database and SSL certs (v4.0.2)

View File

@@ -0,0 +1,55 @@
#!/bin/bash
#
# Docker entrypoint for Stegasoo Web UI
# Handles SSL certificate generation and gunicorn startup
#
set -e
CERT_DIR="/app/frontends/web/certs"
CERT_FILE="$CERT_DIR/cert.pem"
KEY_FILE="$CERT_DIR/key.pem"
HOSTNAME="${STEGASOO_HOSTNAME:-localhost}"
# Generate self-signed SSL certificate if HTTPS enabled and certs don't exist
generate_certs() {
if [ ! -f "$CERT_FILE" ] || [ ! -f "$KEY_FILE" ]; then
echo "Generating self-signed SSL certificate for $HOSTNAME..."
mkdir -p "$CERT_DIR"
openssl req -x509 -newkey rsa:2048 \
-keyout "$KEY_FILE" \
-out "$CERT_FILE" \
-sha256 -days 365 -nodes \
-subj "/CN=$HOSTNAME" \
-addext "subjectAltName=DNS:$HOSTNAME,DNS:localhost,IP:127.0.0.1" \
2>/dev/null
echo "SSL certificate generated."
else
echo "Using existing SSL certificates."
fi
}
# Start gunicorn with appropriate settings
if [ "${STEGASOO_HTTPS_ENABLED:-false}" = "true" ]; then
echo "HTTPS mode enabled"
generate_certs
exec gunicorn \
--bind 0.0.0.0:5000 \
--workers 2 \
--threads 4 \
--timeout 120 \
--certfile "$CERT_FILE" \
--keyfile "$KEY_FILE" \
app:app
else
echo "HTTP mode (HTTPS disabled)"
exec gunicorn \
--bind 0.0.0.0:5000 \
--workers 2 \
--threads 4 \
--timeout 120 \
app:app
fi

View File

@@ -1,10 +1,15 @@
#!/bin/bash #!/bin/bash
# #
# Stegasoo Pi Smoke Test # Stegasoo Smoke Test
# Tests all core functionality against a running Pi instance # Tests all core functionality against a running instance (Pi, Docker, or dev)
# #
# Usage: ./smoke-test.sh [host] [port] [user] [pass] # Usage: ./smoke-test.sh [host] [port] [user] [pass]
# #
# Examples:
# ./smoke-test.sh # Pi default (stegasoo.local:443)
# ./smoke-test.sh localhost 5000 # Docker default
# ./smoke-test.sh 192.168.1.100 5000 # Custom host
#
set -e set -e
@@ -296,7 +301,7 @@ test_tools() {
echo "" echo ""
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}" echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ Stegasoo Pi Smoke Test ║${NC}" echo -e "${CYAN}║ Stegasoo Smoke Test ${NC}"
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}" echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
echo "" echo ""
echo -e "Target: ${YELLOW}$BASE_URL${NC}" echo -e "Target: ${YELLOW}$BASE_URL${NC}"