Downtime & Symlinks
Using Symlinks for a Zero-downtime Deployment
We'll be automating a deployment strategy with Fabric. However, first, let's see what that process is by doing it manually.
Log into the server as user admin, who can use sudo.
Nginx
Let's change the root directory back to what we had a few videos ago.
server {
# Items skipped for brevity
root /home/serial/serialapp.com/current/public;
# Items skipped for brevity
}
We changed the root directory from the repository (/home/serial/serialapp.com/repo/public) to the current/public directory, where our deployed files will live.
Test and reload Nginx after that change:
sudo service nginx configtest
sudo service nginx reload
Deployment with Symlinks
Log in as the serial user and head to our project directory at ~/serialapp.com.
Github Repo
We'll move the github repo to be one level up, so we end up with:
~/serialapp.com
|-- current
|-- -- public
|-- repo
The steps to do that:
cd ~/serialapp.com
mv current/repo ./
Persist Directory
Next we want to create a directory where files that should persist across deployments should live. These will be environment files, cache file, log files and similar.
cd ~/serialapp.com
mkdir persist
And move our application's .env file there:
cd ~/serialapp.com
mv repo/.env persist/.env
And then we'll take our Laravel application's storage directory, which contains cache and log files that we don't want to lose in deployments:
cd ~/serialapp.com
cp -r repo/storage ./persist/
Releases
We want a place to put the code that we'll use for each release (each deployment). We'll simply name this the releases directory:
cd ~/serialapp.com
mkdir releases
Build Process
We have files in place now, let's see the manual steps to take in order to deploy.
cd ~/serialapp.com/repo
# Get the latest code
git pull origin master
# We'll build a deployment in a new directory which has a timestamp
# as a name. In this case, dir name 1436408501
mkdir ~/serialapp.com/releases/`php -r "echo time();"`
# Build an archive of the site
cd ~/serialapp.com/repo
git archive --worktree-attributes master | tar -x -C ~/serialapp.com/releases/1436408501
# Double check that the files are now in our
# new release directory
ls -lah ~/serialapp.com/releases/1436408501
# Clear our storage, since we want to use our
# storage from "persist"
rm -rf ~/serialapp.com/releases/1436408501/storage
# Create symlinks to symlink needed files to the latest release
#
## Symlink our .env file
ln -nfs ~/serialapp.com/persist/.env ~/serialapp.com/releases/1436408501/.env
## Symlink our storage directory
ln -nfs ~/serialapp.com/persist/storage ~/serialapp.com/releases/1436408501/storage
## Finally get it up and running in "current" dir
## This is setting us up to use our Nginx web root
ln -nfs ~/serialapp.com/releases/1436408501 ~/serialapp.com/current
## Build our application composer dependencies
cd ~/serialapp.com/releases/1436408501
php composer install
And that's it! On our next release, we would:
- Make a new timestamp release directory
- Get the latest code in the Git repo
- Use
git archiveto get a copy of the site at that commit to our new release directory - Build composer dependencies in that directory
- Symlink the
.env,storageand finallycurrentdirectory to make the latest code live
Moving on, we'll automate this process in Fabric.