Skip to content

Latest commit

 

History

History
314 lines (189 loc) · 16.7 KB

File metadata and controls

314 lines (189 loc) · 16.7 KB

This project has been created as part of the 42 curriculum by iouhssei.

Inception-42

Service Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Docker Network (wp-network)             │
│                                                             │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐      │
│  │   nginx     │    │  wordpress  │    │   mariadb   │      │
│  │   :443      │───▶│    :9000    │───▶│    :3306    │      │
│  │  (HTTPS)    │    │  (PHP-FPM)  │    │   (MySQL)   │      │
│  └──────┬──────┘    └──────┬──────┘    └──────┬──────┘      │
│         │                  │                  │             │
└─────────┼──────────────────┼──────────────────┼─────────────┘
          │                  │                  │
          ▼                  ▼                  ▼
    ┌──────────┐      ┌──────────┐       ┌──────────┐
    │ Host:443 │      │ wp_data  │       │ db_data  │
    └──────────┘      └──────────┘       └──────────┘

Project Structure Overview

srcs/
├── docker-compose.yml          # Service orchestration
├── .env                        # Environment variables (create this)
└── requirements/
    ├── mariadb/
    │   ├── Dockerfile          # MariaDB container definition
    │   ├── config/
    │   │   └── 50-server.cnf   # MariaDB server configuration
    │   └── tools/
    │       └── mariadb.sh      # Database initialization script
    ├── nginx/
    │   ├── Dockerfile          # Nginx container definition
    │   └── config/
    │       └── nginx.conf      # Nginx/SSL configuration
    └── wordpress/
        ├── Dockerfile          # WordPress/PHP-FPM container
        ├── config/
        │   └── www.conf        # PHP-FPM pool configuration
        └── tools/
            └── wordpress.sh    # WordPress installation script

Makefile Commands

Command Description
make RUN Build and start all containers
make STOP Stop containers
make RESTART Restart containers
make LOGS View container logs
make PS Show container status
make STATUS Show Docker system info
make DELETE Remove containers, images, and volumes

The Story.

In the bad old days, businesses used to run one application per Windows or Linux server—a costly approach that wasted both money and resources.

Then came VMware, and everything changed. For the first time, multiple applications could run on a single physical server. While this was a huge step forward, it wasn’t perfect. Virtual machines are slow to boot, consume large amounts of RAM and CPU, and are often hard to migrate and maintain.

Hello Containers, Companies like Google had been using container technologies internally for years to overcome the limitations of traditional virtual machines. Unlike VMs, containers don’t require a full operating system for each application. Instead, they share the host OS, making them lighter, faster..

🤘

Google LLC, has contributed a lot in the container related technologies, thank you google 😊

But Containers remained complex and out of reach, till Docker came and democratized this technologies.

Docker.Inc Made Containers simple

The Big Picture.

Docker Inc, a technology based company started in San Francisco.

Docker the technology.

  • The Runtime (the lowest level)
  • The Daemon (Docker Engine)
  • The orchestrate

Main focus is managing and running application containers, and it can basically anywhere.

When you install docker you get two components

  • The Docker Client: The client talk to the daemon via a local IPC/Unix Socket in /var/run/docker.sock and in windows happened via named pipe.
  • The Docker Engine: It implement the runtime, API…

The Technical Stuff.

The Docker engine is the core software that runs and manages containers, it is modular is design and built from many small tools, and that was possible because they were based on open standards such as those maintained by Open Container Initiative (OCI), its a is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes.

  • runc is a small lightweight CLI wrapper for libcontainer, its only purpose its to create containers, its is very low level, bare bones.
  • containerd is available as daemon for linux and windows, its purpose is to manage containers life-cycle operations such as start | stop | pause | rm…
  • Namespaces: Provide isolation. Each container gets its own view of the system (PID for processes, NET for networking, MNT for the filesystem).
  • Control Groups (cgroups): Provide resource limits. They prevent a single container from eating all the host’s CPU or RAM.

