
У меня есть несколько своих проектов, которые соответственно приходится самому поддерживать разворачивать и тп, к примеру данный блог и другие простые проекты. Когда я использовал symfony и php, развернуть можно просто с помощью capifony, даже не зная Ruby. В связи с тем что я решил перейти на golang то данные инструменты не совсем подходят. Почему не использовать к примеру в проектах тот же php, чаще быстрее разрабатывать на том что используешь в работе. Для начала решил попробовать обычный способ с помощью docker swarm и gitlab ci, есть конечно решения с heroku, но я пока решил использовать vps например vscale. K8s для маленьких проектов возможно будет излишним.
Мы будем использовать Centos, Swarm вместе с gitlab-ci. В данной статье будет только базовое разворачивание, возможно в дальнейшем мы развернем stateless сервисы и также добавим миграцию для базы.
Выбираем любой сервис vps и устанавливаем на него centos 8 64bit.
Установка и настройка Swarm
Есть некоторые особенности установки docker на centos8, вы можете использовать любую другую систему, или некоторые севисы сразу предоставляют систему с установленным docker.
# dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo # dnf --disablerepo=AppStream install -y container-selinux docker-ce # systemctl start docker # systemctl enable docker # firewall-cmd --zone=public --add-masquerade --permanent # firewall-cmd --reload
Инициализация swarm - командой docker swarm init
.
Настройка проекта
В качестве примера я буду использовать проект gitlab.com/4devs/gqlgen-todos
$ mkdir ~/go/src/gitlab.com/4devs/gqlgen-todos $ cd ~/go/src/gitlab.com/4devs/gqlgen-todos $ go mod init gitlab.com/4devs/gqlgen-todos
Добавляем базовую схему
$ echo 'type Todo { id: ID! text: String! done: Boolean! user: User! } type User { id: ID! name: String! } type Query { todos: [Todo!]! } input NewTodo { text: String! userId: String! } type Mutation { createTodo(input: NewTodo!): Todo! }' >> schema.graphql
Генерация всего сервера командой go run github.com/99designs/gqlgen init
, запустить можно командой go run ./server/server.go
.
В файле resolver.go
мы заменим panic("not implemented")
на строке 25 на return nil,nil
, чтобы не получать паники.
Настройка Gitlab CI
Добавим файл для создания образа из нашего проекта mkdir build && vim build/Dockerfile
таким содержимым
FROM scratch COPY bin/server . CMD ["/server"]
У нас будет три этапа в проекте:
- build, соберем проект
- image, создадим docker образ с бинарником проекта
- deploy, обновление образа на сервере
На рабочем проект конечно должно быть больше этапов как минимум lint и test.
Получается .gitlab-ci.yml
с таким содержимым
stages: - build - image - deploy services: - docker:dind build: stage: build image: golang:1.13 before_script: - pwd - ls -la script: CGO_ENABLED=0 GOOS=linux go build -o bin/server server/server.go artifacts: paths: - bin/ expire_in: 1 day create image: stage: image image: docker:latest before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY dependencies: - build script: - pwd - ls -la - docker build -t ${CI_REGISTRY_IMAGE}:${CI_PIPELINE_ID} -f ./build/Dockerfile . - docker push ${CI_REGISTRY_IMAGE}:${CI_PIPELINE_ID} - docker tag ${CI_REGISTRY_IMAGE}:${CI_PIPELINE_ID} ${CI_REGISTRY_IMAGE}:latest - docker push ${CI_REGISTRY_IMAGE}:latest deploy stage: stage: deploy when: manual tags: - stage before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - pwd - ls -la - docker system prune -f - docker pull ${CI_REGISTRY_IMAGE}:latest - docker service update --image ${CI_REGISTRY_IMAGE}:latest --force api
Настройка разворачивания проекта на сервере
Добавляем gitlab-runner как контейнер
# dnf install -y git # curl -LJO https://gitlab-runner-downloads.s3.amazonaws.com/latest/rpm/gitlab-runner_i686.rpm # rpm -i gitlab-runner_i686.rpm
Запуск runner
# docker run -d \ --name gitlab-runner \ --restart always \ -v gitlab-runner:/etc/gitlab-runner \ -v /var/run/docker.sock:/var/run/docker.sock \ gitlab/gitlab-runner:latest
Настройка runners, токен нужно скопировать из CI / CD Settings->Runners
# docker exec -it gitlab-runner gitlab-runner register -n \ --url https://gitlab.com/ \ --registration-token <токен> \ --executor docker \ --description "docker-build-runner" \ --docker-image "docker:latest" \ --docker-privileged \ --docker-volumes /var/run/docker.sock:/var/run/docker.sock \ --docker-pull-policy "always" \ --tag-list stage
После этого runner должен появится в списке доступных.
Создание проекта на сервере
Так как наши команды CI обновляют сервис, нам необходимо первый раз его создать, можно сделать командой docker service create --name api --publish published=80,target=8080 registry.gitlab.com/4devs/gqlgen-todos
, проверить можно по ip сервера.
В вкладке Pipelines нам доступен ручной деплой сервиса.
Выводы
Показан один из простых вариантов разворачивания сервиса на vps. В дальнейшем планируется разворачивания базы данных и добавления дополнительных этапов в CI, таких как тестирование и линтер. Так же данная структура проекта была взята без изменений, в рабочем проекте обычно применяется другая. Скачать проект можно по ссылке Init Swarm
Дополнительно по теме можете прочитать несколько статей: