I have the following setup in GitLab CI. I have a script which I use to build my application using php, composer and npm commands.
I want to replace the script with a single Dockerfile
.
Here is the script:
#!/bin/bash
if [ "$APP" = "webapp" ]; then
docker exec -t cozact_app composer install && \
docker exec -t cozact_app php artisan down && \
docker exec -t cozact_app php artisan migrate --force && \
docker exec -t cozact_app php artisan storage:link && \
docker exec -t cozact_app php artisan droit:run && \
docker exec -t cozact_app npm install;
fi
if [ "$APP" = "webapp" ] && [ "$ENV" = "test" ]; then
docker exec -t cozact_app npm run dev && \
docker exec -t cozact_app php artisan up;
fi
if [ "$APP" = "webapp" ] && [ "$ENV" = "preprod" ]; then
docker exec -t cozact_app npm run production && \
docker exec -t cozact_app php artisan up;
fi
if [ "$APP" = "webapp" ] && [ "$ENV" = "prod" ]; then
docker exec -t cozact_app npm run production && \
docker exec -t cozact_app php artisan up;
fi
#!/bin/sh
composer install && \
php artisan down && \
php artisan migrate --force && \
php artisan storage:link && \
php artisan droit:run && \
npm install
if [ "$var" = "test" ] ; then
npm run dev && \
php artisan up;
else
npm run production && \
php artisan up;
fi
CodePudding user response:
You can use the following Multi-stage Dockerfile
, and adapt it to your usecase.
ARG APP_ENVIRONMENT=dev
FROM composer:latest as vendor
COPY database/ database/
COPY composer.json composer.json
COPY composer.lock composer.lock
RUN composer install && \
php artisan down && \
php artisan migrate --force && \
php artisan storage:link && \
php artisan droit:run && \
FROM node:latest as frontend
RUN mkdir -p /app/public
COPY package.json webpack.mix.js package.lock /app/
COPY resources/assets/ /app/resources/assets/
WORKDIR /app
RUN npm install && \
npm run $APP_ENVIRONMENT
FROM php:7.2-apache-stretch
COPY . /var/www/html
COPY --from=vendor /app/vendor/ /var/www/html/vendor/
COPY --from=frontend /app/public/js/ /var/www/html/public/js/
COPY --from=frontend /app/public/css/ /var/www/html/public/css/
COPY --from=frontend /app/mix-manifest.json /var/www/html/mix-manifest.json
This Dockerfile is composed of 3 stages:
- vendor: it gets the composer packages and run php artisan commands (I am not a laravel expert. So make sure to only keep the
php artisan
commands that should run during the build and not during the run.php artisan
commands that needs to run during the run should go in aCMD
orENTRYPOINT
in the last stage) - frontend: It gets JavaScript files, download the packages and build the static files
- The last stage in the run stage, it copies the code inside the image and gets the frontend and vendor files from the earlier stages.
the Dockerfile accepts a build argument
APP_ENVIRONMENT
that you can pass in CLI to control which env you are building to.
And then ingitlab-ci.yml
you can just run a
docker build --build-arg APP_ENVIRONMENT=production .
In you gitlab-ci.yml
you'll have something like the following:
job:
variables:
DEPLOY_VARIABLE: "default-deploy"
rules:
- if: $CI_COMMIT_REF_NAME == "dev"
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
variables: # Override DEPLOY_VARIABLE defined
API_ENVIRONMENT: "production" # at the job level.
script:
- docker build -t --build-arg API_ENVIRONMENT=${API_ENVIRONMENT} "some-tag" .
CodePudding user response: