Building a Laravel application using Travis CI

laravel

Montana here, and in this blog post, we are going to setup a Laravel application that has tests (unit) to properly simulate code integration and explain Travis CI’s linear and sometimes not so linear process, which is why Travis CI is one of the most flexible CI/CD’s on the market today.

SSH Keys

The only thing you’re going to need for this tutorial is a server with SSH access, for this I recommend DigitalOcean. So first thing is first let’s generate those SSH keys we were just talking about. With that being said, let’s dig into it. Let’s start out with the ssh command.

ssh root@203.0.113.0

These inputs are examples. In various cases you may have variant SSH keys. In the case of having multiple SSH keys, you’ll need to specify the path of your private key using the -i flag, as in ssh -i /path/to/private/key username@203.0.113.0. Remember using the -i flag means SSH is now specifying the identity_file. If you don’t have multiple SSH instances, you can omit this option.

Let’s get started

So, now we’ve SSH’d into the host machine that we’ve wanted to via specification. For this user, we now need to setup a SSH key and have it mirrored on the local machine. So first let’s run:

cd ~/.ssh && ssh-keygen -t rsa -b 4096 -C "Montana"

You then should see what everyone would see in this situation:

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/xxx/.ssh/id_rsa): montana_rsa
Enter passphrase (empty for no passphrase):

You now need to add that key as an authorized and recognized key on the server.

cat id_rsa.pub >> authorized_keys

Let’s look at the output of this using cat again, and be sure this is be doing in the ~/.ssh directory, there are sometimes where people have created ~/.rsa and causes a problem that needs to actually exist.

So let’s call the key for output:

cat id_rsa.pub

Invoking the public key

So let’s start adding these keys to GitHub:

eval "$(ssh-agent -s)"
> Agent pid 59566

Now it’s time to add the SSH private key to the ssh-agent and store it in the keychain. If you created your key with a different name, or if you are adding an existing key that has a different name, replace id_ed25519 in the command with the name of your private key file, so for example the name I have is id_montana.

ssh-add -K ~/.ssh/id_montana

Great now your keys are officially added! Now to make life a little easier I’ve done the due dilligence and have found a premade build image so you don’t potentially run into any composer issues. Create a file called the Dockerfile.

The Dockerfile

The Dockerfile should look like the following:

# Montana's hunted down prebuild for Laravel:
FROM '123majumundur/php-7.1-nginx:cicd'

# Install prestissimo for faster deps instalation
RUN composer global require hirak/prestissimo

# Make directory for hosting the apps
RUN mkdir /home/app/app
WORKDIR /home/app/app

# Install dependencies
COPY composer.json composer.json
RUN composer install --prefer-dist --no-scripts --no-dev --no-autoloader && rm -rf /home/app/.composer

# Copy codebase
COPY --chown=app:root . ./

# Finish composer
# RUN composer dump-autoload

RUN composer dump-autoload --no-scripts --no-dev --optimize

EXPOSE 8080

Make sure you look at it from your CLI or IDE (in this case I’m using cat).

cat

The private key

We as a user, need to ensure Travis can connect to the server and initiate the pull process that updates what is on the server, so simple read/write functionality will suffice for now. Next we will be using the scp command.

scp

Change directories, then run:

scp {SERVER_USER}@{SERVER_IP}:/home/{SERVER_USER}/.ssh/id_rsa ./deploy_key

Immediately after the fetch is done, add deploy_key to your .gitignore by executing:

echo 'deploy_key' > .gitignore

Now open your .travis.yml in the CLI by running:

touch .travis.yml

Now remember in the step before we grabbed deploy_key, let’s encrypt that:

travis encrypt-file ./deploy_key --add

40564928-8b1209f2-6062-11e8-83a1-2a0df73fe519

You’ll now notice this in your .travis.yml, not key for key, but similar:

before_install:
  - openssl aes-256-cbc -K $encrypted_a382b94461d2_key -iv $encrypted_db32b44003d2_iv
  - in deploy_key.enc -out ./deploy_key -d 
  
  # Travis CI YAML format plugin by Montana Mendy executed 

Testing Travis CI and Deployment

Let’s start testing Travis CI, I’m going to share my .travis.yml as it stands currently:

os:
  - linux
language: php
dist: trusty
php:
  - '7.1'
services:
  - docker
jobs:
  include:
    - stage: "Tests"                
      name: "Unit Test PHP"  
      script: 
      - travis_retry composer self-update
      - travis_retry composer install --prefer-source --no-interaction
      - cp .env.example .env
      - php artisan key:generate
      - vendor/bin/phpunit tests/Feature/ExampleTest.php
    - stage: "Build Docker Image"
      name: "Build Images Docker" 
      script:
      - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
      - docker build -t travis-ci-build-stages-demo .
      - docker images
      - docker tag travis-ci-build-stages-demo $DOCKER_USERNAME/cicd-laravel
      - docker push $DOCKER_USERNAME/cicd-laravel

da60c4065017b4596f3ea7289be9cdb8f8c474d4

You can also set your env vars in the UX/UI portion of Travis for a bit simpler solution to the CLI method as I showed above.

Model Factories

My take on Model Factories specifically in a tutorial esque use case like this, it’s good to use something like faker, you’ll see how this came into handy if you view my entire repo.

faker

Conclusion

Well there you have it, you’ve hopefully successfully are using Laravel and Travis CI. We dealt with SSH keys, spc, and a lot more. So if you got through this congratulations!

I will link you to my repository of all my code in it. So you can fork it, clone it, and use it yourself. You can find the GitHub repo correlated with my blog post here: Laravel + Travis CI Test: Montana’s Repo.

Happy Building!
Montana Mendy