mcp-wordpress 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +503 -0
- package/dist/client/api.d.ts +90 -0
- package/dist/client/api.d.ts.map +1 -1
- package/dist/client/api.js +90 -0
- package/dist/client/api.js.map +1 -1
- package/dist/tools/media.d.ts +43 -4
- package/dist/tools/media.d.ts.map +1 -1
- package/dist/tools/media.js +43 -4
- package/dist/tools/media.js.map +1 -1
- package/dist/tools/posts.d.ts +225 -4
- package/dist/tools/posts.d.ts.map +1 -1
- package/dist/tools/posts.js +225 -4
- package/dist/tools/posts.js.map +1 -1
- package/docs/DOCKER_PUBLISHING_TROUBLESHOOTING.md +233 -0
- package/docs/PUBLISHING-TROUBLESHOOTING.md +227 -0
- package/docs/api/README.md +53 -11
- package/docs/api/openapi.json +10 -10
- package/docs/api/summary.json +1 -1
- package/docs/api/tools/wp_create_post.md +9 -3
- package/docs/api/tools/wp_delete_post.md +2 -3
- package/docs/api/tools/wp_get_current_user.md +7 -1
- package/docs/api/tools/wp_get_post.md +2 -3
- package/docs/api/tools/wp_get_post_revisions.md +1 -1
- package/docs/api/tools/wp_list_posts.md +10 -3
- package/docs/api/tools/wp_list_users.md +8 -1
- package/docs/api/tools/wp_search_site.md +8 -1
- package/docs/api/tools/wp_test_auth.md +8 -1
- package/docs/api/tools/wp_update_post.md +2 -3
- package/docs/examples/docker-production.md +801 -0
- package/docs/examples/multi-site-setup.md +575 -0
- package/docs/examples/single-site-setup.md +390 -0
- package/docs/examples/use-case-workflows.md +469 -0
- package/package.json +4 -1
- package/src/client/api.ts +90 -0
- package/src/tools/media.ts +43 -4
- package/src/tools/posts.ts +225 -4
|
@@ -0,0 +1,801 @@
|
|
|
1
|
+
# Docker Production Deployment Examples
|
|
2
|
+
|
|
3
|
+
Complete configuration examples for deploying MCP WordPress in production environments using Docker.
|
|
4
|
+
|
|
5
|
+
## Basic Production Setup
|
|
6
|
+
|
|
7
|
+
### Dockerfile (Production)
|
|
8
|
+
|
|
9
|
+
```dockerfile
|
|
10
|
+
# Multi-stage build for production
|
|
11
|
+
FROM node:20-alpine AS builder
|
|
12
|
+
|
|
13
|
+
# Set working directory
|
|
14
|
+
WORKDIR /app
|
|
15
|
+
|
|
16
|
+
# Copy package files
|
|
17
|
+
COPY package*.json ./
|
|
18
|
+
|
|
19
|
+
# Install dependencies
|
|
20
|
+
RUN npm ci --only=production
|
|
21
|
+
|
|
22
|
+
# Copy source code
|
|
23
|
+
COPY . .
|
|
24
|
+
|
|
25
|
+
# Build application
|
|
26
|
+
RUN npm run build
|
|
27
|
+
|
|
28
|
+
# Production stage
|
|
29
|
+
FROM node:20-alpine AS production
|
|
30
|
+
|
|
31
|
+
# Install security updates
|
|
32
|
+
RUN apk update && apk upgrade && apk add --no-cache \
|
|
33
|
+
ca-certificates \
|
|
34
|
+
&& update-ca-certificates
|
|
35
|
+
|
|
36
|
+
# Create non-root user
|
|
37
|
+
RUN addgroup -g 1001 -S nodejs && \
|
|
38
|
+
adduser -S nextjs -u 1001
|
|
39
|
+
|
|
40
|
+
# Set working directory
|
|
41
|
+
WORKDIR /app
|
|
42
|
+
|
|
43
|
+
# Copy built application from builder stage
|
|
44
|
+
COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
|
|
45
|
+
COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules
|
|
46
|
+
COPY --from=builder --chown=nextjs:nodejs /app/package*.json ./
|
|
47
|
+
|
|
48
|
+
# Create necessary directories
|
|
49
|
+
RUN mkdir -p cache logs && chown -R nextjs:nodejs cache logs
|
|
50
|
+
|
|
51
|
+
# Switch to non-root user
|
|
52
|
+
USER nextjs
|
|
53
|
+
|
|
54
|
+
# Expose port
|
|
55
|
+
EXPOSE 3000
|
|
56
|
+
|
|
57
|
+
# Health check
|
|
58
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
59
|
+
CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
|
|
60
|
+
|
|
61
|
+
# Start application
|
|
62
|
+
CMD ["node", "dist/index.js"]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Docker Compose (Production)
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
# docker-compose.prod.yml
|
|
69
|
+
version: '3.8'
|
|
70
|
+
|
|
71
|
+
services:
|
|
72
|
+
mcp-wordpress:
|
|
73
|
+
build:
|
|
74
|
+
context: .
|
|
75
|
+
dockerfile: Dockerfile
|
|
76
|
+
target: production
|
|
77
|
+
container_name: mcp-wordpress-prod
|
|
78
|
+
restart: unless-stopped
|
|
79
|
+
ports:
|
|
80
|
+
- "3000:3000"
|
|
81
|
+
environment:
|
|
82
|
+
- NODE_ENV=production
|
|
83
|
+
- WORDPRESS_SITE_URL=${WORDPRESS_SITE_URL}
|
|
84
|
+
- WORDPRESS_USERNAME=${WORDPRESS_USERNAME}
|
|
85
|
+
- WORDPRESS_APP_PASSWORD=${WORDPRESS_APP_PASSWORD}
|
|
86
|
+
- CACHE_ENABLED=true
|
|
87
|
+
- CACHE_TTL=600
|
|
88
|
+
- SECURITY_MONITORING=true
|
|
89
|
+
- LOG_LEVEL=info
|
|
90
|
+
volumes:
|
|
91
|
+
- ./cache:/app/cache
|
|
92
|
+
- ./logs:/app/logs
|
|
93
|
+
- ./config:/app/config:ro
|
|
94
|
+
networks:
|
|
95
|
+
- mcp-network
|
|
96
|
+
deploy:
|
|
97
|
+
resources:
|
|
98
|
+
limits:
|
|
99
|
+
cpus: '0.5'
|
|
100
|
+
memory: 512M
|
|
101
|
+
reservations:
|
|
102
|
+
cpus: '0.25'
|
|
103
|
+
memory: 256M
|
|
104
|
+
healthcheck:
|
|
105
|
+
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"]
|
|
106
|
+
interval: 30s
|
|
107
|
+
timeout: 10s
|
|
108
|
+
retries: 3
|
|
109
|
+
start_period: 40s
|
|
110
|
+
logging:
|
|
111
|
+
driver: "json-file"
|
|
112
|
+
options:
|
|
113
|
+
max-size: "10m"
|
|
114
|
+
max-file: "3"
|
|
115
|
+
|
|
116
|
+
networks:
|
|
117
|
+
mcp-network:
|
|
118
|
+
driver: bridge
|
|
119
|
+
|
|
120
|
+
volumes:
|
|
121
|
+
cache-data:
|
|
122
|
+
logs-data:
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Environment Configuration
|
|
126
|
+
|
|
127
|
+
**.env.production**
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Production Environment Configuration
|
|
131
|
+
NODE_ENV=production
|
|
132
|
+
|
|
133
|
+
# WordPress Configuration
|
|
134
|
+
WORDPRESS_SITE_URL=https://your-production-site.com
|
|
135
|
+
WORDPRESS_USERNAME=api-user
|
|
136
|
+
WORDPRESS_APP_PASSWORD=secure-production-password
|
|
137
|
+
|
|
138
|
+
# Performance Settings
|
|
139
|
+
CACHE_ENABLED=true
|
|
140
|
+
CACHE_TTL=600
|
|
141
|
+
CACHE_MAX_ITEMS=1000
|
|
142
|
+
CACHE_MAX_MEMORY_MB=200
|
|
143
|
+
|
|
144
|
+
# Security Settings
|
|
145
|
+
SECURITY_MONITORING=true
|
|
146
|
+
RATE_LIMIT_ENABLED=true
|
|
147
|
+
RATE_LIMIT_WINDOW=900000
|
|
148
|
+
RATE_LIMIT_MAX=100
|
|
149
|
+
|
|
150
|
+
# Logging
|
|
151
|
+
LOG_LEVEL=info
|
|
152
|
+
LOG_FORMAT=json
|
|
153
|
+
LOG_FILE=/app/logs/mcp-wordpress.log
|
|
154
|
+
|
|
155
|
+
# Monitoring
|
|
156
|
+
PERFORMANCE_MONITORING=true
|
|
157
|
+
METRICS_ENABLED=true
|
|
158
|
+
HEALTH_CHECK_ENABLED=true
|
|
159
|
+
|
|
160
|
+
# Timeouts
|
|
161
|
+
API_TIMEOUT=15000
|
|
162
|
+
CONNECTION_TIMEOUT=10000
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Load Balanced Setup
|
|
166
|
+
|
|
167
|
+
### Docker Compose with Load Balancer
|
|
168
|
+
|
|
169
|
+
```yaml
|
|
170
|
+
# docker-compose.loadbalanced.yml
|
|
171
|
+
version: '3.8'
|
|
172
|
+
|
|
173
|
+
services:
|
|
174
|
+
nginx:
|
|
175
|
+
image: nginx:alpine
|
|
176
|
+
container_name: mcp-nginx-lb
|
|
177
|
+
ports:
|
|
178
|
+
- "80:80"
|
|
179
|
+
- "443:443"
|
|
180
|
+
volumes:
|
|
181
|
+
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
|
182
|
+
- ./ssl:/etc/nginx/ssl:ro
|
|
183
|
+
depends_on:
|
|
184
|
+
- mcp-wordpress-1
|
|
185
|
+
- mcp-wordpress-2
|
|
186
|
+
networks:
|
|
187
|
+
- mcp-network
|
|
188
|
+
restart: unless-stopped
|
|
189
|
+
|
|
190
|
+
mcp-wordpress-1:
|
|
191
|
+
build:
|
|
192
|
+
context: .
|
|
193
|
+
dockerfile: Dockerfile
|
|
194
|
+
target: production
|
|
195
|
+
container_name: mcp-wordpress-1
|
|
196
|
+
environment:
|
|
197
|
+
- NODE_ENV=production
|
|
198
|
+
- SERVER_ID=server-1
|
|
199
|
+
- WORDPRESS_SITE_URL=${WORDPRESS_SITE_URL}
|
|
200
|
+
- WORDPRESS_USERNAME=${WORDPRESS_USERNAME}
|
|
201
|
+
- WORDPRESS_APP_PASSWORD=${WORDPRESS_APP_PASSWORD}
|
|
202
|
+
- CACHE_ENABLED=true
|
|
203
|
+
- REDIS_URL=redis://redis:6379
|
|
204
|
+
volumes:
|
|
205
|
+
- ./cache:/app/cache
|
|
206
|
+
- ./logs:/app/logs
|
|
207
|
+
networks:
|
|
208
|
+
- mcp-network
|
|
209
|
+
depends_on:
|
|
210
|
+
- redis
|
|
211
|
+
restart: unless-stopped
|
|
212
|
+
|
|
213
|
+
mcp-wordpress-2:
|
|
214
|
+
build:
|
|
215
|
+
context: .
|
|
216
|
+
dockerfile: Dockerfile
|
|
217
|
+
target: production
|
|
218
|
+
container_name: mcp-wordpress-2
|
|
219
|
+
environment:
|
|
220
|
+
- NODE_ENV=production
|
|
221
|
+
- SERVER_ID=server-2
|
|
222
|
+
- WORDPRESS_SITE_URL=${WORDPRESS_SITE_URL}
|
|
223
|
+
- WORDPRESS_USERNAME=${WORDPRESS_USERNAME}
|
|
224
|
+
- WORDPRESS_APP_PASSWORD=${WORDPRESS_APP_PASSWORD}
|
|
225
|
+
- CACHE_ENABLED=true
|
|
226
|
+
- REDIS_URL=redis://redis:6379
|
|
227
|
+
volumes:
|
|
228
|
+
- ./cache:/app/cache
|
|
229
|
+
- ./logs:/app/logs
|
|
230
|
+
networks:
|
|
231
|
+
- mcp-network
|
|
232
|
+
depends_on:
|
|
233
|
+
- redis
|
|
234
|
+
restart: unless-stopped
|
|
235
|
+
|
|
236
|
+
redis:
|
|
237
|
+
image: redis:alpine
|
|
238
|
+
container_name: mcp-redis
|
|
239
|
+
command: redis-server --appendonly yes
|
|
240
|
+
volumes:
|
|
241
|
+
- redis-data:/data
|
|
242
|
+
networks:
|
|
243
|
+
- mcp-network
|
|
244
|
+
restart: unless-stopped
|
|
245
|
+
|
|
246
|
+
networks:
|
|
247
|
+
mcp-network:
|
|
248
|
+
driver: bridge
|
|
249
|
+
|
|
250
|
+
volumes:
|
|
251
|
+
redis-data:
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Nginx Configuration
|
|
255
|
+
|
|
256
|
+
```nginx
|
|
257
|
+
# nginx.conf
|
|
258
|
+
events {
|
|
259
|
+
worker_connections 1024;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
http {
|
|
263
|
+
upstream mcp-backend {
|
|
264
|
+
server mcp-wordpress-1:3000;
|
|
265
|
+
server mcp-wordpress-2:3000;
|
|
266
|
+
|
|
267
|
+
# Health checks
|
|
268
|
+
keepalive 32;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
# Rate limiting
|
|
272
|
+
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
|
273
|
+
|
|
274
|
+
server {
|
|
275
|
+
listen 80;
|
|
276
|
+
server_name your-domain.com;
|
|
277
|
+
|
|
278
|
+
# Redirect to HTTPS
|
|
279
|
+
return 301 https://$server_name$request_uri;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
server {
|
|
283
|
+
listen 443 ssl http2;
|
|
284
|
+
server_name your-domain.com;
|
|
285
|
+
|
|
286
|
+
# SSL Configuration
|
|
287
|
+
ssl_certificate /etc/nginx/ssl/cert.pem;
|
|
288
|
+
ssl_certificate_key /etc/nginx/ssl/key.pem;
|
|
289
|
+
ssl_protocols TLSv1.2 TLSv1.3;
|
|
290
|
+
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
|
291
|
+
|
|
292
|
+
# Security headers
|
|
293
|
+
add_header X-Frame-Options DENY;
|
|
294
|
+
add_header X-Content-Type-Options nosniff;
|
|
295
|
+
add_header X-XSS-Protection "1; mode=block";
|
|
296
|
+
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
|
|
297
|
+
|
|
298
|
+
# Rate limiting
|
|
299
|
+
limit_req zone=api burst=20 nodelay;
|
|
300
|
+
|
|
301
|
+
location / {
|
|
302
|
+
proxy_pass http://mcp-backend;
|
|
303
|
+
proxy_set_header Host $host;
|
|
304
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
305
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
306
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
307
|
+
|
|
308
|
+
# Timeouts
|
|
309
|
+
proxy_connect_timeout 5s;
|
|
310
|
+
proxy_send_timeout 60s;
|
|
311
|
+
proxy_read_timeout 60s;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
location /health {
|
|
315
|
+
proxy_pass http://mcp-backend/health;
|
|
316
|
+
access_log off;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Multi-Site Production Setup
|
|
323
|
+
|
|
324
|
+
### Multi-Site Docker Compose
|
|
325
|
+
|
|
326
|
+
```yaml
|
|
327
|
+
# docker-compose.multisite.yml
|
|
328
|
+
version: '3.8'
|
|
329
|
+
|
|
330
|
+
services:
|
|
331
|
+
mcp-wordpress:
|
|
332
|
+
build:
|
|
333
|
+
context: .
|
|
334
|
+
dockerfile: Dockerfile
|
|
335
|
+
target: production
|
|
336
|
+
container_name: mcp-wordpress-multisite
|
|
337
|
+
restart: unless-stopped
|
|
338
|
+
ports:
|
|
339
|
+
- "3000:3000"
|
|
340
|
+
environment:
|
|
341
|
+
- NODE_ENV=production
|
|
342
|
+
volumes:
|
|
343
|
+
- ./mcp-wordpress.config.json:/app/mcp-wordpress.config.json:ro
|
|
344
|
+
- ./cache:/app/cache
|
|
345
|
+
- ./logs:/app/logs
|
|
346
|
+
networks:
|
|
347
|
+
- mcp-network
|
|
348
|
+
deploy:
|
|
349
|
+
resources:
|
|
350
|
+
limits:
|
|
351
|
+
cpus: '1.0'
|
|
352
|
+
memory: 1G
|
|
353
|
+
reservations:
|
|
354
|
+
cpus: '0.5'
|
|
355
|
+
memory: 512M
|
|
356
|
+
|
|
357
|
+
networks:
|
|
358
|
+
mcp-network:
|
|
359
|
+
driver: bridge
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Multi-Site Configuration
|
|
363
|
+
|
|
364
|
+
```json
|
|
365
|
+
{
|
|
366
|
+
"sites": [
|
|
367
|
+
{
|
|
368
|
+
"id": "main-production",
|
|
369
|
+
"name": "Main Production Site",
|
|
370
|
+
"config": {
|
|
371
|
+
"WORDPRESS_SITE_URL": "https://main.company.com",
|
|
372
|
+
"WORDPRESS_USERNAME": "api-admin",
|
|
373
|
+
"WORDPRESS_APP_PASSWORD": "secure-main-password",
|
|
374
|
+
"CACHE_ENABLED": "true",
|
|
375
|
+
"CACHE_TTL": "600",
|
|
376
|
+
"SECURITY_MONITORING": "true",
|
|
377
|
+
"PERFORMANCE_MONITORING": "true"
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"id": "blog-production",
|
|
382
|
+
"name": "Blog Production Site",
|
|
383
|
+
"config": {
|
|
384
|
+
"WORDPRESS_SITE_URL": "https://blog.company.com",
|
|
385
|
+
"WORDPRESS_USERNAME": "blog-editor",
|
|
386
|
+
"WORDPRESS_APP_PASSWORD": "secure-blog-password",
|
|
387
|
+
"CACHE_ENABLED": "true",
|
|
388
|
+
"CACHE_TTL": "300"
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
"id": "shop-production",
|
|
393
|
+
"name": "E-commerce Production Site",
|
|
394
|
+
"config": {
|
|
395
|
+
"WORDPRESS_SITE_URL": "https://shop.company.com",
|
|
396
|
+
"WORDPRESS_USERNAME": "shop-manager",
|
|
397
|
+
"WORDPRESS_APP_PASSWORD": "secure-shop-password",
|
|
398
|
+
"CACHE_ENABLED": "true",
|
|
399
|
+
"RATE_LIMIT_ENABLED": "true"
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
]
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## Kubernetes Deployment
|
|
407
|
+
|
|
408
|
+
### Kubernetes Manifests
|
|
409
|
+
|
|
410
|
+
**Namespace**
|
|
411
|
+
|
|
412
|
+
```yaml
|
|
413
|
+
# namespace.yaml
|
|
414
|
+
apiVersion: v1
|
|
415
|
+
kind: Namespace
|
|
416
|
+
metadata:
|
|
417
|
+
name: mcp-wordpress
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**ConfigMap**
|
|
421
|
+
|
|
422
|
+
```yaml
|
|
423
|
+
# configmap.yaml
|
|
424
|
+
apiVersion: v1
|
|
425
|
+
kind: ConfigMap
|
|
426
|
+
metadata:
|
|
427
|
+
name: mcp-wordpress-config
|
|
428
|
+
namespace: mcp-wordpress
|
|
429
|
+
data:
|
|
430
|
+
NODE_ENV: "production"
|
|
431
|
+
CACHE_ENABLED: "true"
|
|
432
|
+
CACHE_TTL: "600"
|
|
433
|
+
SECURITY_MONITORING: "true"
|
|
434
|
+
LOG_LEVEL: "info"
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
**Secret**
|
|
438
|
+
|
|
439
|
+
```yaml
|
|
440
|
+
# secret.yaml
|
|
441
|
+
apiVersion: v1
|
|
442
|
+
kind: Secret
|
|
443
|
+
metadata:
|
|
444
|
+
name: mcp-wordpress-secret
|
|
445
|
+
namespace: mcp-wordpress
|
|
446
|
+
type: Opaque
|
|
447
|
+
data:
|
|
448
|
+
WORDPRESS_SITE_URL: <base64-encoded-url>
|
|
449
|
+
WORDPRESS_USERNAME: <base64-encoded-username>
|
|
450
|
+
WORDPRESS_APP_PASSWORD: <base64-encoded-password>
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**Deployment**
|
|
454
|
+
|
|
455
|
+
```yaml
|
|
456
|
+
# deployment.yaml
|
|
457
|
+
apiVersion: apps/v1
|
|
458
|
+
kind: Deployment
|
|
459
|
+
metadata:
|
|
460
|
+
name: mcp-wordpress
|
|
461
|
+
namespace: mcp-wordpress
|
|
462
|
+
spec:
|
|
463
|
+
replicas: 3
|
|
464
|
+
selector:
|
|
465
|
+
matchLabels:
|
|
466
|
+
app: mcp-wordpress
|
|
467
|
+
template:
|
|
468
|
+
metadata:
|
|
469
|
+
labels:
|
|
470
|
+
app: mcp-wordpress
|
|
471
|
+
spec:
|
|
472
|
+
containers:
|
|
473
|
+
- name: mcp-wordpress
|
|
474
|
+
image: docdyhr/mcp-wordpress:latest
|
|
475
|
+
ports:
|
|
476
|
+
- containerPort: 3000
|
|
477
|
+
envFrom:
|
|
478
|
+
- configMapRef:
|
|
479
|
+
name: mcp-wordpress-config
|
|
480
|
+
- secretRef:
|
|
481
|
+
name: mcp-wordpress-secret
|
|
482
|
+
resources:
|
|
483
|
+
requests:
|
|
484
|
+
memory: "256Mi"
|
|
485
|
+
cpu: "250m"
|
|
486
|
+
limits:
|
|
487
|
+
memory: "512Mi"
|
|
488
|
+
cpu: "500m"
|
|
489
|
+
livenessProbe:
|
|
490
|
+
httpGet:
|
|
491
|
+
path: /health
|
|
492
|
+
port: 3000
|
|
493
|
+
initialDelaySeconds: 30
|
|
494
|
+
periodSeconds: 10
|
|
495
|
+
readinessProbe:
|
|
496
|
+
httpGet:
|
|
497
|
+
path: /health
|
|
498
|
+
port: 3000
|
|
499
|
+
initialDelaySeconds: 5
|
|
500
|
+
periodSeconds: 5
|
|
501
|
+
volumeMounts:
|
|
502
|
+
- name: cache-volume
|
|
503
|
+
mountPath: /app/cache
|
|
504
|
+
- name: logs-volume
|
|
505
|
+
mountPath: /app/logs
|
|
506
|
+
volumes:
|
|
507
|
+
- name: cache-volume
|
|
508
|
+
emptyDir: {}
|
|
509
|
+
- name: logs-volume
|
|
510
|
+
emptyDir: {}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Service**
|
|
514
|
+
|
|
515
|
+
```yaml
|
|
516
|
+
# service.yaml
|
|
517
|
+
apiVersion: v1
|
|
518
|
+
kind: Service
|
|
519
|
+
metadata:
|
|
520
|
+
name: mcp-wordpress-service
|
|
521
|
+
namespace: mcp-wordpress
|
|
522
|
+
spec:
|
|
523
|
+
selector:
|
|
524
|
+
app: mcp-wordpress
|
|
525
|
+
ports:
|
|
526
|
+
- protocol: TCP
|
|
527
|
+
port: 80
|
|
528
|
+
targetPort: 3000
|
|
529
|
+
type: ClusterIP
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Ingress**
|
|
533
|
+
|
|
534
|
+
```yaml
|
|
535
|
+
# ingress.yaml
|
|
536
|
+
apiVersion: networking.k8s.io/v1
|
|
537
|
+
kind: Ingress
|
|
538
|
+
metadata:
|
|
539
|
+
name: mcp-wordpress-ingress
|
|
540
|
+
namespace: mcp-wordpress
|
|
541
|
+
annotations:
|
|
542
|
+
kubernetes.io/ingress.class: nginx
|
|
543
|
+
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
544
|
+
nginx.ingress.kubernetes.io/rate-limit: "10"
|
|
545
|
+
spec:
|
|
546
|
+
tls:
|
|
547
|
+
- hosts:
|
|
548
|
+
- api.company.com
|
|
549
|
+
secretName: mcp-wordpress-tls
|
|
550
|
+
rules:
|
|
551
|
+
- host: api.company.com
|
|
552
|
+
http:
|
|
553
|
+
paths:
|
|
554
|
+
- path: /
|
|
555
|
+
pathType: Prefix
|
|
556
|
+
backend:
|
|
557
|
+
service:
|
|
558
|
+
name: mcp-wordpress-service
|
|
559
|
+
port:
|
|
560
|
+
number: 80
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
## Monitoring and Logging
|
|
564
|
+
|
|
565
|
+
### Prometheus Configuration
|
|
566
|
+
|
|
567
|
+
```yaml
|
|
568
|
+
# prometheus.yml
|
|
569
|
+
global:
|
|
570
|
+
scrape_interval: 15s
|
|
571
|
+
|
|
572
|
+
scrape_configs:
|
|
573
|
+
- job_name: 'mcp-wordpress'
|
|
574
|
+
static_configs:
|
|
575
|
+
- targets: ['mcp-wordpress:3000']
|
|
576
|
+
metrics_path: /metrics
|
|
577
|
+
scrape_interval: 30s
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
### Docker Compose with Monitoring
|
|
581
|
+
|
|
582
|
+
```yaml
|
|
583
|
+
# docker-compose.monitoring.yml
|
|
584
|
+
version: '3.8'
|
|
585
|
+
|
|
586
|
+
services:
|
|
587
|
+
mcp-wordpress:
|
|
588
|
+
build:
|
|
589
|
+
context: .
|
|
590
|
+
dockerfile: Dockerfile
|
|
591
|
+
target: production
|
|
592
|
+
container_name: mcp-wordpress
|
|
593
|
+
environment:
|
|
594
|
+
- NODE_ENV=production
|
|
595
|
+
- METRICS_ENABLED=true
|
|
596
|
+
- PROMETHEUS_ENABLED=true
|
|
597
|
+
networks:
|
|
598
|
+
- monitoring
|
|
599
|
+
|
|
600
|
+
prometheus:
|
|
601
|
+
image: prom/prometheus:latest
|
|
602
|
+
container_name: prometheus
|
|
603
|
+
ports:
|
|
604
|
+
- "9090:9090"
|
|
605
|
+
volumes:
|
|
606
|
+
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
|
607
|
+
networks:
|
|
608
|
+
- monitoring
|
|
609
|
+
|
|
610
|
+
grafana:
|
|
611
|
+
image: grafana/grafana:latest
|
|
612
|
+
container_name: grafana
|
|
613
|
+
ports:
|
|
614
|
+
- "3001:3000"
|
|
615
|
+
environment:
|
|
616
|
+
- GF_SECURITY_ADMIN_PASSWORD=admin
|
|
617
|
+
volumes:
|
|
618
|
+
- grafana-data:/var/lib/grafana
|
|
619
|
+
networks:
|
|
620
|
+
- monitoring
|
|
621
|
+
|
|
622
|
+
networks:
|
|
623
|
+
monitoring:
|
|
624
|
+
driver: bridge
|
|
625
|
+
|
|
626
|
+
volumes:
|
|
627
|
+
grafana-data:
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Logging Configuration
|
|
631
|
+
|
|
632
|
+
```yaml
|
|
633
|
+
# filebeat.yml
|
|
634
|
+
filebeat.inputs:
|
|
635
|
+
- type: log
|
|
636
|
+
enabled: true
|
|
637
|
+
paths:
|
|
638
|
+
- /app/logs/*.log
|
|
639
|
+
json.keys_under_root: true
|
|
640
|
+
json.add_error_key: true
|
|
641
|
+
|
|
642
|
+
output.elasticsearch:
|
|
643
|
+
hosts: ["elasticsearch:9200"]
|
|
644
|
+
|
|
645
|
+
setup.kibana:
|
|
646
|
+
host: "kibana:5601"
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
## Backup and Recovery
|
|
650
|
+
|
|
651
|
+
### Backup Script
|
|
652
|
+
|
|
653
|
+
```bash
|
|
654
|
+
#!/bin/bash
|
|
655
|
+
# backup.sh
|
|
656
|
+
|
|
657
|
+
BACKUP_DIR="/backups"
|
|
658
|
+
DATE=$(date +%Y%m%d_%H%M%S)
|
|
659
|
+
|
|
660
|
+
# Create backup directory
|
|
661
|
+
mkdir -p $BACKUP_DIR
|
|
662
|
+
|
|
663
|
+
# Backup configuration
|
|
664
|
+
docker cp mcp-wordpress:/app/mcp-wordpress.config.json $BACKUP_DIR/config_$DATE.json
|
|
665
|
+
|
|
666
|
+
# Backup cache data
|
|
667
|
+
docker cp mcp-wordpress:/app/cache $BACKUP_DIR/cache_$DATE
|
|
668
|
+
|
|
669
|
+
# Backup logs
|
|
670
|
+
docker cp mcp-wordpress:/app/logs $BACKUP_DIR/logs_$DATE
|
|
671
|
+
|
|
672
|
+
# Create archive
|
|
673
|
+
tar -czf $BACKUP_DIR/mcp-wordpress-backup_$DATE.tar.gz \
|
|
674
|
+
$BACKUP_DIR/config_$DATE.json \
|
|
675
|
+
$BACKUP_DIR/cache_$DATE \
|
|
676
|
+
$BACKUP_DIR/logs_$DATE
|
|
677
|
+
|
|
678
|
+
# Cleanup
|
|
679
|
+
rm -rf $BACKUP_DIR/config_$DATE.json $BACKUP_DIR/cache_$DATE $BACKUP_DIR/logs_$DATE
|
|
680
|
+
|
|
681
|
+
echo "Backup completed: mcp-wordpress-backup_$DATE.tar.gz"
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
### Recovery Script
|
|
685
|
+
|
|
686
|
+
```bash
|
|
687
|
+
#!/bin/bash
|
|
688
|
+
# restore.sh
|
|
689
|
+
|
|
690
|
+
BACKUP_FILE=$1
|
|
691
|
+
RESTORE_DIR="/restore"
|
|
692
|
+
|
|
693
|
+
if [ -z "$BACKUP_FILE" ]; then
|
|
694
|
+
echo "Usage: $0 <backup_file>"
|
|
695
|
+
exit 1
|
|
696
|
+
fi
|
|
697
|
+
|
|
698
|
+
# Extract backup
|
|
699
|
+
mkdir -p $RESTORE_DIR
|
|
700
|
+
tar -xzf $BACKUP_FILE -C $RESTORE_DIR
|
|
701
|
+
|
|
702
|
+
# Restore configuration
|
|
703
|
+
docker cp $RESTORE_DIR/config_*.json mcp-wordpress:/app/mcp-wordpress.config.json
|
|
704
|
+
|
|
705
|
+
# Restore cache
|
|
706
|
+
docker cp $RESTORE_DIR/cache_* mcp-wordpress:/app/cache
|
|
707
|
+
|
|
708
|
+
# Restart container
|
|
709
|
+
docker restart mcp-wordpress
|
|
710
|
+
|
|
711
|
+
echo "Restore completed from $BACKUP_FILE"
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
## Security Hardening
|
|
715
|
+
|
|
716
|
+
### Security-Enhanced Dockerfile
|
|
717
|
+
|
|
718
|
+
```dockerfile
|
|
719
|
+
FROM node:20-alpine AS production
|
|
720
|
+
|
|
721
|
+
# Install security updates and tools
|
|
722
|
+
RUN apk update && apk upgrade && \
|
|
723
|
+
apk add --no-cache \
|
|
724
|
+
ca-certificates \
|
|
725
|
+
dumb-init \
|
|
726
|
+
&& update-ca-certificates
|
|
727
|
+
|
|
728
|
+
# Create non-root user with minimal permissions
|
|
729
|
+
RUN addgroup -g 1001 -S nodejs && \
|
|
730
|
+
adduser -S nextjs -u 1001 -G nodejs
|
|
731
|
+
|
|
732
|
+
# Set security-focused work directory
|
|
733
|
+
WORKDIR /app
|
|
734
|
+
|
|
735
|
+
# Copy application with correct ownership
|
|
736
|
+
COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
|
|
737
|
+
COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules
|
|
738
|
+
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./
|
|
739
|
+
|
|
740
|
+
# Create directories with restricted permissions
|
|
741
|
+
RUN mkdir -p cache logs && \
|
|
742
|
+
chown -R nextjs:nodejs cache logs && \
|
|
743
|
+
chmod 750 cache logs
|
|
744
|
+
|
|
745
|
+
# Remove unnecessary packages and clean up
|
|
746
|
+
RUN apk del --purge \
|
|
747
|
+
&& rm -rf /var/cache/apk/* \
|
|
748
|
+
&& rm -rf /tmp/*
|
|
749
|
+
|
|
750
|
+
# Set security labels
|
|
751
|
+
LABEL security.scan="true" \
|
|
752
|
+
security.vulnerability-scan="true"
|
|
753
|
+
|
|
754
|
+
USER nextjs
|
|
755
|
+
|
|
756
|
+
# Use dumb-init for proper signal handling
|
|
757
|
+
ENTRYPOINT ["dumb-init", "--"]
|
|
758
|
+
CMD ["node", "dist/index.js"]
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
### Security Policies
|
|
762
|
+
|
|
763
|
+
```yaml
|
|
764
|
+
# security-policy.yaml
|
|
765
|
+
apiVersion: v1
|
|
766
|
+
kind: Pod
|
|
767
|
+
metadata:
|
|
768
|
+
name: mcp-wordpress-secure
|
|
769
|
+
spec:
|
|
770
|
+
securityContext:
|
|
771
|
+
runAsNonRoot: true
|
|
772
|
+
runAsUser: 1001
|
|
773
|
+
runAsGroup: 1001
|
|
774
|
+
fsGroup: 1001
|
|
775
|
+
containers:
|
|
776
|
+
- name: mcp-wordpress
|
|
777
|
+
image: docdyhr/mcp-wordpress:latest
|
|
778
|
+
securityContext:
|
|
779
|
+
allowPrivilegeEscalation: false
|
|
780
|
+
readOnlyRootFilesystem: true
|
|
781
|
+
capabilities:
|
|
782
|
+
drop:
|
|
783
|
+
- ALL
|
|
784
|
+
volumeMounts:
|
|
785
|
+
- name: tmp-volume
|
|
786
|
+
mountPath: /tmp
|
|
787
|
+
- name: cache-volume
|
|
788
|
+
mountPath: /app/cache
|
|
789
|
+
- name: logs-volume
|
|
790
|
+
mountPath: /app/logs
|
|
791
|
+
volumes:
|
|
792
|
+
- name: tmp-volume
|
|
793
|
+
emptyDir: {}
|
|
794
|
+
- name: cache-volume
|
|
795
|
+
emptyDir: {}
|
|
796
|
+
- name: logs-volume
|
|
797
|
+
emptyDir: {}
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
This comprehensive Docker production setup provides scalable, secure, and monitored
|
|
801
|
+
deployment options for MCP WordPress in production environments.
|