Skip to main content
Watchdog uses environment variables for configuration. Copy .env.example to .env and configure the variables below for your environment.

Loading environment variables

Watchdog uses the godotenv package to load environment variables from a .env file at startup. The env package provides helper functions to fetch typed values:
func FetchString(key string, fallback ...string) string {
	response, ok := os.LookupEnv(key)
	if ok {
		return response
	}
	if len(fallback) > 0 {
		return fallback[0]
	}
	panic(fmt.Sprintf("environment variable %s is not set and no fallback provided", key))
}

func FetchInt(key string, fallback ...int) int {
	response, ok := os.LookupEnv(key)
	if ok == false && len(fallback) <= 0 {
		panic(fmt.Sprintf("environment variable %s is not set and no fallback provided", key))
	}
	resp, err := strconv.Atoi(response)
	if err != nil {
		if len(fallback) > 0 {
			return fallback[0]
		}
		panic(fmt.Sprintf("environment variable %s is not an integer", key))
	}
	return resp
}
If a required environment variable is missing and no fallback is provided, the application will panic at startup with a clear error message.

Application environment

APP_ENV
string
default:"dev"
required
Application environment identifier. Controls environment-specific behavior and logging.Common values:
  • dev - Development environment
  • staging - Staging environment
  • prod - Production environment

Redis configuration

Watchdog uses Redis for interval list caching and worker coordination.
REDIS_HOST
string
default:"127.0.0.1:6379"
required
Redis server host and port in the format host:port.Example: 127.0.0.1:6379 or redis.example.com:6379
REDIS_PASS
string
default:"''"
Redis server password. Leave empty if Redis doesn’t require authentication.
Always use authentication in production environments.
REDIS_DB
integer
default:"2"
required
Redis database index (0-15). Allows isolating Watchdog data from other applications.Example: 2

Worker and pool configuration

These settings control the concurrency and performance characteristics of the monitoring system.
MAXIMUM_CHILD_WORKERS
integer
default:"5"
required
Maximum number of child workers spawned per parent worker group.Each child worker performs actual HTTP checks. Higher values increase concurrency but consume more resources.Recommended range: 3-10 depending on server capacity
MAXIMUM_WORK_POOL_SIZE
integer
default:"25"
required
Total work pool size controlling how many URLs are processed concurrently per batch.This value determines the batch size when processing URLs at each monitoring interval.Recommended range: 20-100 depending on server capacity and target count
HTTP_REQUEST_TIMEOUT
integer
default:"5"
required
Timeout in seconds for HTTP requests performed by child workers.If a monitored URL doesn’t respond within this timeframe, the check is marked as failed.Recommended range: 5-30 seconds
SUPERVISOR_POOL_FLUSH_TIMEOUT
integer
default:"5"
required
Timeout in seconds for supervisor batch flushing operations.The supervisor batches check results before processing. This controls how long to wait before flushing accumulated results.Recommended range: 3-10 seconds
SUPERVISOR_POOL_FLUSH_BATCHSIZE
integer
default:"100"
required
Batch size for supervisor flush operations.The supervisor processes check results in batches to improve efficiency. Higher values reduce overhead but increase memory usage.Recommended range: 50-200

Database configuration

See Database configuration for detailed PostgreSQL/TimescaleDB setup.
DB_USER
string
default:"tsdbadmin"
required
PostgreSQL username for database connections.Example: tsdbadmin or watchdog_user
DB_PASSWORD
string
required
PostgreSQL password for the database user.
Never commit this value to version control. Use environment-specific .env files that are gitignored.
DB_HOST
string
required
PostgreSQL server hostname or IP address.Examples:
  • localhost - Local database
  • postgres.example.com - Remote database
  • 10.0.1.5 - IP address
DB_PORT
string
required
PostgreSQL server port number.Default PostgreSQL port is 5432.
DB_DATABASE
string
default:"tsdb"
required
PostgreSQL database name.This database must exist and have the TimescaleDB extension installed.

Migration configuration

Watchdog uses Goose for database migrations.
GOOSE_DRIVER
string
default:"postgres"
required
Goose database driver name.For PostgreSQL/TimescaleDB, use postgres.
GOOSE_DBSTRING
string
required
Database connection string used by Goose for migrations.Typically interpolates the DB_* variables:
GOOSE_DBSTRING="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_DATABASE}?sslmode=disable"
For production, replace sslmode=disable with sslmode=require to enforce SSL/TLS connections.
GOOSE_MIGRATION_DIR
string
default:"migrations"
required
Path to the directory containing migration files.Relative to the project root. Default is migrations.

Email configuration

See Email configuration for detailed SMTP setup.
MAIL_FROM_ADDRESS
string
required
Sender email address used for notification emails.This address appears in the “From” field of status change notifications.Example: [email protected]
MAIL_HOST
string
default:"sandbox.smtp.mailtrap.io"
required
SMTP server hostname.Examples:
  • sandbox.smtp.mailtrap.io - Mailtrap (development)
  • smtp.gmail.com - Gmail
  • smtp.sendgrid.net - SendGrid
MAIL_PORT
integer
default:"2525"
required
SMTP server port number.Common ports:
  • 25 - Standard SMTP (often blocked by ISPs)
  • 587 - SMTP with STARTTLS (recommended)
  • 465 - SMTP over SSL
  • 2525 - Alternative port (Mailtrap)
MAIL_USERNAME
string
required
SMTP authentication username.Required by most SMTP providers for authentication.
MAIL_PASSWORD
string
required
SMTP authentication password or API key.
Never commit this value to version control. Some providers (like Gmail) require app-specific passwords instead of account passwords.

Example configuration

.env.example
APP_ENV=dev

REDIS_HOST=127.0.0.1:6379
REDIS_PASS=''
REDIS_DB=2

MAXIMUM_CHILD_WORKERS=5
MAXIMUM_WORK_POOL_SIZE=25

HTTP_REQUEST_TIMEOUT=5

SUPERVISOR_POOL_FLUSH_TIMEOUT=5
SUPERVISOR_POOL_FLUSH_BATCHSIZE=100

DB_USER=tsdbadmin
DB_PASSWORD=
DB_HOST=
DB_PORT=
DB_DATABASE=tsdb

GOOSE_DRIVER=postgres
GOOSE_DBSTRING="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_DATABASE}?sslmode=disable"
GOOSE_MIGRATION_DIR=migrations

MAIL_FROM_ADDRESS="[email protected]"
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=

Validation and error handling

Watchdog validates required environment variables at startup:
1

Load .env file

The application attempts to load environment variables from the .env file using godotenv.Load().If the file is missing, the application will panic with “Error loading file”.
2

Fetch required variables

Each required variable is fetched using env.FetchString() or env.FetchInt().If a required variable is missing and no fallback is provided, the application panics with the variable name.
3

Type validation

Integer variables are validated using strconv.Atoi().If a variable contains a non-integer value, the application panics with “environment variable X is not an integer”.
The panic-on-error approach ensures that configuration issues are caught immediately at startup rather than causing runtime failures.

Build docs developers (and LLMs) love