Docker is not a monolithic program; it is a modular system built on top of Linux kernel features.

Starting a new container:

~ docker container run --name ilyass -it debian:latest bash

After typing this command into a Docker CLI, the docker client convert them into an appropriate API playload and POST them to the API endpoint exposed by the docker daemon. the API is exposed by the unix Socket on linux /var/run/docker.sock or in windows by named pipe. The daemon receives the command, it makes a call to containerd, the communication is set via a CRUD-style API , containerd uses runc to do that, it interfaces with OS kernel and pull out together all the constructs necessary to create a container (namespaces, cgroups…) the container process started as a child process of runc than runc will exit. after the runc exit the containerd-shim or shim for short become the parent process of the container, is integral of the implementation of the daemonless containers.

Images:

A Docker image is a unit of packaging that contains everything required for an application to run. This includes; application code, application dependencies, and OS constructs. Images are made up of multiple layers that are stacked on top of each other and represented as a single object.

Images don’t have a kernel, containers running on a docker host share the host kernel, Alpine Linux Docker Image is only 5 mb.

docker image pull <repository>:<tag> pull the image usually from the docker hub.

docker images list all images that exist locally.

docker search <name of the image> search docker hub for an image

docker image inspect <image> to see the layers and their hashes

Containers:

A container is the runtime instance of an image. the big diffrence between a VM and a container is faster and more lightweight, because the container share the host kernel.

docker container run <image> <app> create a container

docker container run -it debian:latest bash start the debian container using bash as an app, the -it will connect the bash shell to the terminal.

Container processes: the first process in the list PID 1 is the app we told the container to run, to see this run ps -elf in the connected app to the terminal, that said killing the main process in the container will kill the container.

docker container exec -it <container name> <shell>

docker container rm <image>

docker container stop

Container Life-cycle:

docker container stop <image name> will stop the container and u can list it by docker containers ls -a , docker container start <image name> will start it again.

Containerizing an app:

docker image build thsi command that reads a Dockerfile

FROM first instruction in the Dockerfile specifies the base image

RUN instruction that allow to run commands inside the image, each run create a new layer

COPY insctruction adds files into the image as a new layer

EXPOSE insctrucion documents the network port.

ENTRYPOINT instruction sets the default application to run when the image started as a container.

Docker Compose:

Docker compose is am external Python binary that can describe an entire app in a single declarative configuration file. installed on top of the docker engine.

YAML is a subset of JSON u can use JSON as compose config file.

Default name for Compose YAML file is docker-compose.yaml

docker compose build

docker compose up deploy a compose app.

docker compose down stop and delete a running compose app, delete containers and networks.

docker compose stop stop all the containers in a a compose app, you can easily restart them with restart command.

docker compose restart restart a compose app that has been stopped , note if you made changes before stopping the compose app , will not appear.

docker compose logs

docker compose rm will delete a stopped compose app deleting containers and networks.

docker compose ps list each container in the compose app

Self-healing containers with restart policies:

Always: The container restarts regardless of why it stopped. This is useful for services that should run continuously, like web servers or databases.

On-failure: The container only restarts if it exits with a non-zero status code (indicating an error).

Unless-stopped: Similar to "always," but respects manual stops. If you explicitly stop the container, it won't restart until you start it again.

Never: No automatic restart happens. You'd use this for one-off tasks or when you want full manual control.

Docker Network:

Docker Networking is bases on an open-source plug gable architecture called the Container Networking Model (CNM) libnetwork its real implementation in the Docker’s real-world written in Go, used by Docker and is where all of the core Docker networking code lives.

  • Sandbox is an isolated stack (includes Ethernet interfaces, ports. DNS config..)
  • Endpoints are virtual network interfaces.
  • Network is a software implementation of a switch.

Single-host bridge networks:

Single-Host tell us it only exists on a single Docker host and can only connect containers that are on the same host.

Bridge means that its an implementation of an 802.1d bridge.

docker network inspect command give us in low-level detail about the network.

