Skip to content
Draft
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
56 changes: 56 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copy to .env, replace every REPLACE_ value, then chmod 600 .env.

# Build and pinned images
FLEET_IMAGE_REPOSITORY=thinkhome/fleet
FLEET_IMAGE_TAG=local-b0223221
FLEET_REVISION=b0223221a4c68ebc13e12e26e5236f09207d748d
MYSQL_IMAGE=mysql:8.0.44
REDIS_IMAGE=redis:6.2
ALPINE_IMAGE=alpine:3.23.4
CADDY_IMAGE=caddy:2.11.4-alpine

# Secrets: generate with `openssl rand -hex 32` and `openssl rand -base64 32`.
MYSQL_ROOT_PASSWORD=REPLACE_WITH_RANDOM_HEX
MYSQL_PASSWORD=REPLACE_WITH_RANDOM_HEX
FLEET_SERVER_PRIVATE_KEY=REPLACE_WITH_RANDOM_BASE64

# Initial setup credentials. Fleet consumes these only during first-run setup.
FLEET_ADMIN_EMAIL=samuel.paluba@thinkhome.org
FLEET_ADMIN_PASSWORD=REPLACE_WITH_12_CHARS_NUMBER_AND_SYMBOL

# Public endpoint and reverse proxy
FLEET_DOMAIN=fleet.thinkhome.org
HTTP_PORT=80
HTTPS_PORT=443
FLEET_SERVER_ADDRESS=0.0.0.0:1337
FLEET_SERVER_TLS=false
FLEET_SERVER_TRUSTED_PROXIES=1

# MySQL
MYSQL_DATABASE=fleet
MYSQL_USER=fleet
MYSQL_MAX_ALLOWED_PACKET=536870912
MYSQL_BINLOG_EXPIRE_SECONDS=86400

# Fleet runtime
FLEET_LOGGING_JSON=true
FLEET_LOGGING_DEBUG=false
FLEET_SERVER_MAX_INSTALLER_SIZE=10GiB
FLEET_VULNERABILITIES_CURRENT_INSTANCE_CHECKS=yes
FLEET_VULNERABILITIES_DATABASES_PATH=/vulndb
FLEET_VULNERABILITIES_PERIODICITY=1h

# Optional Fleet Premium license and S3-compatible software storage
FLEET_LICENSE_KEY=
FLEET_S3_SOFTWARE_INSTALLERS_BUCKET=
FLEET_S3_SOFTWARE_INSTALLERS_PREFIX=
FLEET_S3_SOFTWARE_INSTALLERS_ACCESS_KEY_ID=
FLEET_S3_SOFTWARE_INSTALLERS_SECRET_ACCESS_KEY=
FLEET_S3_SOFTWARE_INSTALLERS_REGION=
FLEET_S3_SOFTWARE_INSTALLERS_ENDPOINT_URL=
FLEET_S3_SOFTWARE_INSTALLERS_FORCE_S3_PATH_STYLE=false

# MDM
# Windows WSTEP cert/key live in ./secrets/mdm and are mounted read-only.
# Android requires one-line/minified Google service-account JSON for Android Management API + Pub/Sub.
FLEET_MDM_ANDROID_GOOGLE_SERVICE_CREDENTIALS=
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,4 @@ custom-gcl

# dibble (the seed slinger) — binary lives next to source
tools/dibble/dibble
secrets/
4 changes: 4 additions & 0 deletions Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{$FLEET_DOMAIN} {
encode zstd gzip
reverse_proxy fleet:1337
}
24 changes: 24 additions & 0 deletions Dockerfile.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM node:24.10.0-bookworm-slim AS frontend
WORKDIR /src
COPY package.json yarn.lock .npmrc .yarnrc ./
RUN yarn install --frozen-lockfile --network-timeout 600000
COPY . .
RUN NODE_OPTIONS=--max-old-space-size=2048 NODE_ENV=production yarn run webpack --progress

