5 ways to deploy PHP applications
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:
Image loading...
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:
Image loading...
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.
Image loading...
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.
Image loading...
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}
Image loading...
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:
dockerFROM 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:
bashdocker build -t my-image .
$
Once the image is built, you can launch your application in a Docker container isolated from its host:
bashdocker 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
bashdocker pull docker run
$$
Image loading...
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
Jarek Dylewski
Customer Support
A journalist and an SEO specialist trying to find himself in the unforgiving world of coders. Gamer, a non-fiction literature fan and obsessive carnivore. Jarek uses his talents to convert the programming lingo into a cohesive and approachable narration.