docker network ls lists all networks on the local Docker host.

docker network create -d bridge <netname> create a new single host bridge network.

The default “bridge” network, on a linux based Docker host maps to underlying Linux bridge called docker0.

docker network inspect bridge | grep bridge

Volumes and persistent data:

They re two main type of data, persistent and non persistent.

. Persistent is the data that you need to keep.

. Non Persistent is that data that you don’t need to keep.

That sounds Simple.

Non-persistent data:

A writable container layer, that enables all read/writes operations. and its tightly coupled with the container life-cycle, managed by a storage driver.

Persistent data:

  • Volumes are not tied to the life-cycle of a container.
  • Volumes can be mapped to an external storage systems.
  • Different containers on different docker hosts can share the same volume.

docker volume create <namevol> command create an new volume.

Third-party volume are available as plugins, such cloud storage, NAS, SAN.

docker volume inspect <namevol> command inspect a specific volume.

docker volume ls list the volumes.

docker volume prune command to delete all volumes that are not mounted to a container or service**.**

docker volume rm command will delete a specific volume.

Volumes are the recommended way to work with persistent data in a Docker environment.

MariaDB.

MariaDB is an open relational database management system, used to store and organize data suing SQL (Structured Query Language).

The Short Story.

MySQL was opened source, until was bought by Sun Microsystems, Later was bought by Oracle, Now Oracle owns Oracle Database, and MySQL. Monty (The creator of MySQL and “My” it his first daughter name), feared that MySQL could become closed-source and that innovation could slow down, that why he created MariaDB as safe open source replacement, community driven. He name it after his second daughter Maria.

MariaDB Initialization Entrypoint Script

This script serves as the entrypoint for your MariaDB container in the Inception project. It handles first-time database initialization and subsequent container restarts gracefully.

Idempotency Check

The script first checks if the database already exists by looking for the directory /var/lib/mysql/${MYSQL_DATABASE}. If it exists, the container has been initialized before (data persisted via Docker volumes), so it skips setup and immediately starts MariaDB with exec mysqld. The exec command is critical—it replaces the shell process with mysqld, ensuring MariaDB becomes PID 1 and receives signals properly (required for container orchestration).

Data Directory Initialization

If the MariaDB system tables don't exist (/var/lib/mysql/mysql), the script runs mysql_install_db to create the initial database structure. This only happens on a completely fresh volume.

Temporary Server for Configuration

The script starts MariaDB temporarily with two special flags: --skip-grant-tables (allows root access without password) and --skip-networking (security measure—no TCP connections during setup). It runs in the background (&) and captures its PID for later cleanup.

Socket-Based Connection

The script waits for the Unix socket file to appear before attempting database configuration. Using socket communication (--protocol=socket) instead of TCP is more reliable during container initialization and avoids networking issues.

Database Configuration

The heredoc (<< EOSQL) executes SQL commands to: create the WordPress database, create a non-root user with remote access ('%'), remove anonymous users, restrict root to localhost, and set the root password. The backtick escaping (\${MYSQL_DATABASE}``) handles database names with special characters.

Graceful Handoff

After configuration, the temporary server is stopped with kill and wait. The script then starts the final MariaDB instance with exec, which is essential for the 42 project requirement of "one process per container"—the shell exits and mysqld becomes the main container process.

WordPress.

WordPress is a Content Management System. lets you create, manage and publish websites without written them in code, It’s written in PHP and uses MySQL / MariaDB database.

PHP-FPM (PHP FastCGI Process Management):

its a way to run PHP scripts efficiently on a web server. Nginx or Apache cannot run PHP directly, PHP-FPM runs PHP code as separate process.

FastCGI, How its works ?

For traditional CGI its create every time a new process , FastCGI solves this problem by keeping processes alive and reusing them, when it receive a request it looks at its pool of existing FastCGI processes. The process manager it can dynamically adjust the number of processes based on the load FastCGI dont have to run at the same machine as the webserver , because FastCGI communicate through its network protocol.

Resources: