People get hacked easily when they include the environmental files or passwords in version control. Yet keeping it all local makes each and every deployment to OpenShift troublesome as you will need to scp
the environmental file .env
onto server every time you deploy.
You can set up an action hook to create a symbolic link inside the deployment directory to $OPENSHIFT_DATA_DIR
which keeps the .env
persistently. I know this has been covered in a previous tutorial but it doesn’t hurt repeating myself as a reminder of this security trick.
Img. Tried my luck with some keywords, obviously people still do that nowadays
Moreover, a team of students from a class I am mentoring got themselves a $10,000 AWS bill because they published the .pem
files on GitHub and somehow got hacked.
Img. I told them to use OpenShift instead of AWS for educational purpose
Now you see how important and trouble-free it is if your server and your local environments keep their configurations to themselves. Let’s see how you can do it.
Preparation
First you should prepare an OpenShift instanace and a Laravel build on your local machine. My previous tutorial should get this part well covered.
Managing multiple .env locally
To cover the basics, you should first try to have multiple .env
locally. You may use an artisan command I made before or archieve the same effect with symbolic link.
In command line, create a couple of environmental configuration files from your Laravel directory by copying the default .env.example
.
$ cp .env.example .local.env
$ cp .env.example .testing.env
Then make sure this line is inside your .gitignore
file.
.env
By default Laravel does not come with .env
file, so there is nothing to ignore yet. Then create a symbolic link to .local.env
named .env
.
$ ln -s .local.env .env
$ ls -lah
lrwxrwxrwx 1 user user 10 Sep 28 18:21 .env -> .local.env
-rw-rw-r-- 1 user user 306 Jul 2 02:30 .local.env
So .env
is now a symbolic link to .local.env
, modifying either of them changes both. How do you switch to testing environment locally?
$ rm .env
$ ln -s .testing.env .env
That’s it. Don’t worry, removing symbolic link doesn’t remove the actual file.
Uploading .env
to server
Provided that yout have SSH access to the server (you do so by submitting your public key to OpenShift web panel), first SSH into the server to locate $OPENSHIFT_DATA_DIR
.
# figure out the user name and hostname of your OpenShift instance
$ git remote -v
origin ssh://[email protected]/~/git/blog.git/ (fetch)
origin ssh://[email protected]/~/git/blog.git/ (push)
# ssh into the instance to find where the data dir is
$ ssh [email protected]
# on remote server
[test-test.rhcloud.com xxxxxxxxxxxxxxxxxxxxxxxx]\> echo $OPENSHIFT_DATA_DIR
# this is the path to data dir where you should store the .env
/var/lib/openshift/xxxxxxxxxxxxxxxxxxxxxxxx/app-root/data/
Now scp
the current .env
you use locally to server. Note that .local.env
is renamed to .production.env
when it is uploaded. You could make .production.env
locally, edit the configuration then upload instead.
$ scp .local.env [email protected]:/var/lib/openshift/xxxxxxxxxxxxxxxxxxxxxxxx/app-root/data/.production.env
Now .production.env
is on the server, next you should create a symbolic link to it whenever you deploy a new version of your software.
Creating a build hook
Git runs a post-receive hook if you write it in .git/hooks/
. OpenShift plays a different rule, it runs the scripts located in .openshift/action_hooks/
as well. From your project root folder, create folders .openshift/action_hooks/
if they weren’t there already, then make a build
file and flip the execute bit.
$ mkdir -p .openshift/action_hooks
$ touch .openshift/action_hooks
$ chmod +x .openshift/action_hooks
Then, make sure your build
file has these content.
#!/bin/bash
export COMPOSER_HOME="$OPENSHIFT_DATA_DIR/.composer"
if [ ! -f "$OPENSHIFT_DATA_DIR/composer.phar" ]; then
echo 'Installing Composer'
curl -s https://getcomposer.org/installer | php -- --quiet --install-dir=$OPENSHIFT_DATA_DIR
else
echo 'Updating Composer'
php $OPENSHIFT_DATA_DIR/composer.phar -q --no-ansi self-update
fi
if [ -d "$OPENSHIFT_REPO_DIR/vendor" ]; then
echo 'Laravel dependencies already installed, Moving on...'
else
echo 'Hang in there, we are getting ready to Install/Update Laravel dependencies'
# Activate composer install for Laravel on Git Push
( echo 'Installing/Updating Laravel'; unset GIT_DIR ; cd $OPENSHIFT_REPO_DIR ; php $OPENSHIFT_DATA_DIR/composer.phar -q --no-ansi install ; )
fi
( echo 'Loading environmental configurations'; ln -s "$OPENSHIFT_DATA_DIR/.production.env" "$OPENSHIFT_REPO_DIR/.env"; cd $OPENSHIFT_REPO_DIR; )
The first couple lines will fetch the dependencies automatically, and the last line with words Loading environmental configurations makes sure a symbolic link .env
pointing to .production.env
is created each time you push to server.
Why it has to be so cryptic?
Albeit a little bit off-topic, this question keeps popping up in my mind as I wrote this article. From my experience with Ruby on Rails, you can deploy and do the symbolic link thing all inside the confines of your project; i.e. no need for a sneaky hook in .openshift
or .git
.
Then when I looked it up, someone did use a Ruby gem Capistrano
to deploy his Laravel application.
Deploying a PHP project, using a Ruby gem. That’s ingenius.
And it goes no further than that, no automatic push-from-local ways of deploying a Laravel application except for bunch of hacks and cryptic scripts.
Yeah, next time, let’s talk about a simplier Laravel deployment.