Hey there! As a Laravel developer, I’ve often struggled with keeping my app’s environment consistent across development, testing, and production. Manually setting up servers was a headache, and scaling my app for more users felt daunting.
That’s when I turned to Docker and CI/CD to streamline everything. In this article, I’ll walk you through how I containerized my Laravel app with Docker and set up a CI/CD pipeline using GitHub Actions to automate deployment.
This setup makes scaling your app easier and ensures consistency.
Here’s how I set up Docker for my Laravel app and integrated it with a CI/CD pipeline using GitHub Actions. This approach ensures consistent environments and automates deployment for scalability.
First, make sure you have a Laravel project ready and pushed to a GitHub repository. If you don’t, create one:
composer create-project laravel/laravel my-laravel-app
cd my-laravel-app
git init
git add .
git commit -m "Initial commit"
git remote add origin <your-github-repo-url>
git push -u origin main
Ensure your project has some tests (e.g., created with php artisan make:test
) for the CI pipeline to validate your code.
Docker creates containers that package your app and its dependencies, ensuring consistency across environments. If you don’t have Docker installed, download Docker Desktop from the official Docker website and install it.
In your Laravel project’s root, create a Dockerfile
to define your app’s container:
FROM php:8.1-fpm
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /var/www
# Copy project files
COPY . .
# Install Laravel dependencies
RUN composer install --no-dev --optimize-autoloader
# Set permissions
RUN chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache
RUN chmod -R 775 /var/www/storage /var/www/bootstrap/cache
# Expose port
EXPOSE 9000
CMD ["php-fpm"]
Next, create a docker-compose.yml
file to define services (app, web server, and database):
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: my-laravel-app
volumes:
- .:/var/www
environment:
- APP_ENV=production
- APP_KEY=${APP_KEY}
- DB_HOST=db
- DB_DATABASE=laravel
- DB_USERNAME=laravel
- DB_PASSWORD=secret
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- .:/var/www
depends_on:
- app
db:
image: mysql:8.0
environment:
- MYSQL_DATABASE=laravel
- MYSQL_USER=laravel
- MYSQL_PASSWORD=secret
- MYSQL_ROOT_PASSWORD=secret
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
Create an nginx.conf
file for the Nginx service:
server {
listen 80;
index index.php index.html;
root /var/www/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Generate an app key and update .env.example
(used later in CI/CD):
php artisan key:generate --show
Add the key to .env.example
as APP_KEY=your-generated-key
.
Run your app locally to ensure everything works:
docker-compose up -d
Visit http://localhost
in your browser. You should see your Laravel app. If you need to run migrations:
docker-compose exec app php artisan migrate
Stop the containers when done:
docker-compose down
I use an AWS EC2 instance for deployment, but any server with Docker and Docker Compose works. Set up your server:
sudo apt update
sudo apt install -y docker.io docker-compose
sudo usermod -aG docker ubuntu
~/.ssh/authorized_keys
.Create a file at .github/workflows/ci-cd-docker.yml
:
name: Deploy Laravel with Docker
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build Docker image
run: docker build -t my-laravel-app .
- name: Save Docker image
run: docker save my-laravel-app | gzip > my-laravel-app.tar.gz
- name: Copy image to server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
source: "my-laravel-app.tar.gz"
target: "/home/ubuntu"
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /home/ubuntu
docker load < my-laravel-app.tar.gz
docker-compose -f /home/ubuntu/docker-compose.yml up -d
docker-compose exec app php artisan migrate --force
docker-compose exec app php artisan config:cache
docker-compose exec app php artisan route:cache
Copy docker-compose.yml
and nginx.conf
to your server’s /home/ubuntu
directory manually or include them in the repository.
In your GitHub repository (Settings > Secrets and variables > Actions), add:
ubuntu
).Push a change to your main
branch:
git add .
git commit -m "Test Docker CI/CD"
git push origin main
Check the Actions tab in your GitHub repository to monitor the workflow. It builds the Docker image, transfers it to your server, and deploys it.
To handle more traffic, scale your Docker containers:
docker-compose up -d --scale app=3
Use a load balancer (e.g., AWS ALB) to distribute traffic across containers. For larger-scale apps, consider Kubernetes or AWS ECS.
Using Docker and GitHub Actions to scale my Laravel app has been a lifesaver. Docker ensures my app runs consistently across environments, and the CI/CD pipeline automates deployments, making scaling effortless. Whether you’re handling a few users or thousands, this setup is reliable and beginner-friendly.
Q: Why use Docker with Laravel?
A: Docker ensures consistent environments across development, testing, and production, reducing “it works on my machine” issues.
Q: Can I use other CI/CD tools with Docker?
A: Yes, tools like Jenkins or GitLab CI/CD work well with Docker, but GitHub Actions is beginner-friendly and free.
Q: How do I scale my Laravel app further?
A: Use multiple containers (docker-compose --scale
), a load balancer, or a container orchestrator like Kubernetes for larger-scale apps.
Q: What if my Docker deployment fails?
A: Check GitHub Actions logs for errors. Common issues include incorrect SSH keys, missing dependencies, or misconfigured docker-compose.yml
.
Q: Do I need AWS for this setup?
A: No, any server with Docker works, but AWS EC2 is popular for its scalability and reliability.
You might also like :