Skip to main content

Docker deployment

1

Build the image

From the project root, build the Docker image:
docker build -t phisherman .
2

Run the container

Start the container and pass your environment variables:
docker run -p 4000:4000 \
  -e UPSTASH_REDIS_REST_URL=https://your-upstash-endpoint.upstash.io \
  -e UPSTASH_REDIS_REST_TOKEN=your_upstash_token \
  -e GOOGLE_SAFE_API_KEY=your_google_safe_browsing_key \
  phisherman
The API is now available at http://localhost:4000.

Docker environment variables

Pass these variables to the container using -e flags or a .env file with --env-file:
VariableRequiredDescription
UPSTASH_REDIS_REST_URLYesREST URL for your Upstash Redis database
UPSTASH_REDIS_REST_TOKENYesAuthentication token for your Upstash Redis database
GOOGLE_SAFE_API_KEYNoGoogle Safe Browsing API key. If omitted, the GSB checker returns score 0 without making any API call.
PORTNoPort the server listens on (default: 4000)
SCAN_CACHE_SAFE_RESULTSNoSet to true to cache safe scan results in Redis (default: false)
WEBRISK_API_KEYNoGoogle Web Risk API key. Only needed if you enable the WebRiskChecker (disabled by default).
Never commit GOOGLE_SAFE_API_KEY or any other secrets to source control. Pass them as environment variables at runtime or use a secrets manager.

Dockerfile

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install --production

COPY . .

RUN npm run build

EXPOSE 4000

# Start server
CMD ["npm", "start"]

Node.js deployment

To run Phisherman directly without Docker:
npm run build && npm start
This compiles the TypeScript source with tsc and then runs node dist/index.js. For long-running production deployments, use a process manager such as PM2 to handle automatic restarts and logging:
npm install -g pm2
pm2 start dist/index.js --name phisherman
pm2 save
pm2 startup

Production considerations

Phisherman is designed with production use in mind:
  • Reverse proxy support: trust proxy is already set to 1 in Express, so real client IPs are correctly read from the X-Forwarded-For header when you place Phisherman behind Nginx, Caddy, or a cloud load balancer.
  • Persistent rate limiting: Rate limit counters are stored in Redis, so they survive application restarts and work correctly across multiple instances.
  • Persistent feed cache: Threat feed data (URLHaus, OpenPhish, PhishTank, PhishStats) is cached in Redis and persists across restarts, which means feeds are available immediately on startup after the first run.

Build docs developers (and LLMs) love