• +228 872 7355
MagneticOps - DevOps and Infrastructure Experts
  • Home
  • Our Services
  • Blog
CI/CD for PHP: Going Beyond FTP Deployments

CI/CD for PHP: Going Beyond FTP Deployments

magnetic mi
Category: DevOps
23 July 2025
Hits: 378
Rating:
( 0 Rating )

At MagneticOps, we come in contact with a surprising number of clients who are still deploying PHP applications via manual file uploads or—yes—drag-and-drop FTP. And while that may have served its purpose in the early days, today's PHP applications demand more.

Manual deployments like this are not only outdated—they're dangerous. Whether you're a solo developer or leading a full-stack team, evolving your deployment pipeline is essential to shipping faster, safer, and with confidence.

Let’s explore how to leave FTP behind and embrace modern CI/CD workflows that bring your PHP stack into the future.

The Problem with FTP Deployments

FTP deployments are notoriously fragile. A small oversight—a missing file, a corrupt upload, or an outdated config—can bring your production environment to its knees.

Common risks with FTP-based workflows:

  • Lack of visibility into what was deployed, by whom, and when
  • No rollback mechanism when something goes wrong
  • No automated testing or validation before code goes live
  • Inconsistent environments across dev, staging, and production
  • High deployment anxiety that slows down innovation

These issues affect more than just developers—they compromise your users' experience and your team's ability to grow efficiently.

What a CI/CD Pipeline Looks Like for PHP

CI/CD (Continuous Integration and Continuous Deployment) brings clarity, repeatability, and automation to your development cycle. Here's a breakdown of how it works for PHP.

Version Control as the Foundation

All code is tracked in Git. This becomes your central source of truth, enabling teams to collaborate, revert, and review changes effectively.

Automated Testing

Each code commit triggers automated testing pipelines. Using tools like PHPUnit, PHPStan, or Psalm helps you catch bugs and regressions before any code reaches production.

Build and Packaging

Dependencies are installed, configurations are checked, and clean build artifacts (such as .zip or .phar files) are created. This ensures your production code remains stable and consistent.

Automated Deployments

The pipeline pushes validated code to staging or production environments based on conditions, such as only when tests pass or only from a main branch. You can deploy using rsync, SSH, or artifact registries—no human uploads are necessary.

Rollback and Monitoring

Each release is versioned, logged, and monitored. If something goes wrong in production, you can roll back quickly and confidently.

Sample: GitHub Actions CI/CD for a PHP Project

Here’s a simple example of a .github/workflows/deploy.yml for deploying a PHP app using GitHub Actions:


name: CI/CD for PHP

on:   
  push:     
    branches: [ "main" ]

jobs:   
  build-and-deploy:     
    runs-on: ubuntu-latest

    steps:     
      - name: Checkout Code       
        uses: actions/checkout@v3

      - name: Setup PHP       
        uses: shivammathur/setup-php@v2       
        with:         
          php-version: '8.2'

      - name: Install Dependencies       
        run: composer install --no-interaction --prefer-dist --optimize-autoloader

      - name: Run Static Analysis       
        run: vendor/bin/phpstan analyse

      - name: Run Tests       
        run: vendor/bin/phpunit

      - name: Deploy to Server      
        if: success()      
        uses: easingthemes/This email address is being protected from spambots. You need JavaScript enabled to view it.      
        with:        
          ssh-private-key: ${{ secrets.SSH_KEY }}        
          remote-user: deploy        
          server-ip: ${{ secrets.SERVER_IP }}        
          remote-path: /var/www/html/your-app

Why Clients Work With MagneticOps

At MagneticOps, we’ve helped teams transition from unreliable FTP deployments to organized, auditable, and scalable CI/CD pipelines designed for PHP environments.

We focus on:

  • Fast, practical setup; no overengineering
  • Compatibility with shared hosting, VPS, or cloud
  • Hands-on support from local development to production rollout
  • Team training and gradual DevOps adoption

Whether you’re starting from scratch or updating old infrastructure, we can help you move forward without slowing your team down.

Final Thoughts: From Manual to Mature

FTP deployments might still work, but so do fax machines. No one is building their business on those anymore.

Modern CI/CD focuses on confidence, speed, and safety. It's not just about tools; it's a change in how teams deliver software. It’s accessible to you right now.

We’ve helped developers and teams:

  • Regain hours of productivity each week
  • Eliminate "deployment day" stress
  • Prevent production outages from missing or mismatched files
  • Speed up feature releases without sacrificing quality

You don’t have to reinvent your stack to get started. We’ll meet you where you are.

References & Resources

- GitHub Actions: CI for PHP: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-php

- PHPStan - Static Analysis Tool: https://phpstan.org/

- Deployer - PHP Deployment Tool: https://deployer.org/

- Twelve-Factor App Principles: https://12factor.net/

- Symfony Testing Guide: https://symfony.com/doc/current/testing.html

Ready for Production?

If you are ready to get your code into production, let’s discuss it.

MagneticOps can collaborate with your team to set up your CI/CD pipeline and support the deployment of your application at scale.

You won’t have to guess. You won’t need FTP. You will have smooth, modern, and reliable deployment workflows designed for today and the future.

#PHP #CICD #DevOps #WebDevelopment #DeploymentAutomation #MagneticOps #EngineeringExcellence


Dockerizing PHP Like a Pro

Dockerizing PHP Like a Pro

magnetic mi
Category: DevOps
23 July 2025
Hits: 379
Rating:
( 0 Rating )