FROM golang:1.26.5-trixie AS builder
RUN apt-get update && apt-get install -y --no-install-recommends musl-tools && rm -rf /var/lib/apt/lists/*
WORKDIR /src
COPY . .
COPY --from=frontend /src/assets /src/assets
COPY --from=frontend /src/frontend/templates/react.tmpl /src/frontend/templates/react.tmpl
RUN go run github.com/kevinburke/go-bindata/go-bindata -pkg=bindata -tags full -o=server/bindata/generated.go frontend/templates/ assets/... server/mail/templates
ARG FLEET_VERSION=local
ARG FLEET_REVISION=unknown
RUN CC=musl-gcc CGO_ENABLED=1 GOMAXPROCS=2 go build -tags full,fts5,netgo -trimpath -o /fleet -ldflags "-s -w -extldflags '-static' -X github.com/fleetdm/fleet/v4/server/version.version=${FLEET_VERSION} -X github.com/fleetdm/fleet/v4/server/version.revision=${FLEET_REVISION}" ./cmd/fleet

FROM alpine:3.23.4
RUN apk --no-cache add ca-certificates jq && apk --no-cache upgrade openssl libcrypto3 libssl3
RUN addgroup -S fleet && adduser -S fleet -G fleet
COPY --from=builder /fleet /usr/bin/fleet
USER fleet
CMD ["fleet", "serve"]
4 changes: 4 additions & 0 deletions Dockerfile.local.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.git
.env
build
node_modules
121 changes: 121 additions & 0 deletions docker-compose.local.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: fleet-local

volumes:
mysql:
redis:
data:
logs:
vulndb:
caddy_data:
caddy_config:

services:
mysql:
image: ${MYSQL_IMAGE:-mysql:8.0.44}
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?set MYSQL_ROOT_PASSWORD in .env}
MYSQL_DATABASE: ${MYSQL_DATABASE:-fleet}
MYSQL_USER: ${MYSQL_USER:-fleet}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:?set MYSQL_PASSWORD in .env}
volumes:
- mysql:/var/lib/mysql
command: ["mysqld", "--max_allowed_packet=${MYSQL_MAX_ALLOWED_PACKET:-536870912}", "--binlog-expire-logs-seconds=${MYSQL_BINLOG_EXPIRE_SECONDS:-86400}"]
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u$$MYSQL_USER -p$$MYSQL_PASSWORD --silent"]
interval: 10s
timeout: 5s
retries: 20
restart: unless-stopped

redis:
image: ${REDIS_IMAGE:-redis:6.2}
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 20
restart: unless-stopped

fleet-init:
image: ${ALPINE_IMAGE:-alpine:3.23.4}
volumes:
- logs:/logs
- data:/data
- vulndb:/vulndb
command: ["sh", "-c", "chown -R 100:101 /logs /data /vulndb"]

fleet:
image: ${FLEET_IMAGE_REPOSITORY:-thinkhome/fleet}:${FLEET_IMAGE_TAG}
build:
context: .
dockerfile: Dockerfile.local
args:
FLEET_VERSION: ${FLEET_IMAGE_TAG}
FLEET_REVISION: ${FLEET_REVISION:-unknown}
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
fleet-init:
condition: service_completed_successfully
command: ["sh", "-c", "/usr/bin/fleet prepare db --no-prompt && exec /usr/bin/fleet serve"]
environment:
FLEET_REDIS_ADDRESS: redis:6379
FLEET_MYSQL_ADDRESS: mysql:3306
FLEET_MYSQL_DATABASE: ${MYSQL_DATABASE:-fleet}
FLEET_MYSQL_USERNAME: ${MYSQL_USER:-fleet}
FLEET_MYSQL_PASSWORD: ${MYSQL_PASSWORD:?set MYSQL_PASSWORD in .env}
FLEET_SERVER_ADDRESS: ${FLEET_SERVER_ADDRESS:-0.0.0.0:1337}
FLEET_SERVER_TLS: ${FLEET_SERVER_TLS:-false}
FLEET_SERVER_TRUSTED_PROXIES: ${FLEET_SERVER_TRUSTED_PROXIES:-1}
FLEET_SERVER_PRIVATE_KEY: ${FLEET_SERVER_PRIVATE_KEY:?set FLEET_SERVER_PRIVATE_KEY in .env}
FLEET_SERVER_MAX_INSTALLER_SIZE: ${FLEET_SERVER_MAX_INSTALLER_SIZE:-10GiB}
FLEET_LOGGING_JSON: ${FLEET_LOGGING_JSON:-true}
FLEET_LOGGING_DEBUG: ${FLEET_LOGGING_DEBUG:-false}
FLEET_VULNERABILITIES_CURRENT_INSTANCE_CHECKS: ${FLEET_VULNERABILITIES_CURRENT_INSTANCE_CHECKS:-yes}
FLEET_VULNERABILITIES_DATABASES_PATH: ${FLEET_VULNERABILITIES_DATABASES_PATH:-/vulndb}
FLEET_VULNERABILITIES_PERIODICITY: ${FLEET_VULNERABILITIES_PERIODICITY:-1h}
FLEET_MDM_WINDOWS_WSTEP_IDENTITY_CERT: /run/secrets/fleet-mdm/windows-wstep.crt
FLEET_MDM_WINDOWS_WSTEP_IDENTITY_KEY: /run/secrets/fleet-mdm/windows-wstep.key
FLEET_MDM_ANDROID_GOOGLE_SERVICE_CREDENTIALS: ${FLEET_MDM_ANDROID_GOOGLE_SERVICE_CREDENTIALS:-}
FLEET_LICENSE_KEY: ${FLEET_LICENSE_KEY:-}
FLEET_S3_SOFTWARE_INSTALLERS_BUCKET: ${FLEET_S3_SOFTWARE_INSTALLERS_BUCKET:-}
FLEET_S3_SOFTWARE_INSTALLERS_PREFIX: ${FLEET_S3_SOFTWARE_INSTALLERS_PREFIX:-}
FLEET_S3_SOFTWARE_INSTALLERS_ACCESS_KEY_ID: ${FLEET_S3_SOFTWARE_INSTALLERS_ACCESS_KEY_ID:-}
FLEET_S3_SOFTWARE_INSTALLERS_SECRET_ACCESS_KEY: ${FLEET_S3_SOFTWARE_INSTALLERS_SECRET_ACCESS_KEY:-}
FLEET_S3_SOFTWARE_INSTALLERS_REGION: ${FLEET_S3_SOFTWARE_INSTALLERS_REGION:-}
FLEET_S3_SOFTWARE_INSTALLERS_ENDPOINT_URL: ${FLEET_S3_SOFTWARE_INSTALLERS_ENDPOINT_URL:-}
FLEET_S3_SOFTWARE_INSTALLERS_FORCE_S3_PATH_STYLE: ${FLEET_S3_SOFTWARE_INSTALLERS_FORCE_S3_PATH_STYLE:-false}
expose:
- "1337"
volumes:
- data:/fleet
- logs:/logs
- vulndb:/vulndb
- ./secrets/mdm:/run/secrets/fleet-mdm:ro
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:1337/healthz"]
interval: 10s
timeout: 5s
retries: 20
restart: unless-stopped

caddy:
image: ${CADDY_IMAGE:-caddy:2.11.4-alpine}
depends_on:
fleet:
condition: service_healthy
ports:
- "${HTTP_PORT:-80}:80"
- "${HTTPS_PORT:-443}:443"
environment:
FLEET_DOMAIN: ${FLEET_DOMAIN:-fleet.thinkhome.org}
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
restart: unless-stopped