Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,15 @@ SCAN_INTERVAL_SECONDS=3600

# Logging verbosity: DEBUG | INFO | WARNING | ERROR
LOG_LEVEL=INFO

# ── Docker Hub publish (CI use only — set as GitHub Actions secrets) ─────────
# These are NOT used at runtime. They are only consumed by the
# .github/workflows/docker.yml build-and-push workflow.
#
# Required GitHub repository secrets (Settings → Secrets → Actions):
# DOCKERHUB_USERNAME talesofthemoon
# DOCKERHUB_TOKEN Docker Hub access token (Account Settings → Security → New Access Token)
#
# Optional: pin a specific image tag when pulling via docker compose
# IMAGE_TAG=latest

104 changes: 104 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Docker — Build & Push

# Triggers:
# • Push to main → builds and pushes :latest + :<sha>
# • Version tag (v*) → builds and pushes :latest + :<semver> (e.g. v1.2.3 → 1.2.3)
# • Pull request against main → build-only (no push) for image validation
#
# Required GitHub repository secrets (Settings → Secrets → Actions):
# DOCKERHUB_USERNAME — your Docker Hub username (talesofthemoon)
# DOCKERHUB_TOKEN — Docker Hub access token (Account Settings → Security → New Access Token)

on:
push:
branches: [main]
tags: ["v*"]
pull_request:
branches: [main]

concurrency:
group: docker-${{ github.ref }}
cancel-in-progress: true

env:
IMAGE: talesofthemoon/networkcrawler

jobs:
build:
name: Build & Push
runs-on: ubuntu-latest

permissions:
contents: read
packages: write # kept for potential future GHCR mirror

steps:
# ── Checkout ────────────────────────────────────────────────────────────
- uses: actions/checkout@v4

# ── QEMU — multi-arch emulation (linux/amd64 + linux/arm64) ─────────────
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

# ── Buildx — multi-platform builder ─────────────────────────────────────
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# ── Authenticate to Docker Hub (skip on PR builds) ──────────────────────
- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

# ── Generate image tags and OCI labels ──────────────────────────────────
# Push events produce:
# main branch → :latest + :<short-sha>
# v1.2.3 tag → :latest + :1.2.3
- name: Generate Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
tags: |
# Always tag :latest on main / tag pushes
type=raw,value=latest,enable={{is_default_branch}}
# Short SHA for main-branch pushes (e.g. sha-abc1234)
type=sha,prefix=sha-,enable={{is_default_branch}}
# Semver tags: v1.2.3 → 1.2.3, 1.2, 1
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
labels: |
org.opencontainers.image.title=NetworkCrawler
org.opencontainers.image.description=LAN security posture scanner for home lab operators
org.opencontainers.image.vendor=talesofthemoon
org.opencontainers.image.licenses=MIT

# ── Build (and push on non-PR events) ───────────────────────────────────
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: docker/Dockerfile
# Build both amd64 (x86 Unraid servers) and arm64 (Pi / ARM NAS)
platforms: linux/amd64,linux/arm64
# Only push when this is NOT a pull_request event
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# Layer caching via GitHub Actions cache backend
cache-from: type=gha
cache-to: type=gha,mode=max

# ── Update Docker Hub repo description (main branch only) ───────────────
- name: Update Docker Hub description
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: peter-evans/dockerhub-description@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: ${{ env.IMAGE }}
short-description: "LAN security posture scanner for home lab operators"
readme-filepath: ./README.md
5 changes: 4 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ FROM python:3.11-slim AS production

LABEL org.opencontainers.image.title="NetworkCrawler" \
org.opencontainers.image.description="LAN security posture scanner for home lab operators" \
org.opencontainers.image.source="https://github.com/reloadfast/NetworkCrawler"
org.opencontainers.image.source="https://github.com/reloadfast/NetworkCrawler" \
org.opencontainers.image.url="https://hub.docker.com/r/talesofthemoon/networkcrawler" \
org.opencontainers.image.vendor="talesofthemoon" \
org.opencontainers.image.licenses="MIT"

# Install system-level scanning tools
RUN apt-get update \
Expand Down
17 changes: 13 additions & 4 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,23 @@ version: "3.9"
# │ cap_add: [NET_RAW] │
# │ Grants raw socket access for arp-scan and nmap without running as root. │
# │ The container still runs as uid 1000 (non-root, set in Dockerfile). │
# │ │
# │ IMAGE │
# │ By default pulls talesofthemoon/networkcrawler:latest from Docker Hub. │
# │ To build locally instead: │
# │ docker compose -f docker/docker-compose.yml build │
# │ or set IMAGE_TAG env var to a specific digest/sha tag. │
# └─────────────────────────────────────────────────────────────────────────────┘

services:
networkcrawler:
build:
context: ..
dockerfile: docker/Dockerfile
image: talesofthemoon/networkcrawler:${IMAGE_TAG:-latest}
container_name: networkcrawler
image: networkcrawler:latest

# Uncomment the build block to build from source instead of pulling from Hub:
# build:
# context: ..
# dockerfile: docker/Dockerfile

# Host networking — required for ARP visibility across the LAN subnet
network_mode: host
Expand Down Expand Up @@ -54,3 +62,4 @@ services:
volumes:
networkcrawler_data:
driver: local

Loading