インフラエンジニアがGitLabを建ててCI/CDを動かせるようにするまで

# 経緯
インフラエンジニアとして入社し、AWS案件に携わってからCloudFormationやLambda用のPythonを書くことが増えました。
Git/GitHub/GitLabの名前は聞いたことがあるレベルでしたが、前述のバージョン管理が必須になり、自社のGitLabを活用することになります。
素人でしたが直ぐに利便性を感じ、自宅にあるESXiにDockerの勉強がてらGitLabを立てればよいのではと考えたのがスタートとなります。
プライベートで自宅のデスクトップPCと外出先で使うノートPCのファイルを扱うのに重宝しています。

自宅のESXiに建てている為、それが壊れてしまうと0から構築方法を調べ事になるのを回避したいのでここに忘備録として記載していきます。

# Docker
GitLabをDocker-composeで建てたい為、Dockerをインストールします。
※余談ですがk8sをインストールする際にsnapのDockerに苦労したので、下記の方法でDockerをインストールしています。k8sを触らない方はsnapでも問題ないかと思います。


## 環境

|項目|値|
|---|---|
|OS|Ubuntu 19.04|

※2019/12月時点でk8sがdockerのver.19に対応していない為、バージョン指定でインストールしています。

```bash
sudo addgroup --system docker
sudo usermod -aG docker user01
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
sudo apt-get update
apt-cache madison docker-ce
sudo apt-get install docker-ce=5:18.09.9~3-0~ubuntu-bionic docker-ce-cli=5:18.09.9~3-0~ubuntu-bionic containerd.io
sudo systemctl start docker
sudo systemctl enable docker
```


