Skip to content

Latest commit

 

History

History
648 lines (466 loc) · 13 KB

File metadata and controls

648 lines (466 loc) · 13 KB

DEV_DOC.md — Developer Documentation

Overview

This document provides technical guidance for developers working with the Inception project. It covers environment setup, Docker/Makefile usage, container management, and data persistence architecture.


Environment Setup From Scratch

Prerequisites

Before you begin, ensure you have installed:

# Check Docker
docker --version    # v24.0+

# Check Docker Compose
docker-compose --version    # v2.20+

# Check Make
make --version      # v4.0+

# Check git
git --version       # v2.30+

System Requirements:

  • Linux (tested on Debian 13, Ubuntu 20.04+)
  • 4GB RAM minimum (8GB recommended)
  • 20GB free disk space
  • Internet connection (for downloading images)

Step 1: Clone the Repository

git clone https://github.com/mkhavari/inception.git
cd inception

Step 2: Create Environment File

Copy and configure .env:

cp srcs/.env.example srcs/.env

Edit srcs/.env with your settings:

# Domain configuration
DOMAIN_NAME=https://mkhavari.42.fr

# WordPress admin
WP_ADMIN_USER=mkhavari
WP_ADMIN_EMAIL=your-email@example.com

# WordPress author user
WP_USER=javad
WP_USER_EMAIL=second-user@example.com

# Database configuration
WORDPRESS_DB_NAME=wordpress
WORDPRESS_DB_USER=wp_user
WORDPRESS_DB_HOST=mariadb

# FTP configuration
FTP_USER=ftpuser

# Data storage paths (adjust as needed)
WORDPRESS_DATA=/home/mkhavari/data/wordpress
MARIADB_DATA=/home/mkhavari/data/mariadb

Step 3: Configure /etc/hosts

Add your domain to the hosts file:

sudo nano /etc/hosts
# Add this line:
# 127.0.0.1  mkhavari.42.fr

Or use the Makefile:

make hosts

Step 4: Generate Secrets

Create random passwords for all services:

make secrets

This generates:

  • secrets/db_root_password.txt — MariaDB root password
  • secrets/db_password.txt — WordPress database user password
  • secrets/wp_admin_password.txt — WordPress admin password
  • secrets/wp_user_password.txt — WordPress author password
  • secrets/ftp_password.txt — FTP user password
  • secrets/portainer_pass.txt — Portainer admin password

Files are created with mode 600 (readable only by owner).

Step 5: Create Data Directories

make data

This creates:

  • /home/mkhavari/data/wordpress/ — WordPress files
  • /home/mkhavari/data/mariadb/ — Database files

Building and Launching with Makefile

Build All Images

make build

This:

  • Reads all Dockerfiles in srcs/requirements/
  • Downloads base images (Debian, Node.js, etc.)
  • Installs packages and dependencies
  • Creates custom Docker images
  • Takes 5-10 minutes on first run

View build progress:

docker images | grep "inception\|mariadb\|nginx"

Start All Services

make all

This executes in order:

  1. make hosts — Configure /etc/hosts
  2. make data — Create data directories
  3. make secrets — Generate credentials
  4. make build — Build Docker images
  5. docker-compose up -d — Start containers

Check status:

make ps

Rebuild Without Cache

Use --no-cache to force rebuild dependencies:

docker compose -f srcs/docker-compose.yml build --no-cache

Or for a specific service:

docker compose -f srcs/docker-compose.yml build --no-cache wordpress

Docker Compose Commands

Start Services (Detached)

docker-compose -f srcs/docker-compose.yml up -d

Stop Services (Keep Containers)

docker-compose -f srcs/docker-compose.yml stop

Start Stopped Services

docker-compose -f srcs/docker-compose.yml start

Restart All Services

docker-compose -f srcs/docker-compose.yml restart

Remove All Containers (Keep Volumes)

docker-compose -f srcs/docker-compose.yml down

Remove Everything (Containers + Volumes + Images)

docker-compose -f srcs/docker-compose.yml down --rmi all --volumes

Container Management Commands

List All Containers

docker ps -a

View Container Logs

