Docker Deployment

Docker Deployment

Relevant source files

Purpose and Scope

This document provides comprehensive guidance for deploying WSHawk using Docker containers. It covers the Docker image architecture, available registries, volume mounting for report persistence, network configuration, and security best practices. For general installation instructions including pip-based installation, see Installation Methods. For integrating WSHawk into CI/CD pipelines, see CI/CD Integration.


Docker Image Architecture

WSHawk uses a multi-stage Docker build to minimize final image size while maintaining full functionality. The build process consists of two stages: a builder stage for compilation and a runtime stage for execution.

Multi-Stage Build Process

Sources: Dockerfile L1-L66

Image Specifications

| Property | Value | Location | | --- | --- | --- | | Base Image | python:3.11-slim | Dockerfile L4 Dockerfile L23 | | Final Size | ~150MB | docs/DOCKER.md L198 | | Non-root User | wshawk (UID 1000) | Dockerfile L38-L41 | | Working Directory | /app | Dockerfile L7 Dockerfile L26 | | Entrypoint | wshawk | Dockerfile L52 | | Default Command | --help | Dockerfile L53 | | Health Check | wshawk --help every 30s | Dockerfile L48-L49 |

The builder stage installs build dependencies (gcc) and compiles Python packages Dockerfile L10-L20

The runtime stage copies only the compiled packages and binaries from the builder, excluding build tools Dockerfile L34-L35

This reduces attack surface and image size.

Sources: Dockerfile L1-L66

docs/DOCKER.md L196-L201

Environment Configuration

The image sets two critical environment variables for production deployment:

These settings ensure real-time logging output and prevent unnecessary file writes in the container filesystem Dockerfile L44-L45

Sources: Dockerfile L44-L45


Image Availability and Tagging

WSHawk Docker images are published to two registries through automated GitHub Actions workflows:

Registry Locations

| Registry | Image Path | Authentication | | --- | --- | --- | | Docker Hub | docker.io/rothackers/wshawk | Public (no auth required) | | GitHub Container Registry | ghcr.io/noobforanonymous/wshawk | Public (GITHUB_TOKEN for pushes) |

Sources: .github/workflows/docker-build.yml L15-L16

.github/workflows/ghcr-publish.yml L12-L13

Tag Strategy

The automated build pipeline generates semantic version tags following this pattern:

Sources: .github/workflows/docker-build.yml L44-L50

.github/workflows/ghcr-publish.yml L38-L41

Version tags are extracted using docker/metadata-action@v5 with patterns for semantic versioning .github/workflows/docker-build.yml L39-L50

This allows users to pin specific versions or track major/minor releases.

Multi-Architecture Support

Docker Hub images support both linux/amd64 and linux/arm64 platforms through buildx multi-platform builds .github/workflows/docker-build.yml L61

GHCR images currently target default platform only.

Sources: .github/workflows/docker-build.yml L61


Basic Usage Patterns

Pulling Images

Sources: docs/DOCKER.md L7-L9

CLI Command Execution

All four WSHawk CLI commands are available in the container:

| Command | Usage | Description | | --- | --- | --- | | wshawk | Default entrypoint | Quick scan mode | | wshawk-interactive | Requires -it flags | Guided testing mode | | wshawk-advanced | Override entrypoint | Full control mode | | wshawk-defensive | Override entrypoint | Defensive validation mode |

Sources: Dockerfile L35

Dockerfile L52

Standard Scan

This executes wshawk ws://target.com inside the container Dockerfile L52

Sources: docs/DOCKER.md L14-L15

Interactive Mode

The -it flags allocate a pseudo-TTY for menu-driven interaction docs/DOCKER.md L21-L22

Sources: docs/DOCKER.md L21-L22

Defensive Validation

The wshawk-defensive binary is available in /usr/local/bin/ Dockerfile L35

Sources: docs/DOCKER.md L17-L18

Dockerfile L35

Advanced Scan

Sources: docs/DOCKER.md L24


Volume Mounting for Report Persistence

WSHawk generates timestamped HTML reports that are lost when containers are destroyed. Volume mounting persists reports to the host filesystem.

Report Generation Behavior

By default, reports are written to the container's working directory /app with filenames matching the pattern:

wshawk_report_YYYYMMDD_HHMMSS.html

Sources: Dockerfile L26

Host Directory Mounting

This mounts the host's ./reports directory to /app/reports in the container. Reports saved to /app/reports persist after container exit docs/DOCKER.md L57-L63

Sources: docs/DOCKER.md L57-L63

Permission Considerations

The container runs as UID 1000 (wshawk user) Dockerfile L38-L41

If the host user has a different UID, permission issues may occur when writing to mounted volumes.

Solution: Match Host UID

The --user flag overrides the default wshawk user docs/DOCKER.md L172-L174

Sources: Dockerfile L38-L41

docs/DOCKER.md L172-L174

Absolute Path Requirements

Some Docker configurations require absolute paths for volume mounts:

Sources: docs/DOCKER.md L189-L191


Network Modes

Docker network configuration affects WSHawk's ability to reach target WebSocket servers, particularly when scanning localhost or internal networks.

Network Mode Comparison

Sources: docs/DOCKER.md L67-L70

docs/DOCKER.md L177-L184

docs/DOCKER.md L139-L143

Host Network Mode

Use when scanning WebSocket servers on the host machine:

The container accesses the host's network stack directly docs/DOCKER.md L68-L70

This bypasses Docker's network isolation.

Sources: docs/DOCKER.md L68-L70

docs/DOCKER.md L179-L180

Bridge Network Mode (Default)

Suitable for scanning external targets:

The container runs on Docker's default bridge network. It cannot access localhost on the host docs/DOCKER.md L177-L184

Sources: docs/DOCKER.md L177-L184