# GitLab
[Git Lab](https://about.gitlab.com/)はバージョン管理ツールですが、他にも便利な機能が備わっています。
詳しくは公式サイトをご覧ください。

- Git以外の機能
   - CI/CD
   - Issues
   - Wiki
   - etc

## GItLab DockerCompose
以下のファイルをダウンロードし、別のPCからもアクセスしたい場合は
GITLAB_HOST=をローカルのIPアドレスへ変更してください。

https://github.com/sameersbn/docker-gitlab/blob/master/docker-compose.yml


```yaml
version: '2'

services:
  redis:
    restart: always
    image: sameersbn/redis:4.0.9-2
    command:
    - --loglevel warning
    volumes:
    - redis-data:/var/lib/redis:Z

  postgresql:
    restart: always
    image: sameersbn/postgresql:10-2
    volumes:
    - postgresql-data:/var/lib/postgresql:Z
    environment:
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production
    - DB_EXTENSION=pg_trgm

  gitlab:
    restart: always
    image: sameersbn/gitlab:12.5.2
    depends_on:
    - redis
    - postgresql
    ports:
    - "10080:80"
    - "10022:22"
    volumes:
    - gitlab-data:/home/git/data:Z
    environment:
    - DEBUG=false

    - DB_ADAPTER=postgresql
    - DB_HOST=postgresql
    - DB_PORT=5432
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production

    - REDIS_HOST=redis
    - REDIS_PORT=6379

    - TZ=Asia/Kolkata
    - GITLAB_TIMEZONE=Kolkata

    - GITLAB_HTTPS=false
    - SSL_SELF_SIGNED=false

    - GITLAB_HOST=localhost
    - GITLAB_PORT=10080
    - GITLAB_SSH_PORT=10022
    - GITLAB_RELATIVE_URL_ROOT=
    - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string
    - GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string
    - GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string

    - GITLAB_ROOT_PASSWORD=
    - GITLAB_ROOT_EMAIL=

    - GITLAB_NOTIFY_ON_BROKEN_BUILDS=true
    - GITLAB_NOTIFY_PUSHER=false

    - GITLAB_EMAIL=notifications@example.com
    - GITLAB_EMAIL_REPLY_TO=noreply@example.com
    - GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com

    - GITLAB_BACKUP_SCHEDULE=daily
    - GITLAB_BACKUP_TIME=01:00

    - SMTP_ENABLED=false
    - SMTP_DOMAIN=www.example.com
    - SMTP_HOST=smtp.gmail.com
    - SMTP_PORT=587
    - SMTP_USER=mailer@example.com
    - SMTP_PASS=password
    - SMTP_STARTTLS=true
    - SMTP_AUTHENTICATION=login

    - IMAP_ENABLED=false
    - IMAP_HOST=imap.gmail.com
    - IMAP_PORT=993
    - IMAP_USER=mailer@example.com
    - IMAP_PASS=password
    - IMAP_SSL=true
    - IMAP_STARTTLS=false

    - OAUTH_ENABLED=false
    - OAUTH_AUTO_SIGN_IN_WITH_PROVIDER=
    - OAUTH_ALLOW_SSO=
    - OAUTH_BLOCK_AUTO_CREATED_USERS=true
    - OAUTH_AUTO_LINK_LDAP_USER=false
    - OAUTH_AUTO_LINK_SAML_USER=false
    - OAUTH_EXTERNAL_PROVIDERS=

    - OAUTH_CAS3_LABEL=cas3
    - OAUTH_CAS3_SERVER=
    - OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false
    - OAUTH_CAS3_LOGIN_URL=/cas/login
    - OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate
    - OAUTH_CAS3_LOGOUT_URL=/cas/logout

    - OAUTH_GOOGLE_API_KEY=
    - OAUTH_GOOGLE_APP_SECRET=
    - OAUTH_GOOGLE_RESTRICT_DOMAIN=

    - OAUTH_FACEBOOK_API_KEY=
    - OAUTH_FACEBOOK_APP_SECRET=

    - OAUTH_TWITTER_API_KEY=
    - OAUTH_TWITTER_APP_SECRET=

    - OAUTH_GITHUB_API_KEY=
    - OAUTH_GITHUB_APP_SECRET=
    - OAUTH_GITHUB_URL=
    - OAUTH_GITHUB_VERIFY_SSL=

    - OAUTH_GITLAB_API_KEY=
    - OAUTH_GITLAB_APP_SECRET=

    - OAUTH_BITBUCKET_API_KEY=
    - OAUTH_BITBUCKET_APP_SECRET=

    - OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL=
    - OAUTH_SAML_IDP_CERT_FINGERPRINT=
    - OAUTH_SAML_IDP_SSO_TARGET_URL=
    - OAUTH_SAML_ISSUER=
    - OAUTH_SAML_LABEL="Our SAML Provider"
    - OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient
    - OAUTH_SAML_GROUPS_ATTRIBUTE=
    - OAUTH_SAML_EXTERNAL_GROUPS=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_USERNAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME=

    - OAUTH_CROWD_SERVER_URL=
    - OAUTH_CROWD_APP_NAME=
    - OAUTH_CROWD_APP_PASSWORD=

    - OAUTH_AUTH0_CLIENT_ID=
    - OAUTH_AUTH0_CLIENT_SECRET=
    - OAUTH_AUTH0_DOMAIN=
    - OAUTH_AUTH0_SCOPE=

    - OAUTH_AZURE_API_KEY=
    - OAUTH_AZURE_API_SECRET=
    - OAUTH_AZURE_TENANT_ID=

volumes:
  redis-data:
  postgresql-data:
```
## dockerの起動

```
docker-compose up -d
```
するだけです。
port10080が空いていればアクセスができます。

# CI/CD
CI/CDを動かすためにはRunnsersの設定が必要です。
RunnsersはRunnerもしくはk8sが必要になります。
今回はRunnserで構築しました。

1. GitLabでProjectを作成
2. Projectのページに遷移し、左側のSettings 
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316662/638b9390-ea04-250f-009e-0102a929162a.png)
1. CI/CD -> Runners -> Expand
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316662/fc05e293-1973-105d-7fb0-0045445b0e8b.png)
1. 「Set up a specific Runner manually」に従いセットアップしていきます。
    2. インストール
    [公式ページ](https://docs.gitlab.com/runner/install/)
    
        ```bash
        sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
        sudo chmod +x /usr/local/bin/gitlab-runner
        sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
        sudo /usr/local/bin/gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
        sudo systemctl enable gitlab-runner
        sudo systemctl start gitlab-runner
        ```
　
    1. GitLabとの紐づけ
       [公式ページ](https://docs.gitlab.com/runner/register/)      

       ```bash
       sudo /usr/local/bin/gitlab-runner register
       Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
       # GitLab内のCI/CD SettingsページにあるURLを貼り付け
       Please enter the gitlab-ci token for this runner
       # GitLab内のCI/CD Settingsページにあるトークンを貼り付け
       Please enter the gitlab-ci description for this runner
       # GitLab内の表示名
       Please enter the gitlab-ci tags for this runner (comma separated):
       # GitLab内のタグ名
       Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
       docker #今回はdockerを使用するため、dockerと入力します。
       Please enter the Docker image (eg. ruby:2.1):
       Python:3.7 #今回はpythonを扱う為、python3.7のdocker imageを入力します。
       ```
       CI/CD Settingsページ内のRunners activated for this projectにRunnserが追加されれば成功です。出てこない場合は上記のGitLabとの紐づけを再度実施してみてください。

1. 作成したProjectにCI/CDを設定
    2. Projectの直下にgitlab-ci.yml を作成
    
   ```yaml
   image: python:3-alpine # docker image
 
   before_script: # 一番最初に実行するコマンド
     - pip install pytest pytest-cov autopep8 radon

   stages: # いくつか実行したいJobの順番を指定できる
     - build
     - test


   job1: # job名(任意)
     stage: build # stage上のbuildとして設定
     script: # listでコマンド記載
       - autopep8 -i testCode.py
       - radon mi -s testCode.py
       - radon cc -s testCode.py
   
   job2:
     stage: test
     script:
       - pytest -v --cov=.
   ```

上記はjob1が成功したらjob2を実行するようstagesに記載をしています。
gitlab-ci.ymlに関しては以下の記事をご参照ください。

- [GitLab CI/CDパイプライン設定リファレンス](https://qiita.com/ynott/items/1ff698868ef85e50f5a1)

もう一つ大事なCDはありませんが、AWS Lambdaの記事を参照頂ければと思います。

- [lambroll & GitLab CI/CD Pipelineを使ってみた](https://qiita.com/tnagano1981/items/61c22a5b4abeb5b7582c)

# まとめ
忘備録として記載した結果、公式のコピペになってしまいました。
GitLabのCI/CDはあまりハマらず設定をすることができました。
これから開発のスピードをポジティブな意味で早くできればと考えています。(インフラエンジニアとは・・・)
公式や先駆者様の見様見真似で動かしている為、おかしな点がありましたらご教示いただけますと幸いです。

# 参考リンク
- [sameersbn/gitlab](https://github.com/sameersbn/docker-gitlab)
- [GitLab Runner Docs](https://docs.gitlab.com/runner/)
- [GitLab RunnerでCI/CDしてみる(前編)](https://dev.classmethod.jp/ci/gitlab-runner-ci-cd-1/)