# Latest logs
docker logs nginx

# Follow logs in real-time
docker logs -f wordpress

# Last 50 lines
docker logs --tail 50 mariadb

# With timestamps
docker logs -t redis

Execute Command Inside Container

# Interactive bash shell
docker exec -it wordpress bash

# Run single command
docker exec wordpress wp core version --allow-root

# Run with environment variables
docker exec -e VAR=value wordpress command

Inspect Container Details

# Full container info
docker inspect wordpress

# Just IP address
docker inspect -f '{{.NetworkSettings.IPAddress}}' wordpress

# Resource usage
docker stats wordpress

Restart a Service

docker restart wordpress
docker restart mariadb
docker restart nginx

View Container Processes

docker exec wordpress ps aux
docker exec mariadb ps aux

Volume Management

Understanding Volumes in This Project

Docker-managed volumes (for production data):

volumes:
  wordpress:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${WORDPRESS_DATA}

  mariadb:
    driver: local

Bind mounts (for development):

volumes:
  - ./requirements/bonus/static/portfolio:/app  # React source code

List All Volumes

docker volume ls

Inspect a Volume

docker volume inspect inception_wordpress
docker volume inspect inception_mariadb

View Volume Contents

# WordPress files
ls -la /home/mkhavari/data/wordpress/

# Database files
ls -la /home/mkhavari/data/mariadb/

Backup a Volume

# Backup WordPress volume
docker run --rm -v inception_wordpress:/data \
  -v $(pwd):/backup alpine \
  tar -czf /backup/wordpress_backup.tar.gz -C /data .

# Backup Database volume
docker run --rm -v inception_mariadb:/data \
  -v $(pwd):/backup alpine \
  tar -czf /backup/mariadb_backup.tar.gz -C /data .

Restore a Volume

# Create a temporary container and restore
docker run --rm -v inception_wordpress:/data \
  -v $(pwd):/backup alpine \
  tar -xzf /backup/wordpress_backup.tar.gz -C /data

Remove a Volume

docker volume rm inception_wordpress

⚠️ Warning: Removing a volume deletes all data.


Data Storage and Persistence

Where Data Is Stored

Host Machine
├── /home/mkhavari/data/
│   ├── wordpress/              # WordPress files, uploads, plugins
│   │   ├── wp-config.php
│   │   ├── wp-content/
│   │   ├── wp-admin/
│   │   └── index.php
│   └── mariadb/                # Database files (InnoDB tables)
│       ├── mysql/
│       ├── wordpress/
│       └── ibdata1
└── Docker-managed
    └── portainer_data/         # Portainer configuration

How Persistence Works

Bind Mounts (WordPress & MariaDB):

  • ${WORDPRESS_DATA}:/var/www/html — WordPress directory
  • ${MARIADB_DATA}:/var/lib/mysql — Database directory
  • Changes on host immediately visible in container
  • Survives container deletion

Docker Volumes (Portainer):

  • Managed by Docker daemon
  • Stored in /var/lib/docker/volumes/
  • Requires docker volume commands to access

Data Lifecycle

  1. Container Creation: Docker mounts existing volumes
  2. Container Running: All changes written to volumes
  3. Container Stopped: Data persists in volumes
  4. Container Deleted: Volumes persist (unless explicitly removed)
  5. Clean: make fclean removes everything including data

Backup Strategy

Daily backup script:

#!/bin/bash
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_DIR="/backups"

# Backup WordPress
tar -czf $BACKUP_DIR/wordpress_$DATE.tar.gz /home/mkhavari/data/wordpress/

# Backup Database
docker exec inception_mariadb mysqldump -u root \
  -p$(cat secrets/db_root_password.txt) wordpress \
  > $BACKUP_DIR/wordpress_db_$DATE.sql

Makefile Targets Reference

Target Purpose
make all Full setup and start (recommended for first run)
make hosts Add domain to /etc/hosts
make data Create data directories
make secrets Generate random passwords
make build Build Docker images
make up Start containers (detached)
make down Stop and remove containers
make stop Stop containers (keep them)
make start Start stopped containers
make ps List containers and status
make restart Restart all containers
make clean Remove containers, images, volumes
make fclean Remove everything including host data
make re Full rebuild from scratch