At MagneticOps, we come in contact with a surprising number of clients who have yet to start on their DevOps journey and who’ve never touched Docker. In today’s fast-moving development landscape, consistency, portability, and scalability are key ingredients of success. Whether you’re a solo developer or managing a full-stack team, Docker is your secret weapon for building reliable, repeatable environments, not to mention leveraging or even assessing new server-side technologies.

Docker has become a ubiquitous part of the development-build-test-deploy lifecycle, and if you are working with PHP - like we do - this is no exception. Let’s explore how to Dockerize your PHP application like a pro using modern, community-validated images and best practices.

Why Docker for PHP?

Before diving into the how, let’s nitty-gritty of the why:

  • Consistent environments across dev, staging, and production
  • Faster onboarding for new developers—just pull and run
  • Microservice readiness using NGINX, MySQL, Redis, and more
  • CI/CD compatibility with modern pipelines

Whether you're running Laravel, Symfony, or vanilla PHP, Docker simplifies your stack and removes the classic “but it worked on my machine!” headache.

Getting Started with a Hello World App

To help developers get started quickly, here's a basic 'Hello World' setup using PHP and NGINX. Place this index.php file in your project root:

<?php echo "Hello, World!"; ?>

Sample Docker Setup Using NGINX-Based Community Image

For a professional, extensible, and community-maintained Docker PHP stack, we’ll use the NGINX-based variation provided by the open-source project at ServerSideUp (very cool, you should check them out). Their images are tailored for production and development use-cases and offer a cleaner separation of concerns compared to other images we’ve seen.

Here’s an example docker-compose.yml file  using their images:

version: '3.8'

services:
  app:
    image: serversideup/php:8.2-fpm-nginx
    ports:
      - "8000:80"
    volumes:
      - .:/var/www/html
    environment:
      APP_ENV: local
      PHP_DISPLAY_ERRORS: "true"

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app_db
    ports:
      - "3306:3306"

Running docker compose up with that file in the root of your project will cycle through those instructions, and build your ‘app’ and run a database locally for you.

Base image documentation: https://serversideup.net/open-source/docker-php/docs/getting-started/these-images-vs-others

Extending Your Image

Here is a practical and production-ready Dockerfile example that extends the ServerSideUp php:8.2-fpm-nginx image, commonly used by clients who need custom extensions or configuration tweaks:

In many cases our clients will need more customization of their image, installing special PHP extensions, or tweaking nginx. You get all this done by defining those instructions in the Dockerfile.

Sample Dockerfile: Extending the serversideup/php:8.2-fpm-nginx image

# Start from the official ServerSideUp PHP + NGINX image
FROM serversideup/php:8.2-fpm-nginx

# Set working directory
WORKDIR /var/www/html

# Install additional system packages (e.g., git, zip, and PHP extensions)
RUN apt-get update && apt-get install -y \
    git \
    zip \
    unzip \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install gd
# Optional: Add Xdebug or other dev tools
# RUN pecl install xdebug && docker-php-ext-enable xdebug

# Copy custom php.ini overrides
COPY .docker/php.ini /usr/local/etc/php/conf.d/99-custom.ini

# Copy application files
COPY . .

# Set proper ownership
RUN chown -R www-data:www-data /var/www/html

# Expose port 80 for NGINX
EXPOSE 80

Notes:

  • Custom php.ini file: You can create a local config at .docker/php.ini with overrides like:
  • You will want to tweak your nginx root directory to serve only files you want to expose in your application. Consider /var/www/html/public and move your ‘index.php’ file there.
display_errors=On
upload_max_filesize=50M
memory_limit=512M

  • Add more layers for supervisor, cron, or queue workers as needed.
  • This pattern gives you full control while preserving the structure of a reliable base image.

Dev & Debug Tips

Here are some real world gems that can help push your Docker in the right direction

  • Use volumes to sync your code during development
  • Enable Xdebug if needed by extending the serversideup image
  • Keep services modular—PHP-FPM, NGINX, queues, and cron should be split
  • Use .dockerignore and multi-stage builds to reduce image size and speed up CI/CD

Testing in Containers

Testing inside Docker ensures consistency across dev and CI environments. You can execute PHPUnit directly inside the container:

docker exec -it <app_container> vendor/bin/phpunit

You can automate this step in your CI/CD pipelines when you are ready.

Ready for Production?

If you are ready to get your code into production, let’s talk about it! MagneticOps can work directly with your team on implementing your CI/CD pipeline and help guide production deployments of your application at scale.

Final Thoughts

Dockerizing PHP using an NGINX-based architecture is a powerful way to modernize your workflow. Leveraging open-source images like those from ServerSideUp gives you more transparency, greater control, and production-level quality from the start. This approach helps eliminate environment-specific issues and supports a scalable, secure, and collaborative development process.

References

- ServerSideUp Docker PHP Stack Documentation: https://serversideup.net/open-source/docker-php/

- These Images vs. Others: https://serversideup.net/open-source/docker-php/docs/getting-started/these-images-vs-others

- Docker Compose Docs: https://docs.docker.com/compose/

- PHP Docker Best Practices: https://phpdocker.io/

- Official MySQL Docker Image: https://hub.docker.com/_/mysql

What’s Your Stack Look Like?

Have you Dockerized your PHP project using NGINX yet?

What tools, setups, or lessons would you share?

Drop your thoughts in the comments!

Share this article with your team or dev community.

#PHP #Docker #NGINX #DevOps #WebDevelopment #Containers #OpenSource #LinkedInTech

Custom Post

© 2025 MagneticOps. All Rights Reserved.
  • Home
  • Our Services
  • Blog
Loading…
We use cookies to improve your experience on our website. By browsing this website, you agree to our use of cookies. Read more about our Privacy Policy.
I accept