Operations server had grown into a fragile collection of critical tools—Drupal dashboards, Jenkins jobs, file access utilities—all running together on a single VM. Over time, manual configuration changes and dependency conflicts made updates risky and disaster recovery slow.
🚧 Challenge
Services were tightly coupled, making it difficult to upgrade one without impacting others.
Security and reliability risks from shared environments.
No straightforward way to reproduce the setup for scaling or recovery.
💡 Solution
I redesigned the Ops server architecture to run entirely in containers, orchestrated with Docker Compose.
Containerized Services:
Drupal — Dashboard monitoring the status of all client Drupal sites.
FileStash — Web access to backups stored in AWS S3.
Jenkins — Company-wide automation and CI/CD jobs.
Jenkins Agent — Isolated for security and load distribution.
Nginx — Reverse proxy to route requests between services.
Certbot — Automated TLS certificate generation and renewal.
Designed modular configuration for independent updates and restarts.
Implemented internal networking and environment variables for clean, reproducible deployments.
📈 Impact
Downtime reduced — Updates completed in minutes instead of hours.
Improved disaster recovery — Entire stack can be redeployed quickly from configuration files.
Enhanced security — Service isolation reduced attack surface.
Scalability ready — Components can be swapped or scaled independently.