Docker Network Architecture

Inside the Network

All containers communicate on custom bridge network inception:

┌─────────────────────────────────────────┐
│      Docker Network: inception          │
├──────────┬──────────┬───────────────────┤
│  Nginx   │WordPress │    MariaDB        │
│  :443    │  :9000   │     :3306         │
│ port 443 │(internal)│  (internal)       │
└──────────┴──────────┴───────────────────┘

DNS Resolution Inside Containers

Containers resolve service names automatically:

  • wordpress:9000 — PHP-FPM from nginx
  • mariadb:3306 — Database from WordPress
  • redis:6379 — Cache from WordPress

Port Mapping

Only exposed ports reach the host:

ports:
  - "443:443"      # Nginx HTTPS (public)
  - "5173:5173"    # React portfolio (dev)
  - "8080:8080"    # Adminer (admin)
  - "9443:9443"    # Portainer (admin)
  - "21:21"        # FTP (public)
  - "21100-21110:21100-21110"  # FTP passive ports

Internal services (MariaDB, PHP-FPM, Redis) are not exposed.


Debugging & Troubleshooting

Check Container Health

# Is container running?
docker ps | grep wordpress

# What's the exit code?
docker inspect -f '{{.State.ExitCode}}' wordpress

# View startup logs
docker logs wordpress | head -50

Database Connection Issues

# Test connection from WordPress container
docker exec -it wordpress bash -c \
  'mysql -hmariadb -u wp_user -p"$(cat /run/secrets/db_password)" -e "SELECT 1;"'

# Check MariaDB logs
docker logs mariadb | grep -i "error\|ready"

Network Diagnosis

# Test DNS resolution
docker exec wordpress nslookup mariadb

# Test port connectivity
docker exec wordpress nc -zv mariadb 3306

# View network details
docker network inspect inception

File Permission Issues

# Check ownership in WordPress container
docker exec wordpress ls -la /var/www/html/

# Fix ownership
docker exec wordpress chown -R www-data:www-data /var/www/html/

Memory and CPU Usage

# Real-time stats
docker stats

# Limit container memory (after creation)
docker update --memory 512m wordpress

Development Workflow

Make Changes to Code

React Portfolio:

# Changes in ./srcs/requirements/bonus/static/portfolio/
# Automatically reload at http://localhost:5173 (HMR)

WordPress Code:

# Changes in /home/mkhavari/data/wordpress/
# Immediately visible at https://mkhavari.42.fr

PHP/Config:

# Edit php-fpm config in ./srcs/requirements/wordpress/conf/www.conf
# Rebuild: docker compose build --no-cache wordpress
# Restart: docker restart wordpress

Rebuild After Changes

# Rebuild specific service
make build

# Rebuild without cache (slower, cleaner)
docker compose -f srcs/docker-compose.yml build --no-cache wordpress

# Restart after rebuild
docker restart wordpress

View Live Logs

# Follow WordPress errors as they happen
docker logs -f wordpress

# All container logs simultaneously
docker compose -f srcs/docker-compose.yml logs -f

CI/CD Considerations

Automated Testing

# Verify WordPress is accessible
curl -k https://mkhavari.42.fr/

# Verify database
docker exec wordpress wp core is-installed --allow-root

# Verify Redis
docker exec redis redis-cli ping

Health Checks

Add to services for automated restarts:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 30s
  timeout: 10s
  retries: 3

Security Considerations

Secrets Management

  • Never commit secrets/*.txt to git
  • Regenerate secrets for production
  • Use strong passwords (generated with openssl rand)

Network Security

  • No network_mode: host ✅ (isolated)
  • No links: deprecated feature ✅
  • Custom bridge network ✅

Volume Security

  • Database files owned by mysql:mysql
  • WordPress files owned by www-data:www-data
  • Secrets readable only by root (600 permissions)

Contact & Support

For technical questions, refer to:

  • Project README.md
  • Individual Dockerfile comments
  • entrypoint.sh scripts for initialization logic
  • USER_DOC.md for end-user features