4. Gitlab Docker container registry. CI скрипт для роботи docker images
Відео версія
(YouTube - для зворотнього зв'язку)
Продовження попереднього гайда.
Контейнер з PHP завжди модифікується, ми ставимо розширення
для фреймворку, залежностей і так далі. Тому Dockerfile
з php сервісом існує завжди.
Збирати ж php
контейнер кожен раз як на сервері,
так і на машинах розробників не найкраща ідея.
По-перше, і це головне, деплой та прогін тестів на сервері може проходити безліч разів на день, кожен раз збирати контейнер завантажувати та встановлювати одні й ті ж залежності не раціонально й довго.
По-друге, консистентність - на продакшені, стейжі, тестах завжди буде однакове середовище розробки, без поправок на версії будь-яких залежностей
Для Gitlab створюю новий проєкт в підгрупі infrastructure
з назвою swoole
stages:
- build
default:
image: docker:26.1.3-alpine3.19
services:
- docker:26.1.3-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
variables:
IMAGE_NAME: 'swoole/core'
IMAGE_NAME_DEV: $CI_REGISTRY_IMAGE/dev:${CI_COMMIT_TAG}
IMAGE_NAME_PROD: $CI_REGISTRY_IMAGE/prod:${CI_COMMIT_TAG}
build-image:
stage: build
script:
- docker build -t $IMAGE_NAME -f Dockerfile .
- docker build -t $IMAGE_NAME_DEV -f dev.Dockerfile . --build-arg SOURCE=$IMAGE_NAME
- docker build -t $IMAGE_NAME_PROD -f prod.Dockerfile . --build-arg SOURCE=$IMAGE_NAME
- docker push $IMAGE_NAME_DEV
- docker push $IMAGE_NAME_PROD
rules:
- if: '$CI_COMMIT_TAG =~ /^v(\d+\.)?(\d+\.)?(\*|\d+)$/'
Тут треба звернути увагу на
$CI_COMMIT_TAG
- назва тегу. Будь-який реліз робимо тегами.docker login
- команда для авторизації в реєстрі Docker.$CI_REGISTRY_USER
,$CI_REGISTRY_PASSWORD
,$CI_REGISTRY
- gitlab змінні.docker build -t $IMAGE_NAME -f Dockerfile .
- збираємо базовий імейдж. На його основі збираємо прод, дев та будь-яку іншу версію.docker push
- пушимо зображення в реєстрif: '$CI_COMMIT_TAG =~ /^v(\d+\.)?(\d+\.)?(\*|\d+)$/'
- умова по якій запускається крок розробки. У цьому випадку запуститься лише для тегів з назвою з літероюv
та звичайна семантична версійність.
ARG SOURCE
FROM ${SOURCE}
RUN apk add --no-cache nodejs npm git
ARG SOURCE FROM ${SOURCE}
- змінна, яку передаємо командою --build-arg SOURCE=
у нашому випадку - swoole/core зображення.
Логіка роботи з проєктом:
- Всі глобальні зміни додаємо в
Dockerfile
. Зазвичай туди йдутьphp.ini
файли, всіphp extension
. - До файлу
dev.Dockerfile
станом на зараз додаєтьсяnode
,npm
таgit
. За необхідності туди ж встановлюють xdebug, XhProf і тд. Важливо не вмикайте їх для проду. Вони дуже й дуже навантажують сервер. Я б і для dev не вмикав, краще винести їх в окремий контейнер. - To
prod.Dockerfile
go all production settings,opcache
, turn off display of errors, etc.
І звісно ж все це описуємо в README.md
### Local work
0) Build core image
```sh
docker build -t local/swoole-core .
```
1) Build dev image
```sh
docker build -t local/swoole-dev -f dev.Dockerfile . --build-arg SOURCE='local/swoole-core'
```
2) Build prod image
```sh
docker build -t local/swoole-prod -f prod.Dockerfile . --build-arg SOURCE='local/swoole-core'
```
3) Use `local/swoole-prod` or `local/swoole-dev` in your projects
### Deploy
0) Commit your changes
1) Merge to main
2) Switch to main branch
3) Make tag with {version} (using semantic rules https://semver.org/)
should increment [last tags](https://gitlab.com/bandheart.com/back/infrastructure/swoole/container_registry) and match the expression
```regexp
/^v(\d+\.)?(\d+\.)?(\*|\d+)$/
```
3) Push your tag
```
git push origin {version}
```
It will create 2 tagged versions:
- `registry.gitlab.com/bandheart.com/back/infrastructure/swoole/dev:{version}` - for development
- `registry.gitlab.com/bandheart.com/back/infrastructure/swoole/prod:{version}` - for production
Також не забуваємо про .dockerignore
**.git
.idea
README.md
.gitlab-ci.yml
dev.Dockerfile
Dockerfile
prod.Dockerfile
Also, don't forget about .dockerignore