Custom Bridge Networks

Enable DNS-based inter-container communication:

Containers on the same custom network can resolve each other by container name docs/DOCKER.md L140-L143

Sources: docs/DOCKER.md L139-L143


Docker Compose Deployment

Docker Compose provides declarative multi-container orchestration, useful for testing WSHawk against local vulnerable servers.

Compose File Architecture

Sources: docker-compose.yml L1-L36

Service Definitions

The docker-compose.yml defines two services:

wshawk Service

Sources: docker-compose.yml L4-L18

vulnerable-server Service

This service provides a test target for demonstration purposes docker-compose.yml L21-L31

Sources: docker-compose.yml L21-L31

Compose Workflow

The exec command runs commands in the already-running wshawk container docs/DOCKER.md L90-L98

Sources: docs/DOCKER.md L89-L98

docker-compose.yml L14

Network Configuration

The compose file creates a custom bridge network named wshawk-network docker-compose.yml L33-L35

However, the wshawk service uses network_mode: host docker-compose.yml L9

so it bypasses this custom network. The vulnerable-server service connects to wshawk-network docker-compose.yml L30-L31

Sources: docker-compose.yml L9

docker-compose.yml L30-L31

docker-compose.yml L33-L35


Security Best Practices

Non-Root User Execution

The WSHawk image runs as a non-root user by default Dockerfile L38-L41

:

This follows the principle of least privilege, preventing the container process from having root access Dockerfile L41

Sources: Dockerfile L38-L41

docs/DOCKER.md L212-L215

Version Pinning

Always use specific version tags in production:

Semantic version tags (2.0.5, 2.0, 2) are generated by GitHub Actions .github/workflows/docker-build.yml L47-L49

Sources: docs/DOCKER.md L207-L210

.github/workflows/docker-build.yml L47-L49

Read-Only Filesystem

Prevent filesystem modifications in the container:

Note: This requires /tmp to be writable. Mount a tmpfs if needed:

Sources: docs/DOCKER.md L217-L220

Resource Limits

Constrain CPU and memory usage:

This prevents denial-of-service attacks if scanning malicious targets docs/DOCKER.md L222-L225

Sources: docs/DOCKER.md L222-L225

Security Scanning

The image includes OpenContainers standard labels for automated security scanning Dockerfile L55-L66

:

These labels enable GitHub Container Registry vulnerability scanning.

Sources: Dockerfile L55-L66


Advanced Usage Patterns

Playwright Browser Integration

Playwright requires additional browser binaries not included in the default image:

The --playwright flag enables browser-based XSS verification docs/DOCKER.md L126-L131

Sources: docs/DOCKER.md L124-L131

Interactive Shell Access

Override the default entrypoint to access a shell:

The --entrypoint flag overrides the default wshawk entrypoint Dockerfile L52

docs/DOCKER.md L74-L81

Sources: docs/DOCKER.md L74-L81

Dockerfile L52

Custom Environment Variables

Pass environment variables for configuration:

Sources: docs/DOCKER.md L112-L118

CI/CD Integration Example

This workflow automatically scans WebSocket endpoints on every push docs/DOCKER.md L146-L163

Sources: docs/DOCKER.md L146-L163


Troubleshooting

Container Cannot Reach Target

Problem: docker run --rm rothackers/wshawk ws://localhost:8765 fails to connect.

Solution: Use host network mode:

Default bridge networking isolates container network from host docs/DOCKER.md L177-L184

Sources: docs/DOCKER.md L177-L184

Volume Mount Permission Denied

Problem: Reports fail to write with permission errors.

Solution: Run container as host user:

Container runs as UID 1000 by default Dockerfile L38

Sources: docs/DOCKER.md L169-L174

Dockerfile L38

Build Context Size Issues

The .dockerignore file excludes unnecessary files from the build context .dockerignore L1-L72

:

  • Python cache files (__pycache__/, *.pyc)
  • Virtual environments (venv/, env/)
  • Test artifacts (.pytest_cache/, .coverage)
  • Reports (*.html, reports/)
  • Git metadata (.git/)
  • Documentation (docs/, *.md except README.md)

This reduces build context size and build time.

Sources: .dockerignore L1-L72

Image Verification

Verify the image is correctly built:

The health check command wshawk --help is defined in Dockerfile L48-L49

Sources: Dockerfile L48-L49

.github/workflows/docker-build.yml L63-L67


Build Automation

Docker Hub Workflow

The .github/workflows/docker-build.yml workflow automates image building and publishing to Docker Hub .github/workflows/docker-build.yml L1-L68

:

Triggers:

  • Push to main branch
  • Git tags matching v*
  • Pull requests to main
  • Manual dispatch

Process:

  1. Checkout repository
  2. Setup Docker Buildx
  3. Login to Docker Hub (using DOCKER_USERNAME and DOCKER_PASSWORD secrets)
  4. Extract metadata and generate tags
  5. Build multi-platform image (amd64, arm64)
  6. Push to Docker Hub
  7. Test image with --help commands

Sources: .github/workflows/docker-build.yml L1-L68

GitHub Container Registry Workflow

The .github/workflows/ghcr-publish.yml workflow publishes to GHCR .github/workflows/ghcr-publish.yml L1-L50

:

Differences from Docker Hub:

  • Uses GITHUB_TOKEN for authentication (no additional secrets)
  • Publishes to ghcr.io/noobforanonymous/wshawk
  • Single platform (no multi-arch)
  • Only triggers on push to main or version tags

Sources: .github/workflows/ghcr-publish.yml L1-L50

Build Cache Strategy

Both workflows use GitHub Actions cache for faster builds:

This caches Docker layers between workflow runs .github/workflows/docker-build.yml L59-L60

Sources: .github/workflows/docker-build.yml L59-L60