У меня есть несколько своих проектов, которые соответственно приходится самому поддерживать разворачивать и тп, к примеру данный блог и другие простые проекты. Когда я использовал 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
Дополнительно по теме можете прочитать несколько статей: