Inception Bonus: Scaling the Infrastructure

It’s a simulation of Production Scaling. We are adding services that a company uses to handle traffic spikes and simplify developer workflows.
Github link: https://github.com/danoguer/inception
We are expanding our private bridge network to include four new specialized services:
| Service | Component | Role | Protocol/Port |
|---|---|---|---|
| Orchestrator | Docker Compose | Advanced IaC Management | N/A |
| Gatekeeper | NGINX | SSL Termination & Multi-Service Proxy | HTTPS (443) |
| Scholar | WordPress + PHP-FPM | Application Logic & WP-CLI Automation | FastCGI (9000) |
| Guardian | MariaDB | Persistent Data Storage | SQL (3306) |
| Accelerator | Redis | Object Caching (RAM) | Redis (6379) |
| Manager | Adminer | Database GUI (Web Interface) | HTTP/Proxy (8080) |
| Transporter | vsftpd | Direct Volume File Transfer | FTP (20-21/40000) |
| Monitor | cAdvisor | Container Metrics & Observability | HTTP (8080) |
| Showcase | Static Site | Personal Portfolio & Identity | HTTP (80) |
1. Redis: The "Fast-Memory" Strategy
In our previous article, the Scholar (WordPress) had to ask the Guardian (MariaDB) for data every time. This is slow. Redis changes the game.
What is it? Redis is an in-memory data store. Instead of querying the hard drive (MariaDB) for the same "About Me" page 100 times, WordPress saves the result in Redis (RAM).
The DevOps Setup: We run Redis in a dedicated container. In the WordPress container, we use WP-CLI to install the
redis-cacheplugin and injectWP_REDIS_HOSTintowp-config.php.wp config set WP_REDIS_HOST redis --allow-root wp config set WP_REDIS_PORT 6379 --allow-root # Writing directly to the filesystem, dont asking for FTP. wp config set FS_METHOD direct --allow-root wp plugin install redis-cache --activate --allow-root wp redis enable --allow-rootDockerfile:
# 1. Base OS FROM debian:bullseye # 2. Install Redis Server RUN apt-get update -y && apt-get upgrade -y && \ apt-get install -y redis-server # 3. Configure Redis for Docker # - Comment out "bind 127.0.0.1" so it listens to all interfaces (0.0.0.0) # - Set max memory to 256mb (to prevent it from eating your RAM) # - Set eviction policy to delete old keys when full # - Turn off protected mode so WordPress can connect RUN sed -i "s|bind 127.0.0.1|#bind 127.0.0.1|g" /etc/redis/redis.conf && \ sed -i "s|# maxmemory <bytes>|maxmemory 256mb|g" /etc/redis/redis.conf && \ sed -i "s|# maxmemory-policy noeviction|maxmemory-policy allkeys-lru|g" /etc/redis/redis.conf && \ sed -i "s|protected-mode yes|protected-mode no|g" /etc/redis/redis.conf # 4. Open the default Redis port EXPOSE 6379 # 5. Start Redis CMD ["redis-server", "--protected-mode", "no"]DevOps Insight: We use
sedto modify the configuration file during the build. This is an Automation technique that ensures the image is "Plug-and-Play" the moment it starts.Performance Impact: Your "Time to First Byte" (TTFB) drops significantly.
2. Adminer: The "Database Dashboard"
Managing a database via the command line is great for 42, but in a startup, speed is key.
The Role: Adminer is a lightweight, single-file PHP application that provides a full GUI for your MariaDB.
Security Note: Since Adminer is a "point of entry," it should be routed through our NGINX Reverse Proxy over HTTPS. It’s a dedicated service that speaks to MariaDB over the internal bridge, keeping the database itself invisible to the internet.
Dockerfile:
FROM debian:bullseye # Install PHP and the MySQL extension so it can talk to MariaDB RUN apt-get update -y && apt-get upgrade -y && \ apt-get install -y php7.4 php7.4-mysql wget # Download the Adminer script and name it adminer.php RUN wget "https://www.adminer.org/latest.php" -O /var/www/html/adminer.php # Use PHP's built-in web server to serve the file on port 8080 WORKDIR /var/www/html CMD ["php", "-S", "0.0.0.0:8080", "adminer.php"]
3. FTP Server: Direct "Guardian" Access
Sometimes you need to upload 500 images at once. Doing this through a web dashboard is a nightmare.
The Solution: A vsftpd (Very Secure FTP Daemon) container.
The Integration: We point the FTP root directory to the WordPress Volume. This allows us to "Live Edit" the site files from a local client (like FileZilla) while the changes reflect instantly in the Docker cluster.
DevOps Logic: We use Passive Mode and specific port ranges (20-21) to ensure the container networking doesn't block the file transfer.
Dockerfile:
FROM debian:bullseye
RUN apt-get update -y && apt-get upgrade -y && \
apt-get install -y vsftpd
# Copy our configuration and the start script
COPY conf/vsftpd.conf /etc/vsftpd.conf
COPY tools/setup.sh /usr/local/bin/setup.sh
RUN chmod +x /usr/local/bin/setup.sh
# FTP needs these ports: 21 (commands) and 21100-21110 (data)
EXPOSE 21 21100-21110
CMD ["/usr/local/bin/setup.sh"]
vsftpd.conf:
# Listen on IPv4 (REQUIRED for Docker) listen=YES listen_ipv6=NO # DO NOT run in the background background=NO # Standard User Settings anonymous_enable=NO local_enable=YES write_enable=YES local_root=/var/www/html chroot_local_user=YES allow_writeable_chroot=YES # Security / Docker Hacks secure_chroot_dir=/var/run/vsftpd/empty seccomp_sandbox=NO # Passive Mode (For your host connection) pasv_enable=YES pasv_min_port=21100 pasv_max_port=21110 pasv_address=127.0.0.1setup.sh
#!/bin/bash # Create the secure_chroot_dir (vsftpd will OOPS if this doesn't exist) mkdir -p /var/run/vsftpd/empty # Create the user if it doesn't exist if ! id -u "$FTP_USER" >/dev/null 2>&1; then useradd -m $FTP_USER echo "\(FTP_USER:\)FTP_PASSWORD" | chpasswd # Ensure the user can actually write to the shared volume chown -R \(FTP_USER:\)FTP_USER /var/www/html fi echo "FTP Server starting on port 21..." # Run vsftpd with the config file exec vsftpd /etc/vsftpd.conf
4. The Static Portfolio: Your Identity Site
This is a dedicated NGINX container serving only HTML/CSS. It's the perfect place to make your own portfolio.
🛠️ Key Configuration
We use a separate server block in the orchestration.
try_files \(uri \)uri/ =404;: Ensures clean URL routing.Dockerfile:
FROM debian:bullseye RUN apt-get update -y && apt-get upgrade -y && \ apt-get install -y nginx # Copy our page into the standard NGINX folder RUN rm -rf /var/www/html/* COPY index.html /var/www/html/index.html # Run NGINX in the foreground CMD ["nginx", "-g", "daemon off;"]index.html:
<!DOCTYPE html> <html> <head> <title>Portfolio - Danoguer</title> <style> body { background: #121212; color: #00ff00; font-family: monospace; text-align: center; padding-top: 50px; } h1 { border-bottom: 2px solid #00ff00; display: inline-block; } </style> </head> <body> <h1>Welcome to my 42 Inception Bonus</h1> <p>This is a static site served from a dedicated container.</p> <p>Current Status: 42 Student | Future Web Dev</p> </body> </html>
📈 5. cAdvisor: The "Internal Eye"
cAdvisor is a daemon that collects, aggregates, and exports resource usage data (CPU, Memory, Network, and Disk I/O) from your running containers.
🛠️ The "No-Config" Dockerfile
Since we are sticking to our minimalist, immutable approach, we don't use an external config file. We bake the logic into the Dockerfile and rely on the Docker Compose volume mapping to give cAdvisor access to the host's kernel data.
FROM debian:bullseye
# 1. Install wget and ca-certificates (crucial for HTTPS)
RUN apt-get update -y && \
apt-get install -y wget ca-certificates && \
rm -rf /var/lib/apt/lists/*
# 2. Download the binary (using the correct Linux-AMD64 version)
# I've updated this to v0.49.1 which is a very stable release
RUN wget https://github.com/google/cadvisor/releases/download/v0.49.1/cadvisor-v0.49.1-linux-amd64 -O /usr/bin/cadvisor
# 3. Set permissions
RUN chmod +x /usr/bin/cadvisor
EXPOSE 8080
CMD ["/usr/bin/cadvisor", "-logtostderr"]

