Skip to content

Instantly share code, notes, and snippets.

@axeloz
Last active November 2, 2022 07:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save axeloz/addcb53113e51f7b19655097ee7517ee to your computer and use it in GitHub Desktop.
Save axeloz/addcb53113e51f7b19655097ee7517ee to your computer and use it in GitHub Desktop.
DroneCI Laravel app Back and Front Testing and Deployment
#####
#
# Because it took me a sh*tload of time to make this work (and I mean it), I'm sharing with you my config file.
# There aren't that many .drone.yml samples around working with PHP / Laravel / MySQL ...
# So I had to do everything from scratch. Hope you'll find this useful
#
#####
#
# DroneCI (https://www.drone.io) is an open source CI/CD written in Go. It comes with a server and a runner started in Docker containers
# The following pipelines are:
# - cloning the repository
# - boostraping MariaDB + NodeJS + PHP8.1
# - installing dependencies
# - building the front with Laravel Mix
# - running Unit/Feature testing on the back
# And if the previous tasks are successful:
# - Starting a deployment with DeployPHP (https://deployer.org)
# - Sending an email notification report with SUCCESS or FAIL and build details
#
# Requirements:
# You need:
# - drone-server (https://docs.drone.io/server/overview/) and drone-runner (https://docs.drone.io/runner/overview/) up and running
# - setup the DroneCi integration with your Git repository
# - install the Drone CLI on your machine (https://docs.drone.io/cli/install/)
# - add a secret key in DroneCI containing your SSH private key
# - change / adapt the following config to your needs
# - some time and perseverance
#
#####
---
###########
# TESTING #
###########
kind: pipeline
type: docker
name: testing
platform:
os: linux
arch: amd64
workspace:
path: /drone/src
services:
- name: mariadb
image: mariadb:10.5.17 # you may adapt the version / db server
environment:
MARIADB_DATABASE: db_test # you may change this, must reflect in .env.testing
MARIADB_ROOT_PASSWORD: password # you may change this, must reflect in .env.testing
steps:
- name: frontend
pull: if-not-exists
image: node:16.18-bullseye-slim
commands:
- npm install
- npm run production
- name: backend
pull: if-not-exists
image: laradock/workspace:latest-8.1 # you may change version, see Laradock
depends_on:
- mariadb
- frontend
commands:
- composer install --prefer-dist
- php artisan test --testsuite=Feature --stop-on-failure --coverage
trigger:
branch:
- master # you may change this
event:
- push
- pull_request
---
##############
# DEPLOYMENT #
##############
kind: pipeline
type: docker
name: deployment
depends_on:
- testing
clone:
depth: 0
steps:
- name: deploy
image: php:8.1.12-cli-bullseye
when:
status:
- success
environment:
SSH_KEY:
from_secret: PRIVATE_KEY # must be set in Drone CI
commands:
- apt update && apt install -yq openssh-client wget
- eval "$(ssh-agent -s)"
- echo "$SSH_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh && touch ~/.ssh/known_hosts
- chmod 600 ~/.ssh/known_hosts
- ssh-keyscan -H <your-server-hostname> >> ~/.ssh/known_hosts 2> /dev/null # you must adapt this
- wget https://github.com/deployphp/deployer/releases/download/v7.0.2/deployer.phar
- chmod +x deployer.phar
- ./deployer.phar deploy
- name: notify
image: drillster/drone-email
when:
status:
- success
- failure
settings:
repo: owner/myrepo # you must change this
host: <smtp_host> #you must change this
username: <smtp_username> # you must change this
password:
from_secret: email_password # Must be set below (or in Drone secrets)
from: <from_email> # you must change this
recipients:
- <cc_recipients> # you must change this of remove it
subject: >
[{{ build.status }}]
{{ repo.owner }}/{{ repo.name }}
({{ commit.branch }} - {{ truncate commit.sha 8 }})
body:
# The following Gist is the Body template
# You may create your own template
# Here is where I found the constant names: https://github.com/Drillster/drone-email/blob/master/main.go
https://gist.githubusercontent.com/axeloz/fe62bfbd2b6756bb42f4d744cd4d1d43/raw/0323cca311a47dfc33fd77da7ab98b6d350092e8/template.html
trigger:
status:
- success
---
kind: secret
name: email_password
data: iPZ8jE9TSeppl/wmUFCCzi0LZD8Jg== # you must generate the secret with Drone CLI
---
kind: signature
hmac: d961684b3ace8361a07d0375422 # you must adapt this with Drone CLI or you may remove signature if not needed
...
<?php
namespace Deployer;
require 'recipe/laravel.php';
// Config
set('repository', 'ssh://git@git.domain.com/owner/repo.git');
set('branch', 'master');
set('update_code_strategy', 'archive');
set('keep_releases', 5);
add('shared_files', ['.env']);
add('shared_dirs', ['storage', 'vendor', 'node_modules']);
add('writable_dirs', ['storage']);
// Hosts
host('box.domain.com')
->set('remote_user', 'deploy')
->set('deploy_path', '/var/www/app');
// Hooks
task('deploy:build-assets', function () {
cd('{{release_path}}');
run('npm install');
run('npm audit fix');
run('npm run prod');
})->desc('Building JS/CSS assets');
after('deploy:update_code', 'deploy:build-assets');
after('deploy:failed', 'deploy:unlock');
docker run \
--volume=/var/lib/drone:/data \
--env=DRONE_GITEA_SERVER=https://git.domain.com \
--env=DRONE_GITEA_CLIENT_ID=1804-48-6f-a-3654 \
--env=DRONE_GITEA_CLIENT_SECRET=thKjgVPn9wOdMk99le \
--env=DRONE_RPC_SECRET=3d1019d077dc \
--env=DRONE_SERVER_HOST=ci.domain.com \
--env=DRONE_SERVER_PROTO=https \
--env=DRONE_TLS_AUTOCERT=false \
--env=DRONE_USER_CREATE=username:<admin_username>,admin:true \
--publish=8000:80 \
--restart=always \
--detach=true \
--name=drone-server \
drone/drone:2
docker run --detach \
--volume=/var/run/docker.sock:/var/run/docker.sock \
--env=DRONE_RPC_PROTO=https \
--env=DRONE_RPC_HOST=ci.domain.com \
--env=DRONE_RPC_SECRET=3d1019d077dc \
--env=DRONE_RUNNER_CAPACITY=2 \
--env=DRONE_RUNNER_NAME=drone-runner-1 \
--publish=3000:3000 \
--restart=always \
--name=drone-runner-docker \
drone/drone-runner-docker:1
# Nginx config
server {
server_name ci.domain.com;
ssl_certificate /etc/letsencrypt/live/ci.domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/ci.domain.com/privkey.pem; # managed by Certbot
listen 443 ssl http2;
ssl_session_cache builtin:1000 shared:SSL:10m;
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Host $http_host;
proxy_pass http://192.168.50.6:8000; # Had to use local IP, adapt or find a workaround if you can
proxy_redirect off;
proxy_http_version 1.1;
proxy_buffering off;
chunked_transfer_encoding off;
}
}
server {
if ($host = ci.domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name ci.domain.com;
return 404; # managed by Certbot
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment