gitlabCIでhttp通信による自動デプロイをしようとしたらハマった話

##まずはじめに
デプロイ先用のアカウントをつくってSSH接続するのがめんどくさかったので手っ取り早くHTTP通信で自動デプロイしようとしたら
謎の挙動をされハマったのでメモ。
ちなみにここではgitlab-ci.ymlのこまかい書き方とかは触れません。違う記事を参照してください。
そして、もっと正統派なやり方があるはずなので、あまり参考にはならないかもしれません。。。

##環境
AWS　EC2
　1つ目・・・WEBサーバ(centos)
　2つ目・・・gitサーバ(gitlab)
　これらは同一セキュリティグループ(同一ネットワーク)内に存在している

##今回の自動デプロイの全体図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/251992/2d4b4283-bad1-f50a-692d-640e0d973f70.png)
今回はgitlab-ci初めてですし、
ただただWEBサーバが常にdevelopブランチの最新状態になってほしいのでコードのテストとかはこの手順の中でやってません。
（しかしこの方法だと使われていない古いファイルなどが残ってしまうので、rsyncでやったほうが良いと思いました）

##単純なgitlab-ci.ymlを用意したがなぜかcloneできない

ymlにcloneを書いたときに認証とおすのどうしたら良いのかわからず無駄にシェルにしてみる

```.gitlab-ci.yml
build:
  stage: deploy
  script:
    - bash .gitlab-deploy.sh 
  environment:
    name: staging
    url: http://{パブリックIP}/staging
  when: on_success
  only:
    - develop
```


最初のエラーは、同一ネットワークに存在するのにgitlabの画面で表示されているままにcloneURLのIP部分をパブリックIPにしていたからでした。
しかし、プライベートIPに修正するも延々とfaildするJobたち。。。

```
Running with gitlab-runner 11.7.0 (8bb608ff)
  on test mrx2efNr
Using Shell executor...
Running on ip-10-2-1-10.ap-northeast-1.compute.internal...
Cloning repository...
Cloning into '/home/gitlab-runner/builds/mrx2efNr/0/hoge-dev/hoge-project'...
fatal: repository 'http://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@10.2.1.20/hoge-dev01/hoge-project.git/hoge-dev01/hoge-project.git/' not found
bash: 66 行: cd: /home/gitlab-runner/builds/mrx2efNr/0/hoge-dev01/hoge-project: そのようなファイルやディレクトリはありません
ERROR: Job failed: exit status 1
```

`gitlab-ci-token`なんてymlに書いた覚えはないが、なんかそれをつかって勝手に知らない場所にcloneしている模様。
cloneできないなら、clone用ディレクトリを最初にgit initしとけばとりあえずpullできるかなーと思い修正。

```.gitlab-ci.yml
stages:
  - deploy

deploy_develop:
  stage: deploy
  script:
    - cd /var/www/hoge-project
    - git pull origin develop
  only:
    - develop
```

しかし、ymlにpullしか書かないで実行してもなぜか勝手にcloneして失敗、
そしてその後の処理ができないという具合になっている。

最後のディレクトリがないというエラーだが、`/home/gitlab-runner/builds/mrx2efNr/0/`このパスは存在するし
リポジトリは確実に存在しているので、cloneできてないということっぽい。

そこで勝手にcloneしている処理で使われている`gitlab-ci-token`について調べてみることにしました。

##gitlab-ci-tokenについて

ぐぐってみると、こいつはgitlab8.12からの機能らしいが、結構な人数の人がcloneできない！と嘆いていることが判明。
https://gitlab.com/gitlab-org/gitlab-ce/issues/22723

結局解決方法とかのってないのかよ～～とおもっていたら発見！
https://gitlab.com/gitlab-org/gitlab-runner/issues/1884#note_18695580
・gitlabCI側で勝手に`git clone`してしまうのをまず無効にする(`GIT_STRATEGY: none`と書くと無効にできる)
・cloneとかしたいならbefore_scriptで自分で書く
とのことでした。GIT_STRATEGYとはなんぞ？？とということでこちらを発見。
https://docs.gitlab.com/ee/ci/yaml/#git-strategy
「If left unspecified, the default from project settings will be used.」ということで、デフォルトはきっとcloneすることになっていたんでしょう。

ということで、ymlに`GIT_STRATEGY: none`を追加。

しかし、pullをするにはアカウント情報とかが必要・・・。
入力を求められたタイミングでパスワードを入力する等の処理が複雑で対応できなかったのと
アカウント作ってSSH Keyを作成したり登録したりするのも面倒だったので、HTTP通信でデプロイできる方法を探すことにしました。
なんか便利なものないのかなーとgitlabの設定周りを見ていたら、便利そうなものを見つけました。
その名も`deploy-token`です！

## deploy-tokenについて
Setting > Repository に存在する機能です。
「Deploy tokens allow read-only access to your repository and registry images.」
なるほど、このトークンを発行するとリポジトリへの読み取り専用アクセスができるらしい。
作成すると、デプロイトークンのユーザ名とパスワードが発行されました。（Expires atは設定しなくても作成できます。）
パスワードに関してはもう見られなくなるそうなので、この時点でしっかりキャプチャ撮ったりコピって保存したりしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251992/46ed449b-0892-fbc2-8893-32cfd1ff84d9.png)

実際に使うときは、こんな感じで使います。
`git clone -b develop http://{gitlab+deploy-token-N}:{発行されたパスワード}@{IP}/{リポジトリのグループ}/{プロジェクト名}.git {クローンしたいディレクトリ(書かない場合はカレントディレクトリになる)}`

## 結論: deploy-tokenを使ってクローンできました！

色々面倒くさがってしまいましたが、なんやかんやでこんな感じでできました！

```.gitlab-ci.yml
variables:
  GIT_STRATEGY: none

before_script:
  ## clean the working directory
  - CLONE_DIR="/var/www/clone_dir/"
  - sudo rm -rf $CLONE_DIR
  - sudo mkdir -p $CLONE_DIR

  ## clone the project each time (inefficient, consider performing fetch instead if it already exists)
  - git clone -b develop http://{user}:{pass}@{IP}/hoge-dev/hoge-prjct.git $CLONE_DIR
  - cd $CLONE_DIR
  - ls -l

stages:
  - deploy

deploy_develop:
  stage: deploy
  script:
    - cd /var/www/
    - sudo cp -rf $CLONE_DIR* /var/www/hoge-prjct/
    - cd /var/www/hoge-prjct/
    - chmod -R 777 .
    - composer dump-autoload
    - composer install
    - php artisan migrate:refresh --seed
    - ls -l
  only:
    - develop
```

deploy-tokenは参照用のみでリポジトリにアクセスできるものなので
CI以外の場面でも使ったりできます、割と便利！
という話でした。