Containerization
What is a Container?
A container is a lightweight, standalone, executable software package that includes everything needed to run a piece of software, including the code, runtime, libraries, and system tools.
WordPress in a Container:
WordPress Image: WordPress can be deployed in a container. Containers are isolated environments that include everything needed to run a piece of software, including the code, runtime, libraries, and system tools. To deploy WordPress, you first pull the WordPress image, which is a pre-packaged version of the software.
Deploying WordPress in a Container
Pulling WordPress Image
To deploy WordPress in a container, you can pull the official WordPress image from the Docker Hub repository using the following command:
docker pull wordpress
This image contains all the necessary components to run WordPress, including the PHP runtime, web server, and other dependencies.
WordPress and MySQL Database:
Data Storage: WordPress stores its content, such as blog posts, in a MySQL database.
Three-Tier Architecture: The architecture involves three components - User, WebApp (WordPress), and Database (MySQL). When a user interacts with the WordPress application, data is stored in the MySQL database. This is known as a three-tier architecture. In the three-tier architecture, WordPress stores its data, such as blog posts, in a MySQL database.
Launching MySQL Database Container
Launching MySQL in a container involves setting up the necessary credentials (database name, username, password), while WordPress needs to be connected to this MySQL container by specifying the database host (which is the IP address of the running MySQL container).
docker run -d --name mysql-container -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wpuser -e MYSQL_PASSWORD=wppassword mysql:latest
Here, we launch a MySQL container with specified environment variables. These include the root password, WordPress database name, and user credentials.
Container Isolation and Porting
Container Isolation: Containers are isolated by default and don't have connectivity with the outside world. Porting: Porting is done to expose the MySQL container to the outside world.
For example, to expose WordPress on port 8080:
docker run -d --name wordpress-container --link mysql-container:mysql -p 8080:80 wordpress
Managing WordPress Installation
Installing WordPress and Data Storage:
Once connected, WordPress can be installed and used. The WordPress container handles frontend elements, while the MySQL container stores the data in its directory (/var/lib/mysql).
Deleting MySQL Database Container
Launch Sequence: MySQL is launched before WordPress because WordPress relies on the MySQL database.
If the MySQL database container is deleted, Docker allows for quick re-launch within seconds. However, the data stored in the database container is ephemeral.
Launching MySQL with Persistence Storage
Persistence in Data Storage: Initially, containers store data ephemeral, meaning data is lost if the container is deleted. However, to make data persistent, MySQL can be launched with persistence storage, ensuring that even if the container is removed, the data remains intact in the base system.
Data Storage Paths: Each service (e.g., HTTPd, MySQL) stores data in specific directories.
For permanent data storage, launch the MySQL database container with persistent storage:
docker run -d --name mysql-container -v /path/to/mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wpuser -e MYSQL_PASSWORD=wppassword mysql:latest
- -d: Runs the container in detached mode (in the background).
- --name mysql-container: Assigns the name "mysql-container" to the running container.
- -v /path/to/mysql-data:/var/lib/mysql: Mounts the host machine's
/path/to/mysql-data
directory into the container's/var/lib/mysql
directory. This is a volume mount, allowing data persistence even if the container is removed. - -e MYSQL_ROOT_PASSWORD=my-secret-pw: Sets the root password for MySQL to "my-secret-pw".
- -e MYSQL_DATABASE=wordpress: Creates a MySQL database named "wordpress".
- -e MYSQL_USER=wpuser -e MYSQL_PASSWORD=wppassword: Sets up a MySQL user named "wpuser" with the password "wppassword".
Now, the data stored in the MySQL database will be permanent.
Container Linking
Instead of relying on IP addresses, containers can be linked using the --link
keyword in the docker run
command. For example:
docker run -d --name wordpress-container -p 8080:80 --link mysql-container:mysql -e WORDPRESS_DB_HOST=mysql -e WORDPRESS_DB_NAME=wordpress -e WORDPRESS_DB_USER=wpuser -e WORDPRESS_DB_PASSWORD=wppassword wordpress
This command runs the WordPress container, exposing it on port 8080. Here, we use the --link
flag to link the WordPress container with the MySQL container using their names (mysql-container
and wordpress-container
). This simplifies connectivity and reduces reliance on changing IP addresses.
Environment variables are set to configure WordPress to use the linked MySQL container.
Challenges in Container Linking
Container linking has limitations, including unidirectional communication and potential disruptions due to IP changes.
Best Practices
Avoiding IP Address Dependency
In a multi-tier architecture, it's a good network practice to avoid relying on IP addresses for inter-container communication.
Container Naming Best Practice
Instead of using an IP address, containers should be referred to by name. This concept is known as container linking.
Installing WordPress
Login to WordPress:
Connecting to WordPress Server
After launching the WordPress container, access the WordPress application by navigating to the specified URL (usually http://localhost:8080
). You'll be directed to the WordPress installation page where you can set up your site.
Front-end and Data Source:
- The user interface fields are served by the WordPress container.
- Data is retrieved from the MySQL database container.
Handling Database Container Deletion
Deleting Database Container:
If the MySQL database container is deleted, Docker allows quick re-launch within seconds.
Ephemeral Data:
The data stored in the database container is ephemeral, and if the container is deleted, all information is lost.
Service-specific Data Directories:
Services store data in specific directories (e.g., Apache HTTPd stores data in /var/www/html
, MySQL in /var/lib/mysql
).
Persistent Storage for MySQL
Launching MySQL with Persistence:
To ensure data permanence, launch the MySQL database container with persistent storage.
docker run -d --name mysql-container -v /path/on/host:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=rootpass -e MYSQL_DATABASE=wordpressdb -e MYSQL_USER=wpuser -e MYSQL_PASSWORD=wppass mysql
Data Persistence:
Now, the data stored in the MySQL database is permanent.
Container Linking
Container Linking: Linking containers allows them to communicate. Instead of using IP addresses (which can change), containers can be linked using a container's name. This is beneficial as it avoids reliance on changing IPs.
Linking Command: --link keyword in the Docker run command is used for linking.
Linking WordPress with MySQL:
docker run -d --name wordpress-container --link mysql-container:mysql -p 8080:80 wordpress
Now, use the name "mysql" instead of the IP address when connecting WordPress to MySQL.
Limitations of Linking:
Container linking has limitations. It works one way; if one operating system wants to connect to another, it won't work in reverse. Also, if the IP address changes, connectivity might be lost. eg. if OS1 wants to connect to OS2, it will not work in the reverse direction.
Challenges in Linking
Unidirectional Linking:
Container linking is unidirectional; if the IP address changes, connectivity is lost.
Name-to-IP Conversion Internally:
Internally, linking converts container names into IP addresses. If the IP changes, connectivity breaks.
Addressing IP Changes:
Changing IP addresses can disrupt connectivity in a multi-tier architecture.
Best Practices
Avoiding IP Address Dependency:
Best network practice is to avoid relying on IP addresses for inter-container communication.
Container Naming Best Practice:
Overcoming Challenges in Container Linking: To mitigate the limitations of linking, launching MySQL and WordPress containers while linking them by using container names instead of IP addresses can help maintain connectivity even if the IP changes. Containers should be referred to by name instead of IP addresses.
Conclusion:
Persistent Data: Launching MySQL with persistence ensures data remains even if containers are recreated. Networking Best Practice: Instead of relying on changing IP addresses, container linking using names is a recommended practice. In essence, containerization provides an isolated, portable, and scalable environment for deploying applications like WordPress, and understanding container linking helps manage communication between containers effectively while considering the challenges it presents.