Why dependencies matter
- Features. Libraries add functions that you do not have to write.
- Security and updates. Updating dependencies brings security fixes.
- Compatibility. Managing versions keeps your app running.
- Reuse. Many libraries work in many projects.
PHP package tools
- Composer. The standard dependency manager for PHP.
- PEAR. An older packaging system for PHP extensions.
- PHP-CLI. The command-line PHP, used to run Composer and scripts.
What you need
- Docker, installed from the official website.
- Composer is added inside the container in this guide, so you do not need it on the host.
Step 1: Create a project folder
mkdir my-php-app
cd my-php-app
Step 2: Create a Dockerfile
Create a file named Dockerfile:
# Use an official PHP image
FROM php:8.2-cli
# Install system tools and PHP extensions
RUN apt-get update && apt-get install -y git unzip libzip-dev \
&& docker-php-ext-install zip pdo_mysql \
&& rm -rf /var/lib/apt/lists/*
# Install Composer from its official image
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# Set the working directory
WORKDIR /usr/src/myapp
# Copy the dependency files first, to use the Docker cache
COPY composer.json composer.lock* ./
# Install the PHP dependencies
RUN composer install --no-dev --no-interaction --prefer-dist
# Copy the rest of the app
COPY . .
CMD ["php", "./index.php"]
Step 3: Add composer.json
Create composer.json with the packages you need, for example:
{
"require": {
"monolog/monolog": "^3.0"
}
}
Or create it by running Composer in a temporary container:
docker run --rm -v "$PWD":/app composer:2 require monolog/monolog
Step 4: Add a test script
Create index.php:
<?php
require __DIR__ . '/vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('app');
$log->pushHandler(new StreamHandler('php://stdout'));
$log->info('Hello from Docker');
Step 5: Build the image
docker build -t my-php-app .
Step 6: Run the container
docker run --rm my-php-app
You should see the log line.
Tips
- Copy
composer.jsonbefore the rest of the code, so Docker re-uses the cached layer when only your code changes. - Use
--no-devin production images. - Use a
.dockerignorefile withvendorand.git. - Add more extensions with
docker-php-ext-installor with themlocati/php-extension-installerhelper.
Quick recap
- Put Composer in the image with
COPY --from=composer:2. - Run
composer installin the Dockerfile. - Build with
docker buildand run withdocker run.