Last active
March 8, 2025 18:13
-
-
Save uxweb/10096f17d2e032f5b0b1ed11f1f77990 to your computer and use it in GitHub Desktop.
Laravel application build and deployment with GitLab CI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 <[email protected]>" | |
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 <[email protected]>" | |
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