Overview
The webhook server can be deployed as a containerized application using Docker, or run directly with Node.js. This deployment method is ideal for self-hosted environments, Kubernetes clusters, or cloud platforms that support container deployments.
Docker Deployment
Building the Docker Image
The provided Dockerfile uses a multi-stage build to create an optimized production image:
docker build \
--build-arg PAYMENT_PLATFORM=stripe \
-t cryptlex-stripe-webhook:latest \
.
The build process:
Uses Node.js 22 Alpine as the base image
Installs dependencies and builds the platform-specific bundle
Creates a minimal runtime image with only production dependencies
Runs as a non-root user (hono:nodejs) for security
Running the Container
Run the container with the required environment variables:
docker run -d \
--name cryptlex-stripe-webhook \
-p 9890:9890 \
-e STRIPE_WEBHOOK_SECRET="whsec_..." \
-e CRYPTLEX_PRODUCT_ID="your-product-id" \
-e CRYPTLEX_ACCESS_TOKEN="your-access-token" \
-e CRYPTLEX_WEB_API_BASE_URL="https://api.cryptlex.com/v3" \
cryptlex-stripe-webhook:latest
The server listens on port 9890 by default. Map this to your desired host port using the -p flag.
Using Environment Files
For easier management, store environment variables in a file:
STRIPE_WEBHOOK_SECRET = whsec_...
CRYPTLEX_PRODUCT_ID = your-product-id
CRYPTLEX_ACCESS_TOKEN = your-access-token
CRYPTLEX_WEB_API_BASE_URL = https://api.cryptlex.com/v3
Run with the env file:
docker run -d \
--name cryptlex-stripe-webhook \
-p 9890:9890 \
--env-file .env.stripe \
cryptlex-stripe-webhook:latest
Never commit .env files containing secrets to version control. Add them to .gitignore.
Standalone Node.js Deployment
You can run the webhook server directly with Node.js without Docker:
Build Process
npm ci
npm run build:stripe:node
Running the Server
Set environment variables and start the server:
export STRIPE_WEBHOOK_SECRET = "whsec_..."
export CRYPTLEX_PRODUCT_ID = "your-product-id"
export CRYPTLEX_ACCESS_TOKEN = "your-access-token"
export CRYPTLEX_WEB_API_BASE_URL = "https://api.cryptlex.com/v3"
node dist/index.node.js
The server will start on port 9890.
Health Checks
Docker Health Check
Add a health check to your Docker run command:
docker run -d \
--name cryptlex-webhook \
-p 9890:9890 \
--env-file .env \
--health-cmd= "wget --no-verbose --tries=1 --spider http://localhost:9890/ || exit 1" \
--health-interval=30s \
--health-timeout=5s \
--health-retries=3 \
cryptlex-webhook:latest
Or add to your docker-compose.yml:
version : '3.8'
services :
webhook :
build :
context : .
args :
PAYMENT_PLATFORM : stripe
ports :
- "9890:9890"
env_file :
- .env.stripe
healthcheck :
test : [ "CMD" , "wget" , "--no-verbose" , "--tries=1" , "--spider" , "http://localhost:9890/" ]
interval : 30s
timeout : 5s
retries : 3
start_period : 10s
restart : unless-stopped
Production Considerations
Reverse Proxy Setup
In production, run the webhook server behind a reverse proxy like Nginx:
server {
listen 443 ssl http2;
server_name webhook.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:9890;
proxy_set_header Host $ host ;
proxy_set_header X-Real-IP $ remote_addr ;
proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto $ scheme ;
}
}
Container Orchestration
For Kubernetes deployments:
apiVersion : apps/v1
kind : Deployment
metadata :
name : cryptlex-webhook
spec :
replicas : 2
selector :
matchLabels :
app : cryptlex-webhook
template :
metadata :
labels :
app : cryptlex-webhook
spec :
containers :
- name : webhook
image : cryptlex-webhook:latest
ports :
- containerPort : 9890
env :
- name : STRIPE_WEBHOOK_SECRET
valueFrom :
secretKeyRef :
name : webhook-secrets
key : stripe-webhook-secret
- name : CRYPTLEX_ACCESS_TOKEN
valueFrom :
secretKeyRef :
name : webhook-secrets
key : cryptlex-access-token
- name : CRYPTLEX_PRODUCT_ID
value : "your-product-id"
- name : CRYPTLEX_WEB_API_BASE_URL
value : "https://api.cryptlex.com/v3"
livenessProbe :
httpGet :
path : /
port : 9890
initialDelaySeconds : 10
periodSeconds : 30
resources :
requests :
memory : "128Mi"
cpu : "100m"
limits :
memory : "256Mi"
cpu : "200m"
Logging
The application logs to stdout/stderr. Configure log aggregation:
Docker logging driver :
docker run -d \
--log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file= 3 \
cryptlex-webhook:latest
View logs :
docker logs -f cryptlex-webhook
Port Configuration
The server is configured to listen on port 9890 as defined in the Dockerfile:
To use a different port, you can:
Map to a different host port (recommended):
docker run -p 8080:9890 ...
Modify the Dockerfile and rebuild:
Troubleshooting
Container Won’t Start
# Check container logs
docker logs cryptlex-webhook
# Inspect container configuration
docker inspect cryptlex-webhook
Environment Variables Not Set
Verify environment variables inside the container:
docker exec cryptlex-webhook env | grep CRYPTLEX
Permission Denied Errors
The container runs as user hono (UID 1001). Ensure mounted volumes have appropriate permissions:
chown -R 1001:1001 /path/to/mounted/volume
Next Steps
Environment Variables Complete reference for all environment variables
AWS Lambda Alternative serverless deployment option