From maintainx-pack
Deploys MaintainX Node.js integrations to production via Docker on GCP Cloud Run or Kubernetes, with health checks, secret management, and gcloud commands.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin maintainx-packThis skill is limited to using the following tools:
Deploy MaintainX integrations to production using Docker, Google Cloud Run, and Kubernetes with proper health checks and secret management.
Provides production deployment checklist for MaintainX integrations verifying security, resilience, data integrity, observability, and performance.
Deploys Apollo.io integrations to production on Vercel, GCP Cloud Run, or Kubernetes using Node.js with health checks, Docker, and secret management.
Provides checklists and best practices for CI/CD pipelines, Docker builds, monitoring/alerting setups, infrastructure defaults, and incident response to ship reliably and debug production issues.
Share bugs, ideas, or general feedback.
Deploy MaintainX integrations to production using Docker, Google Cloud Run, and Kubernetes with proper health checks and secret management.
MAINTAINX_API_KEY for production environment# Dockerfile
FROM node:20-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --production=false
COPY tsconfig.json ./
COPY src/ ./src/
RUN npm run build
FROM node:20-slim
WORKDIR /app
RUN addgroup --system app && adduser --system --ingroup app app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
USER app
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]
// src/health.ts
import express from 'express';
import { MaintainXClient } from './client';
const app = express();
app.get('/health', async (req, res) => {
const checks: Record<string, string> = {
server: 'ok',
apiKey: process.env.MAINTAINX_API_KEY ? 'configured' : 'missing',
};
try {
const client = new MaintainXClient();
await client.getUsers({ limit: 1 });
checks.maintainxApi = 'ok';
} catch (err: any) {
checks.maintainxApi = `error: ${err.response?.status || err.message}`;
}
const allOk = Object.values(checks).every((v) => v === 'ok' || v === 'configured');
res.status(allOk ? 200 : 503).json({
status: allOk ? 'healthy' : 'degraded',
checks,
uptime: process.uptime(),
timestamp: new Date().toISOString(),
});
});
app.get('/ready', (req, res) => {
res.status(process.env.MAINTAINX_API_KEY ? 200 : 503).json({
ready: !!process.env.MAINTAINX_API_KEY,
});
});
export { app };
# Build and push container
PROJECT_ID="your-gcp-project"
REGION="us-central1"
SERVICE="maintainx-integration"
gcloud builds submit --tag gcr.io/$PROJECT_ID/$SERVICE
# Deploy with secrets
gcloud run deploy $SERVICE \
--image gcr.io/$PROJECT_ID/$SERVICE \
--region $REGION \
--platform managed \
--set-secrets "MAINTAINX_API_KEY=maintainx-api-key:latest" \
--min-instances 1 \
--max-instances 10 \
--memory 512Mi \
--cpu 1 \
--port 3000 \
--allow-unauthenticated # Only if webhook endpoint
# docker-compose.yml
services:
maintainx-sync:
build: .
env_file: .env.production
ports: ["3000:3000"]
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 5s
retries: 3
redis:
image: redis:7-alpine
ports: ["6379:6379"]
volumes: ["redis-data:/data"]
volumes:
redis-data:
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: maintainx-integration
spec:
replicas: 2
selector:
matchLabels:
app: maintainx-integration
template:
metadata:
labels:
app: maintainx-integration
spec:
containers:
- name: app
image: gcr.io/your-project/maintainx-integration:latest
ports:
- containerPort: 3000
env:
- name: MAINTAINX_API_KEY
valueFrom:
secretKeyRef:
name: maintainx-secrets
key: api-key
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: maintainx-integration
spec:
selector:
app: maintainx-integration
ports:
- port: 80
targetPort: 3000
type: ClusterIP
# Create secret and deploy
kubectl create secret generic maintainx-secrets \
--from-literal=api-key="$MAINTAINX_API_KEY"
kubectl apply -f k8s/deployment.yaml
kubectl rollout status deployment/maintainx-integration
/health and /ready endpoints for container orchestration| Issue | Cause | Solution |
|---|---|---|
| Container crashes on start | Missing MAINTAINX_API_KEY | Verify secret is mounted correctly |
| Health check fails | API key expired or network issue | Check /health response, rotate key |
| High memory usage | Unbounded caching or data retention | Set memory limits, add cache eviction |
| Cold start latency | Cloud Run scaling from zero | Set min-instances: 1 |
For webhook integration, see maintainx-webhooks-events.
AWS Lambda deployment (serverless):
// lambda.ts
import { APIGatewayProxyHandler } from 'aws-lambda';
import { MaintainXClient } from './client';
export const handler: APIGatewayProxyHandler = async (event) => {
const client = new MaintainXClient(process.env.MAINTAINX_API_KEY);
if (event.path === '/webhook' && event.httpMethod === 'POST') {
const body = JSON.parse(event.body || '{}');
await processWebhook(body);
return { statusCode: 200, body: '{"ok":true}' };
}
return { statusCode: 404, body: '{"error":"not found"}' };
};