Skip to content

Instantly share code, notes, and snippets.

@heartshare
Forked from uxweb/.gitlab-ci.yml
Created October 17, 2022 07:36
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 heartshare/3c075aa3c6819c06282063df30494719 to your computer and use it in GitHub Desktop.
Save heartshare/3c075aa3c6819c06282063df30494719 to your computer and use it in GitHub Desktop.
Laravel application build and deployment with GitLab CI
image: docker:19.03
services:
- name: docker:19.03-dind
variables:
# ENABLE DOCKER BUILDKIT
DOCKER_BUILDKIT: 1
DOCKER_TLS_CERTDIR: "/certs"
DOMAIN: futurofficevalencia.es
PHP_IMAGE_TAG: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}
NGINX_IMAGE_TAG: ${CI_REGISTRY_IMAGE}/nginx:${CI_COMMIT_SHORT_SHA}
WEBROOT: /home/${SSH_USER}
STORAGE_PATH: ${WEBROOT}/storage
RELEASES_PATH: ${WEBROOT}/releases
CURRENT_PATH: ${WEBROOT}/current
stages:
- build_nginx
- build_php
- test
- review
- deploy
before_script:
- mkdir -p ~/.docker
- echo "$TLSCACERT" > ~/.docker/ca.pem
- echo "$TLSCERT" > ~/.docker/cert.pem
- echo "$TLSKEY" > ~/.docker/key.pem
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
build_nginx:
stage: build_nginx
only:
refs:
- branches
# RUN THIS JOB ONLY WHEN ANY OF THESE FILES CHANGES
changes:
- public/**/*
- resources/**/*
- .docker/nginx/**/*
- docker-stack.*
- package.json
- tailwind.config.js
- webpack.mix.js
- .gitlab-ci.yml
script:
# BUILD THE NEW IMAGE...
- >
docker image build
--build-arg BUILDKIT_INLINE_CACHE=1
--build-arg ENV_BUILD=development
--cache-from ${CI_REGISTRY_IMAGE}/nginx:latest
--tag ${CI_REGISTRY_IMAGE}/nginx:latest
--tag ${NGINX_IMAGE_TAG}
--label es.futurofficevalencia.ci.project.url=${CI_PROJECT_URL}
--label es.futurofficevalencia.ci.pipeline.id=${CI_PIPELINE_ID}
--label es.futurofficevalencia.ci.pipeline.url=${CI_PIPELINE_URL}
--label es.futurofficevalencia.ci.job.id=${CI_JOB_ID}
--label es.futurofficevalencia.ci.job.url=${CI_JOB_URL}
--file .docker/nginx/Dockerfile
.
# PUSH THE NEW IMAGE TO THE CONTAINER REGISTRY OVERWRITING THE LATEST TAG...
- docker image push ${NGINX_IMAGE_TAG}
- docker image push ${CI_REGISTRY_IMAGE}/nginx:latest
after_script:
- docker logout ${CI_REGISTRY}
build_php:
stage: build_php
only:
refs:
- branches
# RUN THIS JOB ONLY WHEN ANY OF THESE FILES CHANGES
changes:
- app/**/*
- public/**/*
- resources/**/*
- routes/**/*
- database/**/*
- config/**/*
- tests/**/*
- Dockerfile
- .docker/**/*
- docker-stack.*
- .gitlab-ci.yml
script:
# BUILD THE NEW IMAGE...
- >
docker image build
--build-arg BUILDKIT_INLINE_CACHE=1
--build-arg ASSETS_CONTAINER_IMAGE=${NGINX_IMAGE_TAG}
--cache-from ${CI_REGISTRY_IMAGE}:latest
--tag ${PHP_IMAGE_TAG}
--tag ${CI_REGISTRY_IMAGE}:latest
--label es.futurofficevalencia.ci.project.url=${CI_PROJECT_URL}
--label es.futurofficevalencia.ci.pipeline.id=${CI_PIPELINE_ID}
--label es.futurofficevalencia.ci.pipeline.url=${CI_PIPELINE_URL}
--label es.futurofficevalencia.ci.job.id=${CI_JOB_ID}
--label es.futurofficevalencia.ci.job.url=${CI_JOB_URL}
.
# PUSH THE NEW IMAGE WITH A TAG TO THE CONTAINER REGISTRY...
- docker image push ${PHP_IMAGE_TAG}
- docker image push ${CI_REGISTRY_IMAGE}:latest
after_script:
- docker logout ${CI_REGISTRY}
unit_tests:
stage: test
cache: {}
dependencies: []
variables:
GIT_STRATEGY: none
script:
# RUNNING UNIT TESTS SUITE WITH PHPUNIT USING THE BUILT IMAGE
- >
docker container run --name php ${PHP_IMAGE_TAG}
vendor/bin/phpunit --verbose --testsuite Unit --log-junit phpunit-report-unit.xml
# CREATING TEST REPORT FILE
- docker cp php:/var/www/html/phpunit-report-unit.xml ./
artifacts:
expire_in: 1 day
reports:
junit: phpunit-report-unit.xml
feature_tests:
stage: test
cache: {}
dependencies: []
variables:
GIT_STRATEGY: none
script:
# RUNNING FEATURE TESTS SUITE WITH PHPUNIT USING THE BUILT IMAGE
- >
docker container run --name php --env APP_KEY ${PHP_IMAGE_TAG}
vendor/bin/phpunit --verbose --testsuite Feature --log-junit phpunit-report-feature.xml
# CREATING TEST REPORT FILE
- docker cp php:/var/www/html/phpunit-report-feature.xml ./
artifacts:
expire_in: 1 day
reports:
junit: phpunit-report-feature.xml
codestyle:
stage: test
cache: {}
dependencies: []
variables:
GIT_STRATEGY: none
allow_failure: true
script:
- >
docker container run --name php ${PHP_IMAGE_TAG}
vendor/bin/php-cs-fixer fix --dry-run --config=.php_cs --using-cache=no --allow-risky=yes --verbose --diff
deploy_review:
stage: review
cache: {}
dependencies: []
environment:
name: review/$CI_COMMIT_REF_NAME # => review-branch-name-commit-id
url: https://$CI_ENVIRONMENT_SLUG.futurofficevalencia.naobatec.com
on_stop: stop_review
variables:
DOCKER_HOST: tcp://${SSH_HOST}:2376
DOCKER_TLS_VERIFY: 1
DOCKER_TLS_CERTDIR: ""
STACK_NAME: ${CI_PROJECT_NAME}-${CI_ENVIRONMENT_SLUG}
only:
- branches
except:
- master
script:
- >
docker stack deploy
--prune
--with-registry-auth
--compose-file docker-stack.review.yml
${STACK_NAME}
after_script:
- docker logout ${CI_REGISTRY}
stop_review:
stage: review
cache: {}
dependencies: []
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
variables:
GIT_STRATEGY: none
DOCKER_HOST: tcp://${SSH_HOST}:2376
DOCKER_TLS_VERIFY: 1
STACK_NAME: ${CI_PROJECT_NAME}-${CI_ENVIRONMENT_SLUG}
when: manual
only:
- branches
except:
- master
script:
- docker stack rm ${STACK_NAME}
deploy_staging:
stage: deploy
cache: {}
dependencies: []
environment:
name: staging
url: https://${CI_ENVIRONMENT_SLUG}.futurofficevalencia.naobatec.com
variables:
DOCKER_HOST: tcp://${SSH_HOST}:2376
DOCKER_TLS_VERIFY: 1
DOCKER_TLS_CERTDIR: ""
STACK_NAME: ${CI_PROJECT_NAME}-${CI_ENVIRONMENT_SLUG}
only:
- master
script:
- >
docker stack deploy
--prune
--with-registry-auth
--compose-file docker-stack.staging.yml
${STACK_NAME}
after_script:
- docker logout ${CI_REGISTRY}
deploy_production:
stage: deploy
cache: {}
environment:
name: production
url: https://${DOMAIN}
variables:
GIT_STRATEGY: none
APP_NAME: ${DOMAIN}
only:
- tags
before_script:
- which ssh-agent || apk update --quiet && apk add --quiet --no-cache tar openssh-client
# START THE SSH AGENT
- eval $(ssh-agent -s)
# ADD THE SSH PRIVATE KEY TO THE SSH AGENT STORE
- echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add -
# CREATE SSH DIRECTORY
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
# ADD SSH HOST TO KNOWN HOSTS
- ssh-keyscan ${SSH_HOST} >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
script:
- export RELEASE_PATH=${WEBROOT}/public_html
- scp -p22 -r artifact.tgz ${SSH_USER}@${SSH_HOST}:${RELEASE_PATH}
- ssh -p22 ${SSH_USER}@${SSH_HOST} "tar -xvzf ${RELEASE_PATH}/artifact.tgz -C ${RELEASE_PATH} --strip-components=1"
- ssh -p22 ${SSH_USER}@${SSH_HOST} "rm ${RELEASE_PATH}/artifact.tgz"
# Frontend dependencies
FROM node:12-alpine as frontend
ARG ENV_BUILD=development
WORKDIR /usr/src/app
# Copy dependency list and lock file
COPY package.json yarn.lock ./
# Install dependencies
RUN yarn install
# Copy source assets and build configuration
COPY artisan webpack.mix.js tailwind.config.js ./
COPY public/ public/
COPY resources/ resources/
# Build assets
RUN yarn run ${ENV_BUILD}
FROM nginx:1.19-alpine
LABEL maintainer="Naobatec <contacto@naobatec.com>"
WORKDIR /var/www/html/public
# Copy built assets from frontend stage
COPY --from=frontend /usr/src/app/public/ ./
# Copy nginx configuration
COPY .docker/nginx/nginx.conf /etc/nginx/nginx.conf
COPY .docker/nginx/conf.d/*.conf /etc/nginx/conf.d/
COPY .docker/nginx/snippets/*.conf /etc/nginx/snippets/
EXPOSE 80
HEALTHCHECK \
--interval=60s \
--timeout=20s \
--retries=3 \
--start-period=20s \
CMD curl -fs http://localhost || exit 1
# Frontend assets
ARG ASSETS_CONTAINER_IMAGE="registry.gitlab.com/media-global-group/futuroffice-valencia-website/nginx"
FROM $ASSETS_CONTAINER_IMAGE as frontend
# PHP dependencies
FROM composer:latest as vendor
WORKDIR /usr/src/app
COPY composer.* ./
COPY database/ database/
RUN composer install \
--no-interaction \
--no-plugins \
--no-scripts \
--prefer-dist \
--no-suggest \
--no-progress
# Application
FROM php:7.4-fpm-alpine as php
LABEL maintainer="Naobatec <contacto@naobatec.com>"
WORKDIR /var/www/html
# PHP configuration
RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
COPY . .
COPY --from=vendor /usr/src/app/vendor/ vendor/
COPY --from=frontend /var/www/html/public/mix-manifest.json public/
RUN chown -R www-data:www-data \
/var/www/html/storage \
/var/www/html/bootstrap/cache
RUN php artisan route:cache \
&& php artisan view:cache
EXPOSE 9000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment