mcp-wordpress 2.3.0 → 2.4.1

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.
Files changed (36) hide show
  1. package/README.md +511 -0
  2. package/dist/client/api.d.ts +90 -0
  3. package/dist/client/api.d.ts.map +1 -1
  4. package/dist/client/api.js +90 -0
  5. package/dist/client/api.js.map +1 -1
  6. package/dist/tools/media.d.ts +43 -4
  7. package/dist/tools/media.d.ts.map +1 -1
  8. package/dist/tools/media.js +43 -4
  9. package/dist/tools/media.js.map +1 -1
  10. package/dist/tools/posts.d.ts +225 -4
  11. package/dist/tools/posts.d.ts.map +1 -1
  12. package/dist/tools/posts.js +225 -4
  13. package/dist/tools/posts.js.map +1 -1
  14. package/docs/DOCKER_PUBLISHING_TROUBLESHOOTING.md +233 -0
  15. package/docs/PUBLISHING-TROUBLESHOOTING.md +227 -0
  16. package/docs/api/README.md +53 -11
  17. package/docs/api/openapi.json +10 -10
  18. package/docs/api/summary.json +1 -1
  19. package/docs/api/tools/wp_create_post.md +9 -3
  20. package/docs/api/tools/wp_delete_post.md +2 -3
  21. package/docs/api/tools/wp_get_current_user.md +7 -1
  22. package/docs/api/tools/wp_get_post.md +2 -3
  23. package/docs/api/tools/wp_get_post_revisions.md +1 -1
  24. package/docs/api/tools/wp_list_posts.md +10 -3
  25. package/docs/api/tools/wp_list_users.md +8 -1
  26. package/docs/api/tools/wp_search_site.md +8 -1
  27. package/docs/api/tools/wp_test_auth.md +8 -1
  28. package/docs/api/tools/wp_update_post.md +2 -3
  29. package/docs/examples/docker-production.md +801 -0
  30. package/docs/examples/multi-site-setup.md +575 -0
  31. package/docs/examples/single-site-setup.md +390 -0
  32. package/docs/examples/use-case-workflows.md +469 -0
  33. package/package.json +12 -2
  34. package/src/client/api.ts +90 -0
  35. package/src/tools/media.ts +43 -4
  36. 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.