October 2, 2017 | Last updated: February 6, 2024
Share:
PHP delivery overview
The deployment process of web apps depends on a wide range of factors: back and front-end architecture, type of server or IaaS platform (AWS, GCP, Azure Portal, etc.), infrastructure limitations, even team preferences towards specific tools and frameworks. A most generic type of workflow for delivering PHP apps usually involves the following steps:
- Run unit tests on PHP application
- Run
composer install
to download dependencies - Compile assets with Webpack/Parcel/Gulp
- Upload to web server with an FTP client or PHP deployment tool
Of course, different web applications may require different steps. For example, you may want to configure required app services (libraries, databases, etc.), populate environment variables, run post-deployment scripts on the server – everything depends on the specifications of your PHP app, company workflow, and hardware at disposal.
Stop everything and read this now
Before we proceed with deploying PHP apps, there are two things that need to be emphasized every single time the word "deploy" comes into play:
I. Keep everything in version control!
Application source code, configuration files, documentation, db migration scripts — all of them should be kept safe and sound in Git, be it a GitHub repository, Bitbucket, GitLab, or any other provider.
Of course, to every rule there are exceptions (especially in IT), which brings us to the second thing:
II. Never store dependencies and compiled apps in version control!
Keeping dependencies and artifacts in the Git repository will cause it to bloat and sooner or later will mess up your entire project. This leads to one thing that developers hate doing: solving conflicts in code.
How to deploy PHP projects: 5 workflows
Now that we know what not to do, let's proceed to the 5 ways of proper PHP deployment.
#1. Deploy repo w/o dependencies and artifacts and build your app on server
- First, we need to build and test the app. We can do it either on a local machine (CI server), or in a cloud service
- Once the tests pass, we can upload the source code to the server via FTP, SFTP or Rsync (in this case without dependencies and artifacts).
- The final step is downloading the dependencies and building the app by running Composer on the server via SSH.
Translated into a deployment tool pipeline, the whole process looks like this:
A pipeline which builds the web app on the server
Pros & Cons
- The build environment of the PHP app is exactly the same as the running environment.
- Dependencies will download faster as they're fetched from the closest mirror.
- If you don't employ any deployment practice to minimize the downtime, the time required to download the dependencies and build the application may extend it.
- Even on a small change, the build time may be long and impact the performance of the production server.
#2. Deploy repo with dependencies and artifacts
In this workflow, PHP applications are first compiled and tested, then uploaded to the web server with dependencies and artifacts using a deployment tool:
A pipeline which builds the web app locally before the deployment
Pros & Cons
- The production server is not stressed with the build.
- The application on production is the same as the application from the test server.
- You don't need SSH access to the server to run scripts = any old school FTP will do.
- You must provide the same build environment as the running environment for the application.
- Since we deploy everything from the source code repository, the upload time can be long.
#3. The Git variation
This deployment strategy is basically the same as #1, but requires Git installed on the production server. The deployment from the source code repository is made with git push
instead of regular file upload. Then, in Git, the post-receive hook triggers building the application code.
A pipeline which builds the web app and pushes the files to a Git server
Pros & Cons
- Git deployment is faster, because only changesets are deployed
- You don't need to run SSH scripts, because the webhook will call them on the server
- If you don't use any mechanism to minimize the downtime (e.g. atomic deployment), the time required to download the dependencies and build the application may extend the downtime
- The build time may be long and impact the performance of the production server
#4. Zero-downtime / Atomic deployment
The workflows above have one flaw: the downtime. This means your web app will not be available for the client during the deployment. The solution to that is very simple: deploy and build the application in a different folder than the one from which it's served.
Atomic deployment
The process involves creating a couple of directories on the server:
/current
- a symbolic link to the web app's current version in the releases directory to which your web server points./releases
- contains the history of uploaded releases. For each version a directory with the name of the revision tag is created./deploy-cache
- used for storing new files during the deployment. Once the upload has finished, its contents are copied to a new directory in the/releases
directory.
Here's how it works:
- A new version of the web app is uploaded to
deploy-cache
- The contents of
deploy-cache
are copied to/releases/${revision}
- The current symbolic link is switched to
/releases/${revision}
An atomic deployment template which creates and switches the upload directories on the server
Pros & Cons
- Downtime reduced basically to zero (the time required to create a symlink)
- Instant rollback – the previous version of application remains on the server after the deployment; all you need to do is switch back the symlink
- More space on the web server is required to keep the previous revisions
- A lot of scripts to write (unless you use a preconfigured template)
#5. Docker deployment
The last method to deploy a PHP application involves containerization with Docker – a virtualization method that allows you to define the working environment of your application in a single text file called Dockerfile. The file is then used to build a Docker image with your app that can be launched in any environment supporting Docker (Linux/MacOS/Windows).
Here's a PHP Docker example written down to a Dockerfile:
FROM php:7
RUN apt-get update -y && apt-get install -y openssl zip unzip git
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN docker-php-ext-install pdo mbstring
WORKDIR /app
COPY . /app
RUN composer install
CMD php artisan serve --host=0.0.0.0 --port=8181
EXPOSE 8181
The file can be used to build a Docker image:
docker build -t my-image .
$
Once the image is built, you can launch your application in a Docker container isolated from its host:
docker run -p 8081:8081 my-image
$
On top of that, Docker images can be pushed and pulled from a Docker registry. This way you can easily build an image on one server or PC, and run it on another. In this case, the whole delivery process will look like this:
- Test application
- Build Docker image with application
- Push application to Docker registry
- SSH to live server and run
docker pull
docker run
$$
A pipeline which builds a Docker image and runs it on a server
Pros & Cons
- The application works on every type of setup which eliminates the "strange, it works for me" error
- Easy rollback – you just run the previous version of the image
- Build configuration and application environment is documentation in the Dockerfile in the repository
- Yet another tech that adds to the software stack
- Some users claim that Docker is not production ready
Additional resources
Alexander Kus
Customer Success Manager
With Buddy even the most complicated CI/CD workflows take minutes to create
Sign up for Buddy CI/CD
Start a free trial