This project aims to broaden your knowledge of system administration by using Docker.
In this guide, I'll walk you through setting up the required infrastructure step by step, making it simple and enjoyable. Take your time to read, check out the shared links, experiment, and have fun while learning!
- Introduction to Docker
- NGINX Container Setup
- MariaDB Container Setup
- WordPress Container Setup with PHP-FPM
- Docker-Compose Setup
- Understanding Networking in Docker
- Finalizing the Project
- Conclusion
Docker is an open-source platform for developing, shipping, and running applications in an isolated environment called a container
. It enables you to separate applications from your infrastructure, ensuring quick and consistent software delivery.
Containers has their own OS and all, except that unlike virtual machines they don’t simulate the entire computer, but rather create a sand boxed environment that pretends to be a virtual machine. They are lightweight
and contain everything needed to run the application, so you don't need to rely on what's installed on the host. You can share containers while you work, and be sure that everyone you share with gets the same container that works in the same way.
- Solves the
"Works on my machine"
problem. Docker containers ensure that applications run consistently across different environments by bundling the application with all its dependencies. - Docker containers are lightweight and provide isolated environments for running applications.
- Docker containers are portable and can run on any platform that supports Docker (
Linux
,macOS
,Windows
,cloud platforms
). - Applications packaged in Docker containers can be easily moved between
development
,testing
, andproduction
systems. - Docker images include everything needed to run an application:
code
,runtime
,libraries
, anddependencies
. - Faster startup times and reduced resource usage compared to VMs, because they share the host operating system's kernel.
Docker operates using a client-server architecture, consisting of:
Docker Client
: A command-line interface for interacting with Docker.Docker Daemon
: Handles the heavy lifting of building, running, and managing containers.Docker Registries
: Store Docker images. LikeDocker Hub
(public registry) and private registries.
An image is a read-only template with instructions for creating a container.
Use a Dockerfile
to build images. Each step in a Dockerfile creates a layer
, making updates efficient.
A container is a runnable instance of an image. Containers are isolated from one another and the host system by default.
Volumes in Docker are a feature for managing persistent data in containers. Containers are ephemeral
by nature, meaning data inside them is lost when the container stops or is removed. Volumes provide a way to persist and share data between containers and the host system, ensuring data remains available even if a container is restarted, stopped, or deleted.
- Named Volumes:
- Created and managed by Docker.
- Stored in Docker's managed storage directory on the host (e.g.,
/var/lib/docker/volumes
). - Good for long-term data persistence.
- Bind Mounts:
- Maps a specific directory or file on the host to a container.
- More flexibility because you control the exact location of the data.
- Useful for local development or when sharing specific files.
docker run <image> # Run a container from an image
docker ps # List running containers
docker stop <container> # Stop a running container
docker start <container> # Start a stopped container
docker rm <container> # Remove a container
docker rmi <image> # Remove an image
docker images # List locally stored images
docker build -t <tag> <path> # Build an image from a Dockerfile
docker pull <image> # Pull an image from Docker Hub
docker push <image> # Push an image to a registry
docker exec -it <container> <command> # Run a command inside a running container
docker logs <container> # Display container logs
docker stats # Show resource usage
docker system prune # Clean up unused containers, images, networks, and volumes
docker volume prune # Remove unused volumes
docker network prune # Remove unused networks
In Docker containers, PID 1
is the process ID of the first process started within the container. This process is critical because:
- Lifecycle Management: When the process with PID 1 exits, the container stops.
- Signal Handling: PID 1 is responsible for handling signals (e.g.,
SIGTERM
,SIGKILL
). However, many applications don't handle signals correctly when running as PID 1, which can cause issues during container shutdown. - Zombie Process Reaping: PID 1 is responsible for reaping zombie processes (child processes that have terminated but are not properly cleaned up). If PID 1 does not perform this task, it can lead to resource leaks.
NGINX is a powerful open-source web server and reverse proxy software, renowned for its high performance, scalability, and reliability. It's widely adopted in modern web development and system administration for tasks such as:
Reverse proxying
: Directing client requests to different servers based on predefined rules.Load balancing
: Distributing incoming traffic across multiple servers to optimize resource utilization and ensure availability.Caching
: Storing frequently requested content to reduce server load and improve response times.Serving static files
: Efficiently delivering images, CSS, JavaScript, and other static assets.Providing HTTPS server capabilities
: Providing encryption for secure communication between clients and servers.
In this project, NGINX serves as the web server for the WordPress site, handling secure connections and static file delivery.
Before diving into the setup, take some time to explore these resources for a deeper understanding of how NGINX works: ⬇️
By familiarizing yourself with these resources, you'll better understand how to utilize NGINX effectively in your projects.
This section provides a detailed explanation of the Dockerfile
, outlining each step and why it is essential in setting up the Docker container for NGINX.
Now, you should be ready to start creating the NGINX container! By this point, you understand how to write a Dockerfile
, configure NGINX, and how it works. You've also gone through the project requirements multiple times and have a clear understanding of what needs to be done.
- Base Image
FROM debian:bullseye
- The base image
debian:bullseye
provides a lightweight and stable Linux environment. - Using a minimal image reduces unnecessary bloat and focuses only on the essentials required for NGINX and SSL setup.
- Debian is a common choice for server environments due to its reliability and support for many packages.
- Update and Install Packages
RUN apt update -y && apt upgrade -y && \
apt install -y nginx openssl
- Why Update and Upgrade?
apt update
ensures the package list is current, retrieving the latest versions from the repositories.apt upgrade
updates installed packages to their latest stable versions for security and performance improvements.
- Why Install These Packages?
nginx
: This is the core of the container, acting as the web server for the WordPress site.openssl
: Provides tools for creating SSL/TLS certificates, enabling secure HTTPS connections.
- Generate SSL Certificate
RUN mkdir -p /etc/nginx/ssl && \
openssl req -x509 -nodes \
-days 365 \
-keyout /etc/nginx/ssl/inception.key \
-out /etc/nginx/ssl/inception.crt \
-subj "/CN=${DOMAIN_NAME}"
Why Use SSL?
SSL/TLS encrypts communication between the server and clients, ensuring data security and trust. A self-signed certificate is created here for testing purposes:
- Command Breakdown:
mkdir -p /etc/nginx/ssl
: Creates the directory to store SSL files. The-p
flag ensures parent directories are created if they don't exist.openssl req
: Initiates certificate creation.-x509
: Creates an X.509 certificate.-nodes
: No password is required for the private key.-days 365
: Sets the certificate validity to 1 year.-subj
: Defines certificate details.
- Prepare NGINX Directories
RUN mkdir -p /var/www/wordpress /var/run/nginx && \
chmod 755 /var/www/wordpress && \
chown -R www-data:www-data /var/www/wordpress
/var/www/wordpress
: Directory for WordPress./var/run/nginx
: Required for NGINX runtime operations.
Ownership and permissions are set for the www-data
user, which NGINX uses to serve content. Without this, you could encounter "permission denied" errors.
- Copy Configuration
COPY conf/nginx.conf /etc/nginx/nginx.conf
The custom nginx.conf
file is copied into the container at /etc/nginx/nginx.conf
. (We will delve deeper into nginx.conf
in its own section)
- Why Custom Configuration?
- The default NGINX configuration may not support the specific requirements of this project, such as WordPress or reverse proxying.
- The custom configuration will be tailored to enable TLS, define root directories, and set up PHP processing.
- Set the Default Command
CMD ["nginx", "-g", "daemon off;"]
- Purpose of This Command:
- Runs NGINX in the foreground (
daemon off
), ensuring the container stays alive. - If NGINX runs in the background (
daemon on
), the container will stop immediately after execution.
- Why Use CMD?
- The
CMD
instruction sets the default command that the container executes when started. - It ensures NGINX is ready to serve requests as soon as the container starts.
By following this Dockerfile
, you'll have a secure, performant NGINX container configured to serve your WordPress site with HTTPS enabled.
The way NGINX and its modules work is determined by the configuration file. By default, the configuration file is named nginx.conf
and is located in one of the following directories:
/usr/local/nginx/conf
/etc/nginx
/usr/local/etc/nginx
Below, we'll break down the critical components of the configuration file to understand their roles and purpose.
- Events Block
The events
block is a placeholder necessary for the NGINX configuration:
events {}
- HTTP Block
Defines the core HTTP
settings and behavior:
http {
include /etc/nginx/mime.types;
# Additional configuration can go here
...
}
MIME
types describe the media type of content served by web servers or web applications. They are intended to help provide a hint as to how the content should be processed and displayed. Examples of MIME types:text/html
for HTML documents.text/plain
for plain text.text/css
for CSS stylesheets.
- HTTPS Server Block
The server
block configures an HTTPS server. In this project, it is responsible for serving the WordPress site securely:
server {
listen 443 ssl;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_certificate /etc/nginx/ssl/inception.crt;
ssl_certificate_key /etc/nginx/ssl/inception.key;
root /var/www/wordpress;
server_name ${DOMAIN_NAME};
index index.php index.html index.htm;
# Add other configuration blocks here
...
}
listen 443 ssl;
: Specifies that the server will listen for HTTPS traffic on port 443.SSL Protocols
: Restricts connections to use TLSv1.2 and TLSv1.3 for better security.SSL Certificate and Key
: Defines the paths to the SSL certificate and private key files.root
andindex
: Specifies the root directory for WordPress files and default files to serve.server_name
: Specifies the domain name. For testing purposes, you can set it to localhost for now.
- Location Blocks
Defines rules for serving specific types of requests.
Root Location
Handles requests for static files or directories:
location / {
try_files $uri $uri/ =404;
}
$uri
: Tries to serve the requested file.$uri/
: Tries to serve the requested directory.=404
: Returns a 404 error if neither exists.
PHP Processing
Directs .php
files to PHP-FPM for processing:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass wordpress:9000;
}
- Matches
.php
files for PHP-FPM processing. fastcgi_pass wordpress:9000;
assumes a Docker container namedwordpress
is running PHP-FPM on port 9000.
To test your container, follow these steps:
- Remove the PHP Location Block (if PHP-FPM is not yet configured):
- Build and Run the Docker Container:
-
Open a terminal and navigate to the directory containing your
Dockerfile
. -
Run the following commands:
docker build -t nginx-img .
docker run -d --name nginx-container -p 443:443 nginx-img
Tip: If port 443 is blocked, bind the address to a different port (e.g., 8443):
docker run -d --name nginx-container -p 8443:443 nginx-img
- Add a Test File:
- Run this command to create a simple HTML file inside the container:
docker exec -it nginx-container bash -c 'echo "<h1>Hello World!</h1>" > /var/www/wordpress/index.html'
- Access the NGINX Server:
- Open a web browser and go to:
https://localhost:443
(if you used port 443)https://localhost:8443
(if you used port 8443)
- If you encounter issues, inspect the container logs for debugging:
docker logs nginx-container
MariaDB Server is one of the most popular open-source relational databases. Created by the original developers of MySQL, it is designed to remain open-source and is widely used in cloud services and as the default database in many Linux distributions.
MariaDB serves as the database management system (DBMS) for storing WordPress data.
Here’s how we set up MariaDB in our Docker container.
FROM debian:bullseye
- Base Image: As the subject requires (The containers must be built either from the penultimate stable
version of
Alpine
orDebian
. The choice is yours.)
RUN apt update -y && apt upgrade -y && \
apt install -y mariadb-server && \
apt clean && rm -rf /var/lib/apt/lists/*
- Install MariaDB: This command installs the MariaDB server and all necessary dependencies.
- Clean Up: Reduces image size by clearing unnecessary package lists.
COPY conf/50-server.cnf /etc/mysql/mariadb.conf.d/50-server.cnf
COPY tools/mariadb.sh /usr/local/bin/mariadb.sh
- Configuration Files: These lines copy custom configuration files into the container:
50-server.cnf
: Defines MariaDB settings (port, user, socket, and data directory).mariadb.sh
: A custom script for initializing the database and users.
RUN chmod +x /usr/local/bin/mariadb.sh
- Set Permissions: Grants execution permissions to the
mariadb.sh
script.
CMD ["/usr/local/bin/mariadb.sh"]
- Startup Script: Specifies
mariadb.sh
as the script to run when the container starts. This ensures proper initialization of the database.
By default, MariaDB only allows connections from localhost
. We need to set bind-address to 0.0.0.0
to allow connections from all networks, and specify the port as 3306
.
The default config file 50-server.cnf
is located in /etc/mysql/mariadb.conf.d/
.
Modify it as follows:
[mysqld]
user = mysql
socket = /run/mysqld/mysqld.sock
datadir = /var/lib/mysql
bind-address = 0.0.0.0
port = 3306
This script handles the initialization and configuration of the MariaDB server.
1. Environment Variable Validation
Ensures the following environment variables are provided for proper configuration:
- Name of the database to create.
- Name of the user to create.
- Password for the new user.
- Root user password for MariaDB.
2. Database Initialization
- Creates a database and user as specified by the environment variables.
- Grants the user permissions on the database.
3. Root Password Setup
- Updates the MariaDB root password for enhanced security.
4. Graceful Restart
- Stops MariaDB temporarily after initialization to apply changes.
- Restarts MariaDB in the foreground for container compatibility.
#!/bin/bash
service mariadb start;
sleep 5; # Wait for mariadb to start properly
mysql -u root "CREATE DATABASE IF NOT EXISTS \`${MYSQL_DATABASE}\`;"
mysql -u root "CREATE USER IF NOT EXISTS \`${MYSQL_USER}\`@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';"
mysql -u root "GRANT ALL PRIVILEGES ON \`${MYSQL_DATABASE}\`.* TO '${MYSQL_USER}'@'%';"
mysql -u root "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' WITH GRANT OPTION;"
mysql -u root "FLUSH PRIVILEGES;"
mysqladmin -u root -p"${MYSQL_ROOT_PASSWORD}" shutdown;
exec mysqld_safe;
Follow these steps to verify that your MariaDB container is working correctly:
docker build -t mariadb-img .
docker run -d --name mariadb-container -p 3306:3306 \
-e MYSQL_DATABASE=mydb \
-e MYSQL_USER=myuser \
-e MYSQL_PASSWORD=mypass \
-e MYSQL_ROOT_PASSWORD=myrootpass mariadb-img
- Check Logs
docker logs mariadb-container
- Ensure there are no errors and that MariaDB started successfully.
- Access the MariaDB Shell
docker exec -it mariadb-container mysql -u root -p'wp_pass'
- Enter the
MYSQL_ROOT_PASSWORD
you specified.
- Verify the Database and User
SHOW DATABASES;
SELECT user, host FROM mysql.user;
- Confirm that your database and user exist.
Bellow, You will find some useful commands that you need to play with your mariadb container ⬇️
💡💡 In your journey working on this project, try to learn these technologies, read a lot of documentation, and get hands-on experience testing your containers. Enjoy every step of the process. Docker is a useful and in-demand technology. Learning it can improve your job prospects. 💡💡
In a nutshell, WordPress is a tool for building websites without coding. Its ease of use and flexibility have made it the leading website creation tool worldwide. In fact, it powers nearly half of the web content, according to recent WordPress statistics.
PHP-FPM (FastCGI Process Manager) is a tool that improves website performance by managing PHP scripts more efficiently. It’s faster than traditional CGI-based methods and capable of handling high traffic loads.
Read this Documentation for better understanding ⬇️
First, we need to create a Dockerfile
to define the environment for running WordPress.
Here's the content of the Dockerfile
:
FROM debian:bullseye
# Update and upgrade the system, then install necessary dependencies.
# - php7.4: The main PHP runtime.
# - php-fpm: A FastCGI Process Manager for PHP.
# - php-mysql: PHP extension to interact with MySQL.
# - mariadb-client: Allows the container to interact with a MariaDB server.
RUN apt update -y && apt upgrade -y && \
apt install -y curl php7.4 php-fpm php-mysql mariadb-client && \
apt clean && rm -rf /var/lib/apt/lists/*
# Copy the PHP-FPM configuration file into the container.
COPY conf/www.conf /etc/php/7.4/fpm/pool.d/www.conf
# Copy the custom WordPress setup script and make it executable.
COPY tools/wordpress.sh /usr/local/bin/wordpress.sh
RUN chmod +x /usr/local/bin/wordpress.sh
# Set the custom script as the default command to run.
CMD ["/usr/local/bin/wordpress.sh"]
The PHP-FPM configuration file (www.conf
) ensures the proper functioning of the PHP-FPM service. By default, this file is located at /etc/php/7.4/fpm/pool.d
.
Below is the default content:
[www]
user = www-data
group = www-data
listen = something
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
Modify listen
property to configure PHP-FPM to listen on port 9000
:
listen = 9000
Create a file named www.conf
in the conf/
directory and include the updated content. This file will be copied into the container during the Docker build process.
We use a custom script named wordpress.sh
to automate the WordPress setup. Place this file in the tools/
directory. Here’s the content:
Before starting. Take a look at this Documentation to understand the commands used ⬇️
- Create WordPress Directory
mkdir -p /var/www/wordpress
cd /var/www/wordpress
- Creates the directory where WordPress will be installed (
/var/www/wordpress
) and navigates to it.
- Download and Install WP-CLI
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp
- Downloads the WP-CLI (WordPress Command Line Interface).
- Makes it executable and moves it to
/usr/local/bin/wp
, so it can be used globally.
- Download WordPress Core
wp core download --allow-root
- Downloads the WordPress core files into
/var/www/wordpress
.
- Move the Sample Configuration File
mv /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php
- Renames
wp-config-sample.php
towp-config.php
, which is the actual configuration file WordPress uses.
- Configure the Database Connection
sed -i "s/define( 'DB_NAME', 'database_name_here' );/define( 'DB_NAME', '${MYSQL_DATABASE}' );/" wp-config.php
sed -i "s/define( 'DB_USER', 'username_here' );/define( 'DB_USER', '${MYSQL_USER}' );/" wp-config.php
sed -i "s/define( 'DB_PASSWORD', 'password_here' );/define( 'DB_PASSWORD', '${MYSQL_PASSWORD}' );/" wp-config.php
sed -i "s/localhost/mariadb/" wp-config.php
- Updates wp-config.php to:
- Use the database name, user, and password from environment variables.
- Replace
localhost
withmariadb
, assuming MariaDB is running in a Docker container namedmariadb
.
- Wait for MariaDB Service
sleep 10
- Pauses the script for 10 seconds to ensure MariaDB is ready to accept connections.
- Install WordPress
wp core install \
--url="${DOMAIN_NAME}" \
--title="${SITE_TITLE}" \
--admin_user="${WP_ADMIN_USER}" \
--admin_password="${WP_ADMIN_PASSWORD}" \
--admin_email="${WP_ADMIN_EMAIL}" \
--allow-root
- Installs WordPress using WP-CLI with the following:
--url
: The domain name for the WordPress site.--title
: The site title (e.g., "Inception").--admin_user
,--admin_password
,--admin_email
: Sets up the admin account with provided credentials.
- Create an Additional Editor User
wp user create \
"${WP_USER}" "${WP_USER_EMAIL}" \
--user_pass="${WP_USER_PASSWORD}" \
--role=editor \
--allow-root
- Creates another WordPress user with the
editor
role using provided environment variables.
- Prepare PHP-FPM Runtime Directory
mkdir -p /run/php
- Creates the directory
/run/php
required for PHP-FPM to operate.
- Start PHP-FPM Service
php-fpm7.4 -F
- Starts the PHP-FPM service in the foreground to handle PHP requests for the WordPress site.
This script automates the setup of a WordPress environment by:
- Preparing the installation directory.
- Configuring WordPress using environment variables.
- Installing WordPress with the admin user.
- Creating an additional editor user.
- Starting the PHP-FPM service to serve WordPress.
This ensures the container is ready to handle requests and serve the WordPress application.
Ensure the required environment variables (MYSQL_DATABASE
, SITE_TITLE
, MYSQL_USER
, MYSQL_PASSWORD
, DOMAIN_NAME
, WP_ADMIN_USER
, WP_ADMIN_PASSWORD
, WP_ADMIN_EMAIL
, etc.) are properly set before running the container.
Now that you’ve created and configured individual containers, it’s time to orchestrate them using Docker Compose. This step will allow you to manage all your services, networks, and volumes in a single YAML
file, simplifying deployment and scalability.
Docker Compose is a powerful tool that lets you define and manage multi-container applications. Instead of running multiple docker run
commands, Docker Compose allows you to:
- Define your services, networks, and volumes in a single YAML file (
docker-compose.yml
). - Use simple commands to start, stop, and manage your entire application stack.
Learn more:
- Install Docker Compose Ensure Docker Compose is installed on your machine. You can check by running:
docker-compose --version
If it’s not installed, follow the Docker Compose installation guide.
- Plan Your Services
Before writing the
docker-compose.yml
file, identify the services you’ll include. For this project, we need:
- MariaDB: Database service for WordPress.
- NGINX: Web server for serving WordPress with HTTPS.
- WordPress: The application container running WordPress with PHP-FPM.
- Define Volumes and Networks Plan your storage and container communication:
- Volumes: Use persistent storage for the MariaDB database and WordPress files to avoid data loss.
- Networks: Create a custom bridge network to enable secure communication between containers.
- Create the
docker-compose.yml
File Start building your configuration step by step. Below is a detailed breakdown of each section:
MariaDB is the database backend for WordPress. Here’s how to define it:
mariadb:
container_name: mariadb
networks:
- inception
build: ./requirements/mariadb
image: mariadb:notlatest
env_file: .env
volumes:
- mariadb:/var/lib/mysql
restart: always
expose:
- "3306" # Internal database communication port
NGINX will act as the web server, handling HTTPS and reverse proxying PHP requests to WordPress.
nginx:
container_name: nginx
networks:
- inception
depends_on:
- wordpress
build: ./requirements/nginx
image: nginx:notlatest
env_file: .env
volumes:
- wordpress:/var/www/wordpress # Mount WordPress files
restart: always
ports:
- "443:443" # Exposing port 443 for HTTPS traffic
Key Points:
depends_on
: Ensures WordPress starts before NGINX.ports
: Maps port443
on the host to port443
in the container for HTTPS.
The WordPress service runs PHP-FPM, handling dynamic requests.
wordpress:
container_name: wordpress
networks:
- inception
depends_on:
- mariadb
build: ./requirements/wordpress
image: wordpress:notlatest
env_file: .env
volumes:
- wordpress:/var/www/wordpress # Mount WordPress files
restart: always
expose:
- "9000" # Internal PHP-FPM port
Key Points:
depends_on
: Ensures MariaDB starts before WordPress.volumes
: Shares WordPress files between the host and container.
Finally, define the shared storage and networking setup:
volumes:
mariadb:
driver: local
driver_opts:
type: none
device: /home/abel-mqa/data/mariadb # Host path for the MariaDB volume
o: bind
wordpress:
driver: local
driver_opts:
type: none
device: /home/abel-mqa/data/wordpress # Host path for the WordPress files
o: bind
networks:
inception:
driver: bridge
key Points:
- Volumes: Use bind mounts (
device
witho: bind
) to persist data in specific host directories. - Networks: Use a custom
bridge
network for isolated communication between containers.
Once your docker-compose.yml
file is ready, use the following commands to manage your stack:
docker-compose up # Start all services
docker-compose down # Stop and remove containers, networks, and volumes
docker-compose logs # Display logs of running services
docker-compose exec <service> # Run a command inside a service container
docker-compose ps # List running containers
With this guide, you’re ready to create your docker-compose.yml file, manage your containers effortlessly, and troubleshoot like a pro!
Networking in Docker is a fundamental concept that enables containers to communicate with each other and with external systems. Let’s break down how container networking works and the options available:
By default, Docker enables networking for containers, allowing them to make outgoing connections to external networks. However, containers are unaware of the specific network type they are connected to or whether their peers are also Docker workloads. From the container’s perspective, it sees:
A network interface with an assigned IP address
.A gateway for outgoing connections
.A routing table
.DNS services for resolving hostnames
.
This abstraction ensures containers can operate independently of the underlying network structure unless explicitly configured otherwise.
Containers can be attached to custom, user-defined networks, allowing them to communicate with each other using their container names or IP addresses. These networks provide greater flexibility and isolation compared to the default settings.
Docker uses network drivers to define how containers connect to networks. Each driver provides a unique type of networking functionality:
Driver | Description |
---|---|
bridge | The default driver for standalone containers. It creates an isolated network on the Docker host. |
host | Removes network isolation between the container and the Docker host. Directly shares the host's networking. |
none | Completely isolates the container from all networks. No external or inter-container communication is possible. |
overlay | Connects multiple Docker daemons together, allowing containers to communicate across hosts. |
ipvlan | Provides full control over IPv4 and IPv6 addressing for containers. |
macvlan | Assigns a unique MAC address to a container, allowing it to appear as a physical device on the network. |
In this project, we create a custom bridge network named inception
. This network isolates the containers from external traffic and allows only the containers within this network to communicate securely with each other. For example:
- MariaDB can be accessed by the WordPress container using its container name (
mariadb
). - NGINX proxies requests to the WordPress container, ensuring secure communication via port
9000
.
By using a user-defined network, we ensure better control, security, and scalability, while also adhering to the project requirement to avoid options like host
networking or deprecated linking methods.
This setup ensures a well-structured and secure communication environment tailored to our application’s needs.
To complete your WordPress setup with Docker, follow these important steps:
To simplify access to your website, configure your domain name to point to your local IP address. This must follow the format login.42.fr
, where login
is your 42 school login.
- Open the
/etc/hosts
file with elevated privileges:
sudo nano /etc/hosts
- Add an entry pointing your domain to your local IP:
127.0.0.1 login.42.fr
Replace login
with your own login. For example, if your login is Joe:
127.0.0.1 Joe.42.fr
- Save and exit the file.
Note: This ensures that typing login.42.fr
in your browser redirects to your local WordPress environment.
Docker volumes are used to persist data between container restarts. Create a structured directory to store your project’s data.
- Create a data folder in your home directory:
mkdir -p /home/login/data
Replace login
with your 42 login (e.g., Joe):
mkdir -p /home/Joe/data
- Use this folder as the host directory for your Docker volumes. This ensures all data is stored and accessible outside the container.
Using a virtual machine (VM) is essential for the following reasons:
- Sudo Permissions for Volumes: Docker volumes require special permissions to read/write to specific host directories. Without
sudo
, managing these directories (e.g.,/home/login/data
) can lead to permission issues. - Separation of Environments: A VM provides an isolated environment for your project, avoiding interference with your host machine and ensuring compatibility with the required software.
By default, Docker commands require sudo
. To simplify usage, add your user to the docker
group so you can run Docker commands without sudo
.
- Add your user to the
docker
group:
sudo usermod -aG docker $USER
- Log out and log back in to apply the changes.
- Verify Docker works without
sudo
:
docker info
To start your WordPress setup, follow these steps:
- Navigate to your project directory:
cd /path/to/your/project
- Build and start your containers:
docker-compose up -d --build
- Check running containers:
docker ps
-
No
latest
Tag: Using thelatest
tag for Docker images can lead to version inconsistencies. Always specify explicit versions for stability and reproducibility. -
No Hardcoded Passwords: Hardcoding passwords in Dockerfiles or scripts is a security risk. These files can be accidentally exposed, leading to credential leaks.
-
Use of Environment Variables:
- Environment variables enable flexible and secure configuration.
- They prevent sensitive information from being hardcoded.
- They make the setup portable across environments.
- Recommended
.env
File:
- Store all environment variables in a
.env
file at the root of thesrcs
directory. - This approach centralizes configuration, improves maintainability, and enhances security by keeping sensitive data out of version control.
- NGINX as the Only Entry Point:
- All traffic must be routed through the NGINX container on port 443 using TLSv1.2 or TLSv1.3.
- This ensures secure communication by encrypting data and protecting against attacks.
Once everything is set up, you can access your WordPress website and the admin dashboard as follows:
- Open your web browser.
- Enter your domain name in the address bar:
https://login.42.fr
(Replace login
with your actual 42 school login.)
- You should see your WordPress homepage.
- In your web browser, navigate to:
https://login.42.fr/wp-admin
- Enter your admin credentials (created during WordPress installation).
- Once logged in, you’ll have access to the WordPress dashboard.
Basic Navigation:
- Posts: Create new blog posts by going to
Posts > Add New
. - Pages: Add new pages by navigating to
Pages > Add New
. - Themes: Change the site appearance under
Appearance > Themes
. - Plugins: Extend functionality by installing plugins in
Plugins > Add New
. - Users: Manage users under
Users > All Users
.
Testing Your Setup:
- Create a test post and publish it.
- Install a basic plugin (e.g., Elementor) and activate it.
- Change the site’s theme and observe the changes.
- Upload a media file (image, PDF) and verify it appears in
Media > Library
.
Final Notes By following these steps, you’ll have a fully functional and secure WordPress environment. The setup ensures adherence to project requirements while maintaining best practices for security, usability, and maintainability.
If you found this tutorial helpful or learned something new, please show your support by giving it a ⭐ on GitHub! Your feedback encourages me to create more detailed and easy-to-follow guides.
Thank you for reading, and happy coding!