🚀 How Docker Saved Me from Dependency Hell 🔥😵💫
As a developer, I’ve always struggled with managing dependencies for my projects. 🤯 Every time I upgraded my system, switched operating systems, or installed a new version of XAMPP, my older projects would break. ❌💔
The constant need to update dependencies 🔄, reconfigure environments 🛠️, and debug broken setups 🐞 was a pain in the asz (pardon my French 🤭). But then... I discovered Docker, and it changed everything! 🌟🐳
In this blog post, I’ll share my journey 🛤️, the challenges I faced 🏔️, and how I finally solved the nightmare of dependency clashes. I hope my experience helps other developers stuck in the same loop of frustration. 🤝💡
🔥 The Problem: Dependency Hell 😈💥
When I started my programming journey 💻✨, I created many projects using XAMPP (a popular PHP stack 🐘). Over time, as I upgraded my system or switched laptops 💻➡️💻, I faced the same annoying problem:
❌ Dependency Clashes: Newer versions of PHP, MySQL, or Apache would break my older projects. 🛑💣
🛠️ Manual Updates: I had to manually fix each project, which was time-consuming ⏳ and error-prone ❌🔧.
💀 Wasted Projects: Many of my old projects were simply abandoned 🪦 because I couldn't get them to run on newer setups. 😭💻
🐳 Why Docker? 🚢
Docker is a game-changer 🎮💡! It allows you to containerize applications 🏗️📦 so that they run anywhere without dependency issues. Here's why it’s awesome:
✅ No More Dependency Clashes: Each project gets its own environment with the exact versions of PHP, MySQL, and dependencies it needs. 🔄🔒
✅ Portability: You can move projects across systems 🏗️🖥️🛜 without worrying about setup.
✅ Consistency: Your development environment matches your production environment ⚖️🚀—so no surprises when deploying! 🎯
With Docker, I realized I could finally break free from the dependency hell 🔥🔥🔥 I had been stuck in. 😌🕊️
Problem Statement
I have multiple PHP projects, each with different versions of PHP and MariaDB. For example:
Project 1: PHP 7.2 + MariaDB 10.1
Project 2: PHP 8.0 + MariaDB 10.3
Every time I upgraded my system or installed a new version of XAMPP, my older projects would break due to dependency clashes. To solve this, I decided to use Docker to containerize my projects and manage their dependencies independently.
🎯 Solution: Shared Services with Docker 🔗🐳
Instead of each project having its own instance of PHP, MySQL, or phpMyAdmin, I set up shared services. 🏗️✨
🔹 What are Shared Services?
🛠️ A single MariaDB container 🏦 serves multiple projects.
🛠️ A single PHP container 🐘 acts as the web server for multiple projects.
🛠️ A single phpMyAdmin container 🗂️ manages multiple databases.
💡 Benefits of Shared Services:
✔️ Resource Efficiency: 🏗️ No need to run multiple instances of the same service.
✔️ Consistency: 📏 All projects use the same versions of services.
✔️ Isolation: 🚪 Each project’s code & data stay separate.
📂 My Folder Structure 🗂️
This is how I organized my Docker setup: 🏗️
I created a shared services setup where each service (PHP, MariaDB, phpMyAdmin) runs in its own container. This allows multiple projects to share the same services while keeping their dependencies isolated.
Here’s my folder structure:
📁 docker-shared-services/
├── 📁 mariadb10/
│ ├── 📄 docker-compose.yml
│ └── 📁 mariadb-data/
├── 📁 php7/
│ ├── 📄 docker-compose.yml
│ ├── 📄 Dockerfile
│ └── 📄 php.ini
├── 📁 phpmyadmin4/
│ └── 📄 docker-compose.yml
├── 📁 mariadb11/
│ ├── 📄 docker-compose.yml
│ └── 📁 mariadb-data/
├── 📁 php8/
│ ├── 📄 docker-compose.yml
│ ├── 📄 Dockerfile
│ └── 📄 php.ini
└── 📁 phpmyadmin5/
└── 📄 docker-compose.yml
📁 ProjectsUsing-php7-sql-mariadb10/
├── 📄 docker-compose.yml
└── 📁 src/
📁 ProjectsUsing-php8-sql-mariadb11/
├── 📄 docker-compose.yml
└── 📁 src/
1. Explanation of Shared Services
How Shared Services Work
Shared services rely on Docker’s networking and volume features to allow multiple projects to access the same service. Here’s how it works:
a. Networking
Docker containers can communicate with each other if they are connected to the same network. By creating a shared network, you can allow multiple containers (e.g., a PHP container and a MariaDB container) to communicate with each other.
For example:
A MariaDB container and a phpMyAdmin container can be connected to the same network (my-mariadb-network).
The phpMyAdmin container can connect to the MariaDB container using the service name (db) as the hostname.
b. Volumes
Docker volumes allow you to persist data (e.g., database files) even after a container is stopped or removed. By using volumes, you can ensure that your shared services (e.g., MariaDB) retain their data across container restarts.
For example:
A MariaDB container can store its data in a volume (mariadb-data).
Even if the container is stopped, the data remains intact and can be reused by other projects.
1.1 MariaDB 10 Service : /docker-shared-services/mariadb10/
docker-compose.yml
services:
db:
image: mariadb:10.1.34 # MariaDB 10.1.34
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: password
volumes:
- ./mariadb-data:/var/lib/mysql # Persist MariaDB data
ports:
- "33061:3306" # Map host port 33061 to container port 3306
networks:
- my-mariadb10-network # Unique network for MariaDB 10.1
networks:
my-mariadb10-network:
driver: bridgeimage: mariadb:10.1.34: Uses the official MariaDB 10.1.34 image.
volumes: Persists MariaDB data in the mariadb-data directory.
ports: Maps host port 33061 to container port 3306.
networks: Connects to the my-mariadb10-network network.
1.2 PHP 7 Service : /docker-shared-services/php7/
docker-compose.yml
services:
php:
image: php:7.2-apache # PHP 7.2 with Apache
command: apache2-foreground # Ensures Apache runs in the foreground
volumes:
- ./php.ini:/usr/local/etc/php/conf.d/custom.ini # Custom PHP config
ports:
- "8081:80" # Map host port 8081 to container port 80
networks:
- my-php7-network # Unique network for PHP 7.2
networks:
my-php7-network:
name: my-php7-network # Force exact network name
external: true # Use the external networkimage: php:7.2-apache: Uses the official PHP 7.2 image with Apache.
volumes: Mounts the php.ini file for custom PHP configuration.
ports: Maps host port 8081 to container port 80.
networks: Connects to the my-php7-network network.
Dockerfile
# Use official PHP 7 Apache image
FROM php:7.2-apache
# Set working directory
WORKDIR /var/www/html
# Install required PHP extensions
RUN apt-get update && apt-get install -y \
libzip-dev \
unzip \
&& docker-php-ext-install pdo_mysql mysqli zip mbstring bcmath xml \
&& a2enmod rewrite
# Set Apache document root to src
RUN sed -i 's|/var/www/html|/var/www/html/src|g' /etc/apache2/sites-available/000-default.conf
# Give proper permissions for Laravel storage & bootstrap/cache
RUN chown -R www-data:www-data /var/www/html \
&& chmod -R 775 /var/www/html/src/mylarvel/storage \
&& chmod -R 775 /var/www/html/src/mylarvel/bootstrap/cache
# Install Composer globally
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Expose Apache port
EXPOSE 80
# Start Apache
CMD ["apache2-foreground"]FROM php:7.2-apache: Uses the official PHP 7.2 image with Apache.
RUN docker-php-ext-install: Installs required PHP extensions.
COPY --from=composer:latest: Installs Composer globally.
php.ini (Custom PHP configuration file.)
; Enable error reporting
error_reporting = E_ALL
display_errors = On
; Increase memory limit
memory_limit = 256M
; Enable file uploads
file_uploads = On
upload_max_filesize = 64M
post_max_size = 64M
; Enable mysqli extension
extension=mysqli.so
; Enable output buffering
output_buffering = On1.3 phpMyAdmin 4.8.2 Service : /docker-shared-services/phpmyadmin4/
docker-compose.yml
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin:4.8.2 # phpMyAdmin 4.8.2
environment:
PMA_HOST: db # Connect to the MariaDB service
PMA_USER: user
PMA_PASSWORD: password
ports:
- "8080:80" # Access phpMyAdmin at http://localhost:8080
networks:
- my-phpmyadmin4-network # Unique network for phpMyAdmin
- my-mariadb10-network # Connect to the MariaDB network
networks:
my-phpmyadmin4-network:
driver: bridge
my-mariadb10-network:
external: true # Use the external MariaDB networkimage: phpmyadmin/phpmyadmin:4.8.2: Uses the official phpMyAdmin 4.8.2 image.
PMA_HOST: db: Connects to the db service (MariaDB).
ports: Maps host port 8080 to container port 80.
networks: Connects to the my-phpmyadmin4-network and my-mariadb10-network networks.
2.1 Projects Using PHP 7 + MariaDB 10.1
Folder: /ProjectsUsing-php7-sql-mariadb10/docker-compose.yml
services:
app:
extends:
file: ../docker-shared-services/php7/docker-compose.yml
service: php
volumes:
- ./src:/var/www/html # Mount project-specific code
networks:
- my-php7-network
- mariadb10_my-mariadb10-network
networks:
my-php7-network:
external: true
mariadb10_my-mariadb10-network:
external: trueextends: Inherits the php service from the shared PHP 7 Compose file.
volumes: Mounts the project code from the src directory.
networks: Connects to the my-php7-network and mariadb10_my-mariadb10-network networks.
🚀 How It Works
Step 1: Start Shared Services 🏗️
Shared services are the backbone of my setup. They provide common functionality (e.g., a database, a web server, or a tool like phpMyAdmin) that can be reused by multiple projects.
📌 Start MariaDB 🏦
MariaDB is my database of choice. To start the MariaDB service, navigate to the mariadb10 folder and run the following command:
cd /docker-shared-services/mariadb10
docker-compose up -dThis command:
Starts the MariaDB container.
As mentioned in the docker-compose file of MariaDB , it persists data in the mariadb-data directory and Maps host port 33061 to container port 3306.
📌 Start PHP 🐘
Next, I start the PHP service, which serves as the web server for my projects. Navigate to the php7 folder and run:
cd /docker-shared-services/php7
docker-compose up -dThis command:
Starts the PHP container.
As mentioned in the docker-compose file of php7 , it mounts the php.ini file for custom PHP configuration and Maps host port 8081 to container port 80.
📌 Start phpMyAdmin 🗂️
To manage my databases, I use phpMyAdmin. Navigate to the phpmyadmin4 folder and run:
cd /docker-shared-services/phpmyadmin4
docker-compose up -dThis command:
Starts the phpMyAdmin container.
As mentioned in the docker-compose file of phpMyAdmin , it connects to the MariaDB service using the db hostname and Maps host port 8080 to container port 80.
Step 2: Start a Project 🚀
Once the shared services are up and running, I can start my projects. Each project has its own docker-compose.yml file that extends the shared services.
📌 Start a project using PHP 7 + MariaDB 10.1
Navigate to the project folder and run:
cd /ProjectsUsing-php7-sql-mariadb10
docker-compose up -dThis command:
Starts the project container.
Mounts the project code from the src directory.
Connects to the shared PHP and MariaDB services.
Step 3: Access Services 🖥️
With everything up and running, I can now access my services.
🌐 Access PHP Application at:
➡️ http://localhost:8081
🌐 Access phpMyAdmin at:
➡️ http://localhost:8080
🎉 Conclusion
Thanks to Docker, I can now:
✅ Isolate dependencies 🔄
✅ Simplify project setup 📦
✅ Avoid dependency clashes ❌🐞
If you struggle with dependency management, give Docker a try! 🐳 It might just save you from the hell I experienced. 🔥🚀
📚 Resources 📖🔗
Below are the links to few resources that helped me throughout the process,
💬 Lemme know if you want to know more about 📌 Docker Compose files, 📌 Networking in Docker, 📌how it works and 📌the various issues encountered during the process.
I might make a separate blog on that 🚀 or post a YouTube video 🎥 or both💡.
🔥 Happy Coding! 🖥️🐳💙
Disclaimer: The screenshots used in this blog post are for illustrative purposes only. The actual errors and solutions may vary based on your setup.


Comments
Post a Comment