"Inception = A Docker based infrastructure project that simulates a production like hosting environment by orchestrating multiple interconnected services."
To truly understand what this project does, you need to understand what happens before any container is ever created.
When you first get a physical server, it's literally just hardware:
- CPU, RAM, hard drive, network cardβ¦
- But no operating system, no applications, no data.
It's like buying a brand-new computer without Windows or Linux β it can't do anything yet.
Just like your laptop runs macOS, Windows, or Linux, your server needs an OS β though servers almost always run a server version of Linux (not Windows or macOS):
| OS | Use Case |
|---|---|
| Ubuntu Server | General purpose, beginner-friendly |
| Debian | Stable, minimal, widely used |
| CentOS / Rocky Linux | Enterprise environments |
The OS is what lets you: store files, run programs, connect to the internet, and accept requests.
Now your OS is ready β but it still doesn't know what kind of server it should be. You install specific software to give it a purpose:
| Type of Server | Software Example | What It Does |
|---|---|---|
| Web server | Nginx, Apache | Serves web pages (HTML, CSS, JS) |
| Database server | MariaDB, MySQL, PostgreSQL | Stores and provides structured data |
| Application server | PHP-FPM, Node.js, Django | Runs backend logic or APIs |
| File server | Samba, FTP, NFS | Stores and shares files |
Inception builds a mini web hosting environment on your local machine using Docker β inspired by how modern hosting platforms and cloud providers deploy applications.
| Component | Role |
|---|---|
| Nginx | Receives requests, serves pages, routes PHP requests (reverse proxy) |
| WordPress / PHP-FPM | Runs the website's code and generates pages dynamically |
| MariaDB | Stores website data (posts, users, settings, etc.) |
| Docker Network | Connects containers securely and privately |
| Docker Volumes | Keeps data persistent between container restarts |
| Makefile | Automates building, starting, and stopping the environment |
- β How to isolate services using containers
- β How to connect them securely and persist data
- β How to automate deployment with a Makefile
- β Understanding real-world web hosting architecture
- β Foundation of cloud hosting, networking, and DevOps
Browser β Nginx β WordPress/PHP-FPM β MariaDB β Nginx β Browser
flowchart TD
Browser["π Browser"] -->|"HTTPS Request"| Nginx["π© Nginx\n(Reverse Proxy)"]
Nginx -->|"Static files"| Static["π Static Assets\n(HTML/CSS/JS)"]
Nginx -->|"PHP requests\n(FastCGI)"| WordPress["π΅ WordPress\n(PHP-FPM)"]
WordPress -->|"SQL Queries"| MariaDB["π MariaDB\n(Database)"]
MariaDB -->|"Query Results"| WordPress
WordPress -->|"Generated HTML"| Nginx
Nginx -->|"Final Response"| Browser
subgraph volumes["πΎ Persistent Volumes"]
DBVol["π¦ DB Volume\n/home/user/data/db"]
WPVol["π¦ WP Volume\n/home/user/data/wp"]
end
MariaDB --- DBVol
WordPress --- WPVol
subgraph network["π Docker Network (inception)"]
Nginx
WordPress
MariaDB
end
Inception/
βββ Makefile # Automation commands
βββ srcs/
β βββ docker-compose.yml # Orchestrates all services
β βββ requirements/
β βββ nginx/ # Nginx container definition
β β βββ Dockerfile
β β βββ conf/
β βββ wordpress/ # WordPress + PHP-FPM container
β β βββ Dockerfile
β β βββ conf/
β βββ mariadb/ # MariaDB container definition
β βββ Dockerfile
β βββ conf/
βββ secrets/ # Sensitive credentials (not committed)
Imagine you bake a cake π°. To make it, you need:
- Ingredients (flour, eggs, sugarβ¦) β libraries & dependencies
- Tools (oven, bowl, spoonβ¦) β runtime environment
- A recipe (the steps to follow) β your code
If you send only your recipe to a friend but they don't have the same tools or ingredients β they won't be able to make the same cake.
This is the "it works on my computer" problem π
A container is like a box that you put your program + everything it needs inside:
- The program's code
- The libraries
- The tools it uses
- The settings it needs
When you give this box to someone else, they just open it β and everything works perfectly, no matter what computer they're using.
Instead of saying:
"Install Python 3.10, Flask library, and change this configuration fileβ¦"
You just run:
docker run mywebsiteπ§© A container is a small box that holds a program and everything it needs, so it can run anywhere easily and safely.
A virtual machine is like a big fake computer inside your real computer.
It has:
- Its own full operating system (like Windows or Linux)
- Its own apps
- Its own virtual hardware (CPU, memory, disk)
βββββββββββββββββββββββββββββββββββββββ
β Physical Machine β
β βββββββββββββββββββββββββββββββ β
β β Hypervisor β β
β β ββββββββββββ ββββββββββββ β β
β β β VM 1 β β VM 2 β β β
β β β Full OS β β Full OS β β β
β β β + App 1 β β + App 2 β β β
β β ββββββββββββ ββββββββββββ β β
β βββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββ
A container isolates programs β but it's much lighter.
Instead of creating a new fake computer with its own OS, containers share the host's operating system kernel. They only isolate:
- The program
- Its files
- Its libraries
βββββββββββββββββββββββββββββββββββββββ
β Physical Machine β
β βββββββββββββββββββββββββββββββ β
β β Host Operating System β β
β β ββββββββββ ββββββββββ β β
β β β Cont.1 β β Cont.2 β β β
β β β App + β β App + β β β
β β β Libs β β Libs β β β
β β ββββββββββ ββββββββββ β β
β βββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββ
β Lightweight and fast β containers start in seconds and use minimal resources.
Great question! Containers share the host's OS kernel:
- A Linux container can only work on a Linux kernel
- A Windows container can only work on a Windows kernel
Docker's trick: When you install Docker Desktop on Windows or macOS, it secretly runs a small hidden Linux virtual machine in the background π§.
Your App β Linux Container β Tiny Hidden Linux VM β Windows/macOS Host
| Host System | What Docker Does | What Containers Use |
|---|---|---|
| Linux | Runs containers directly | Shares Linux kernel |
| Windows/macOS | Runs a lightweight Linux VM | Containers share that Linux kernel |
| Feature | Container | Virtual Machine |
|---|---|---|
| Startup time | Seconds β‘ | Minutes π’ |
| Size | MBs π¦ | GBs πΎ |
| OS included | No (shares host kernel) | Yes (full OS) |
| Isolation | Process-level | Hardware-level |
| Performance | Near-native | Some overhead |
| Use case | Microservices, apps | Full OS environments |
Docker is not a container itself β it's a platform that automates and simplifies everything needed to run containers.
If you tried to make a container yourself, you'd have to:
- Create an isolated filesystem manually
- Configure Linux namespaces (process, network, file isolation)
- Manage cgroups to control CPU/RAM usage
- Set up virtual networking for your container
- Handle storage layers
β‘οΈ Building containers by hand would be like assembling an OS from scratch every time.
Docker automates all of this:
- Builds images (from a
Dockerfile) - Runs containers (using
docker run) - Manages networking, volumes, and resources
- Provides registries (Docker Hub) to share and pull prebuilt images
- Ensures consistency β your app runs the same everywhere
Think of it like a boxed meal recipe:
- It tells Docker what ingredients you need (software, libraries)
- And how to set everything up (commands)
- Read-only β you can share this recipe with anyone
# Example: pull a prebuilt image
docker pull nginxThis is the meal you cook from the recipe.
- Once you "run" an image, it becomes a container
- It's the actual app running in a small isolated environment
- Each container is separate from others
# Run a container from an image
docker run nginxThis is how you write your own recipe. A simple text file with build instructions:
FROM debian:bullseye
RUN apt-get update && apt-get install -y nginx
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]Containers are temporary. If you delete them, all data inside is gone.
A volume is like a storage box outside the container:
- Important data is stored there
- It survives even if the container is deleted
# Mount a volume
docker run -v /host/path:/container/path nginxExample: Database files β stored in a volume, not inside the container.
Containers need to talk to each other. A network is like a private hallway connecting containers:
- Only containers on the same network can communicate directly
- Provides secure, isolated communication
# docker-compose.yml
networks:
inception:
driver: bridgeExample: WordPress container talks to MariaDB container through the
inceptionnetwork.
Running many containers at once manually is hard. Compose is a script that starts all containers together β like a manager telling each chef: "start cooking, here's your station."
# Start everything with one command
docker compose up --buildDocker CLI (docker command)
β
Docker Engine (dockerd daemon) β interacts with Linux Kernel
β
Namespaces + Cgroups + Filesystem
β
Container processes (isolated, resource-limited)
Main Docker Components:
| Component | Role |
|---|---|
| Docker Engine (dockerd) | Core daemon β creates containers, manages images/networking/storage |
| Docker CLI | The docker command β sends instructions to Engine |
| Docker Images | Read-only templates with app + dependencies |
| Docker Containers | Running instances of images |
| Docker Compose | Defines and runs multi-container apps via YAML |
| Docker Hub/Registry | Store and share images online |
| Docker Volumes | Persistent storage for containers |
Namespaces and Cgroups are Linux kernel features β the actual mechanism that makes containers possible.
Namespaces make processes think they have their own separate view of system resources, even though they share the same kernel.
| Namespace | What It Isolates |
|---|---|
| PID | Each container has its own process tree |
| Network | Each container has its own network interfaces & IP |
| Mount | Containers have their own filesystem view |
| UTS | Allows containers to have their own hostname |
| IPC | Isolates inter-process communication |
| User | Maps container users to different host users |
β Effect: Containers feel like they are running on their own independent machine, but share the same OS kernel.
Control Groups let you limit, prioritize, and monitor resources that processes can use:
| Resource | What You Can Control |
|---|---|
| CPU | Limit how much CPU time a container gets |
| Memory | Cap how much RAM a container can use |
| Disk I/O | Limit read/write speed |
| Network | Control network bandwidth |
Example: You can run 3 containers on the same host but ensure no single container can hog all the CPU or memory.
MariaDB is a database server β it stores data in an organized way so applications can:
- Save information
- Read information
- Update information
- Delete information
Just like your phone contacts app stores names + numbers, WordPress stores:
- Posts & pages
- Comments
- Users & passwords
- Site settings
π MariaDB is the place where WordPress stores ALL its data.
WordPress cannot store data directly in files for everything β it needs a database to organize its dynamic content. Without MariaDB β WordPress cannot work.
You do NOT build MariaDB itself β MariaDB is a complete, existing database engine.
What you DO build is the Docker container that:
- Starts from a minimal Linux image (Debian)
- Installs MariaDB via the package manager (
apt) - Configures it with the right settings
- Runs initialization scripts to set up the WordPress database
- Keeps data persistent via Docker volumes
FROM debian:bullseye
RUN apt-get update && apt-get install -y mariadb-server
COPY ./conf/my.cnf /etc/mysql/my.cnf
COPY ./tools/init_db.sh /init_db.sh
ENTRYPOINT ["/init_db.sh"]| Component | Role |
|---|---|
| PHP | Server-side scripting language that generates dynamic HTML |
| PHP-FPM | The engine/daemon that actually runs PHP scripts efficiently |
| Nginx | The web server that receives requests and decides how to handle them |
1. π Browser requests: GET /index.php
β
2. π© Nginx receives the request
β
3. π€ Nginx checks: Is this a static file or PHP?
βββ Static file (HTML/CSS/JS/Image)?
β β Nginx serves it directly β‘
βββ PHP script?
β Nginx forwards to PHP-FPM via FastCGI
β
4. π΅ PHP-FPM runs the PHP code:
- Queries MariaDB for data
- Processes business logic
- Generates dynamic HTML
β
5. π© PHP-FPM sends generated HTML back to Nginx
β
6. π Nginx sends final HTML to the browser
β
7. π₯οΈ Browser displays the page
- Nginx is extremely fast for serving static files
- PHP-FPM efficiently processes PHP using worker pools (handles many requests simultaneously)
- Together they create a fast, scalable, and secure architecture
- This is the standard setup for WordPress, Laravel, and most PHP applications
| PHP | PHP-FPM | |
|---|---|---|
| What it is | The language | The process manager |
| Role | Defines syntax & features | Runs PHP scripts efficiently |
| Analogy | A cooking language/recipe | The chef who actually cooks |
π‘ In one sentence: Nginx handles incoming requests, PHP-FPM executes PHP code to generate output, and the browser receives only the final HTML.
- Docker installed
- Docker Compose installed
makeavailable on your system
git clone https://github.com/Samia-Hb/Inception.git
cd InceptionEdit the .env file inside srcs/ with your credentials:
# Database
MYSQL_DATABASE=wordpress
MYSQL_USER=wp_user
MYSQL_PASSWORD=your_secure_password
MYSQL_ROOT_PASSWORD=your_root_password
# WordPress
WP_ADMIN_USER=admin
WP_ADMIN_PASSWORD=your_admin_password
WP_ADMIN_EMAIL=admin@example.com
DOMAIN_NAME=login.42.fr # Replace with your actual 42 login (e.g., jdoe.42.fr)
β οΈ Domain Setup: The domainlogin.42.fr(whereloginis your 42 username) must resolve to your local machine. Add it to your/etc/hostsfile:echo "127.0.0.1 login.42.fr" | sudo tee -a /etc/hosts
make build # Build all containers from Dockerfiles
make # Start the full environment| Service | URL |
|---|---|
| WordPress | https://login.42.fr (replace login with your 42 username) |
| MariaDB | Internal (port 3306, container network only) |
| Command | Description |
|---|---|
make or make all |
Start all services (creates volumes if needed) |
make build |
Build and start all containers |
make down |
Stop all services |
make re |
Restart all services |
make clean |
Stop and remove containers, images, and volumes |
make fclean |
Full cleanup including persistent data on disk |
# Check logs for a specific service
docker compose -f srcs/docker-compose.yml logs nginx
docker compose -f srcs/docker-compose.yml logs wordpress
docker compose -f srcs/docker-compose.yml logs mariadb- Verify
.envcredentials match between WordPress and MariaDB configs - Ensure MariaDB container fully initialized before WordPress starts (check healthcheck)
# Check what's using port 443
sudo lsof -i :443make fclean # Removes everything including data volumes
make build # Rebuild from scratch| Inception (Local) | Cloud Provider (AWS/Azure/GCP) |
|---|---|
| Docker containers | Virtual machines / containers |
| Docker volumes | Cloud storage (EBS, Azure Disk) |
| Docker network | VPC / Virtual Network |
| Makefile automation | Terraform / CloudFormation |
login.42.fr |
Your actual domain name |
Every large-scale cloud infrastructure starts with the same building blocks you're learning here.
Made with β€οΈ by Samia-Hb
"Tell me and I forget. Teach me and I remember. Involve me and I learn." β Benjamin Franklin