Using Gitlab to Deploy Laravel App to Shared Hosting via SSH

I developed some small sites for organizing events with my friends or supporting some blogs all hosted on a shared hoster service in Switzerland (if you are considering using cyon too, please use my referral link at the end of this blog post).

Sometimes I have to quickly fix or change things and then annoy me that it is so tedious to connect via ssh and do everything right when updating the latest version of the app. In the case of Laravel I have to clear the caches and install newest composer packages.

As I use Gitlab for some other projects together with Laravel Forge (, Also a great service to use with your own VPS), I searched a way to automate this in a more restricted shared hosting environment.

Here is how I did it.

Setup Project

Just setup the Site as you as you would normally do. Then checkout your project via git from gitlab. In this example it’s done with the following:

cd /path/to/site
git clone [email protected]:okaufmann/gitlab-shared-hoster-example.git

Of course you have to setup the DNS but I’ll not cover that here.

Configure CI/CD

Just study the following Guide to to the whole thing together with Laravel Envoy (what I haven’t used yet).

This guide works without Laravel’s Envoy.

# As the deployer user on server
# Copy the content of public key to authorized_keys
cat ~/.ssh/ >> ~/.ssh/authorized_keys
# Copy the private key text block
cat ~/.ssh/id_gitlab

Add cat ~/.ssh/ to deploy keys of your repository in gitlab.

Environmen Variables set (don’t want them to be in my configs!):


Use this .gitlab-ci.yml config:

image: mightycode/docker-laravel-dusk:latest

  - test
  - deploy

  - vendor/
  - node_modules/

  stage: test
  - bash build/
  - ./vendor/bin/phpunit --coverage-text --colors=never

# test:ui:7.1:
#   stage: test
#   script:
#    - bash build/
#    - cp .env.dusk.testing .env
#    - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
#    - php artisan serve &
#    - php artisan dusk
  stage: deploy
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - ssh-add <(echo "$SSH_PRIVATE_KEY")
    - mkdir -p ~/.ssh
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

    - ssh -t $SERVER_USER@$SERVER_PROD "cd ${PROD_PATH} && sh build/"

    name: production
  when: manual
      - master (run in docker image mightycode/docker-laravel-dusk:latest or any other php testing docker container image)


# We need to install dependencies only for Docker
[[ ! -e /.dockerenv ]] && [[ ! -e /.dockerinit ]] && exit 0

# ensure node
nvm install node

set -xe

composer install --no-progress  --ignore-platform-reqs
npm install -g yarn
yarn run dev -- --progress=false (Run via ssh on server to simplify process)


php70 artisan clear-compiled

git pull origin master --tags

composer install --no-interaction --no-dev --prefer-dist

php70 artisan optimize

php70 artisan config:cache
php70 artisan cache:clear
php70 artisan view:clear
php70 artisan migrate --force --step

php70 artisan up


Configure Runner for better Performance

Don’t forget to configure cache correctly on the runner (Safes a lot of time!)
sudo vim /etc/gitlab-runner/config.toml

My Actual runner config

concurrent = 1
check_interval = 0

  name = "server-name-goes-here"
  url = ""
  token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  executor = "docker"
  environment = ["COMPOSER_CACHE_DIR=/cache"]
    tls_verify = false
    image = "python:3.5"
    privileged = false
    disable_cache = false
    volumes = ["/var/cache:/cache:rw"]
    cache_dir = "/cache"

sudo gitlab-ci-multi-runner restart

Support this Post by using my referral link:

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top