Dockerizing PHP/Laravel Applications
This guide provides detailed instructions for containerizing PHP applications using Docker, with specific configurations for Laravel and raw PHP projects.
Project Structure
.
├── Dockerfile
├── docker
│ ├── nginx
│ │ ├── default.conf
│ │ └── Dockerfile
│ └── php
│ └── www.conf
├── docker-compose.yml
└── src/
└── your-application-files
Docker Configuration Files
PHP Dockerfile
# Base image
FROM php:8.2-fpm
# Arguments defined in docker-compose.yml
ARG user=www-data
ARG uid=1000
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip \
libzip-dev
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Create system user
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
chown -R $user:$user /home/$user
# Copy configuration file
COPY ./docker/php/www.conf:/usr/local/etc/php-fpm.d/www.conf
# Set working directory
WORKDIR /var/www
# Copy existing application directory
COPY ./src .
# Set permissions
RUN chown -R $user:$user /var/www
USER $user
# Expose port 9000
EXPOSE 9000
CMD ["php-fpm"]
Nginx Dockerfile
# docker/nginx/Dockerfile
FROM nginx:alpine
COPY ./src /var/www
COPY docker/nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Nginx Configuration
# docker/nginx/default.conf
server {
listen 80;
server_name localhost;
root /var/www/public; # For Laravel
# root /var/www; # For raw PHP projects
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
PHP Config
# docker/php/www.conf
[www]
user = www-data
group = www-data
listen = 0.0.0.0:9000
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 500
docker-compose
version: '3.8'
services:
# PHP Application
app:
build:
context: .
dockerfile: Dockerfile
args:
user: www-data
uid: 1000
container_name: app
restart: unless-stopped
volumes:
- ./src:/var/www
- ./docker/php/www.conf:/usr/local/etc/php-fpm.d/www.conf
networks:
- app-network
# Nginx Service
nginx:
build:
context: .
dockerfile: docker/nginx/Dockerfile
container_name: nginx
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./src:/var/www
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- app-network
networks:
app-network:
driver: bridge
Deployment Instructions
Building and Starting Containers
if you want use kli to deploy your project with docker-compose file use this command:
kli compose up -d
Laravel-Specific Setup
# Install dependencies
kli exec app "composer install"
# Generate application key
kli exec app "php artisan key:generate"
# Set proper permissions
kli exec app "chown -R www-data:www-data storage bootstrap/cache"
Environment Configuration
Create a .env
file in your project root:
APP_NAME=YourApp
APP_ENV=production
APP_KEY=your-app-key
APP_DEBUG=false
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=your_database
DB_USERNAME=your_username
DB_PASSWORD=your_password
Security Best Practices
Security Considerations
- Always use non-root users in containers
- Implement proper file permissions
- Use environment variables for sensitive data
- Regular security updates for base images
- Implement proper SSL/TLS in production
Performance Optimization
Performance Tips
- Enable OPcache for PHP
- Configure appropriate PHP-FPM settings
- Implement Nginx caching
- Use volume mounts carefully in production