Github Actionsと悪戦苦闘(未解決)

Github Actionsに苦戦中。

まだ解決はしていませんが、途中経過を残しておきます。

その過程でDockerさんと知り合ったので、特徴についても書きました。

Github Actionって何?

Githubが用意している便利なワークフロー。

ブランチにプッシュした時に自動でさまざまなコードが走るように設定できるので、脳死でデプロイなんかもできちゃう。

  • リポジトリには、さまざまなイベントに基づいてさまざまなジョブをトリガーする複数のワークフローを含めることができます。
  • ワークフローを使用してソフトウェアテストアプリをインストールし、GitHub のランナーでコードを自動的にテストすることができます。

記述例

name: auto_test_and_deploy
on: 
  pull_request:
    branches:
      - main

jobs:
    steps:
      # Checkout and install dependencie
      - name: Check out repository code
        uses: actions/checkout@v2

      - name: Prepare Ruby and Gems
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.7
          bundler-cache: true

  build-test:
    name: auto build-test
    needs: prepare
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: yarn
        run: yarn --frozen-lockfile
      - name: Run Breakman
        run: |
          bundle exec bundler-audit --update
          bundle exec brakeman -q -w2
      # Run Linter
      - name: Run Rubocop
        run: |
          bundle exec rubocop --parallel
      # Run RSpec (added later)

  deploy:

name: ワークフロー名を記述する。

jobs: CD/CIで行いたい内容(rubocopを走らせたり、Lintチェックをしたり)を記述する。

steps: 具体的に行いたい内容を記述する。

Dockerって何?

DockerはDocker社が開発したコンテナという概念を管理するソフトウェアで、サーバを起動する方法がシンプルで、かつ起動や処理が速いことが特徴

一つの会社に一つのサーバーが置いてある時代

クラウドにサーバーがある時代

仮想クラウドのある時代

①システム導入の高速化

OSは既に共有して利用しているため、それらの設定は省き、システムを構築するために必要となる最低限のプログラムしかインストールする必要はありません。

そのため、すぐにプログラムを適用し、導入までのスピードを高速化することができます。

②起動時間の短縮化と多くの処理実装が可能

完全仮想化であれば、サーバを起動する際にOSレベルから立ち上げていく必要があり時間がかかります。

一方、DockerではOSは既に立ち上がっているため、その分サーバの起動時間を短縮化することができます。

また、リソースの使用量が少なく済むためサーバへの負荷が低く、1度に多くのプログラム処理を実装することが可能です。

③コンテナ設定の再利用が可能

1度作成したコンテナは、Dockerイメージを作成し、他のコンテナへ適用することにより再利用が可能となります。

検証してみたい時や、リソースを拡大したい時など、すぐに同じ環境設定が適用されたコンテナを準備することができます。

Dockerとは何かを入門者向けに解説!基本コマンドも|Udemy メディア

Docker構築に使ったファイル

Dockerの特徴の一つが、インフラをコード化できるところにあるそう。

これを、Infrastructure as a Codeというらしい。丁度下記に示すDockerfileなんかがそれに該当する。

Dockerfile

FROM ruby:2.6
RUN curl -sS <https://dl.yarnpkg.com/debian/pubkey.gpg> | apt-key add - \\
    && echo "deb <https://dl.yarnpkg.com/debian/> stable main" | tee /etc/apt/sources.list.d/yarn.list \\
    && apt-get update -qq \\
    && apt-get install -y nodejs yarn \\
    && mkdir /Preliquo
WORKDIR /Preliquo
COPY Gemfile /Preliquo/Gemfile
COPY Gemfile.lock /Preliquo/Gemfile.lock
RUN gem install bundler #これを忘れると、bundlerがインストールされてませんと英語で出る。
RUN bundle install
COPY . /Preliquo

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose.yml

version: '3'
services:
  db:
    image: mysql:5.6
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/Preliquo
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
volumes:
  mysql-data:
    driver: local

entrypoint.sh

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /Preliquo/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

このDockerfileを実行するためには下記コードをターミナルで入力する必要がある。

$ docker-compose up

コードを打って出てきた下記エラーに手こずった。

`find_spec_for_exe': Could not find 'bundler'

記事を参考にして、解決。

bundlerが入っていないことが原因だった。Dockerfileに下記記述を追加

RUN gem install bundler

現状

DBをセッティングする場面でかなり時間がかかり、結局完成させることはできなかった。

とりあえず、set databaseは後に置いておいて、他の実装を進めている。

name: auto_test_and_deploy
on: 
  pull_request:
    branches:
      - main
env:
  RAILS_ENV: test
  MYSQL_USER: ${MYSQL_USER}
  MYSQL_PASSWORD: ${MYSQL_PASSWORD}
  MYSQL_HOST: ${DATABASE_HOST}
  MYSQL_PORT: 3306
jobs:
  prepare:
    name: prepare
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      # Checkout and install dependencie
      - name: Check out repository code
        uses: actions/checkout@v2

      - name: Prepare Ruby and Gems
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.7
          bundler-cache: true
      # - name: Setup Database
      #   env:
      #     MYSQL_ROOT_PASSWORD: password
      #   run: |
      #     mysql.server start
      #     gem install bundler
      #     ./bin/rails db:create
      #     ./bin/rails db:migrate
     
      - name: Prepare Node
        uses: actions/setup-node@v2
        with:
          node-version: '12.x'
          cache: 'yarn'
      - name: yarn
        run: yarn --frozen-lockfile

  build-test:
    name: auto build-test
    needs: prepare
    runs-on: ubuntu-latest
    timeout-minutes: 10
    services:
      mysql:
        image: mysql:5.6
        ports:
          - 3306:3306
        env:
          MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    
    steps:
      - name: Check out repository code
        uses: actions/checkout@v2

      - name: Prepare Ruby and Gems
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.7
          bundler-cache: true

      - name: Prepare Node
        uses: actions/setup-node@v2
        with:
          node-version: '12.x'
          cache: 'yarn'
      - name: yarn
        run: yarn --frozen-lockfile

      # - name: Setup database
      #   env:
      #     RAILS_ENV: test
      #   run: |
      #     mysql.server start
      #     gem install bundler
      #     ./bin/rails db:create
      #     ./bin/rails db:migrate
      # Check vulnerabilit
      - name: Run Breakman
        run: |
          bundle exec bundler-audit --update
          bundle exec brakeman -q -w2
      # Run Linter
      - name: Run Rubocop
        run: |
          bundle exec rubocop --parallel
      # Run RSpec (added later)

  # deploy:
  #   name: auto deploy to heroku
  #   needs: [prepare, build-test]
  #   runs-on: ubuntu-latest
  #   timeout-minutes: 10
  #   steps:
  #     - uses: actions/checkout@v2
  #     - uses: akhileshns/heroku-deploy@v3.12.12 # This is the action
  #       with:
  #         heroku_api_key: ${{secrets.HEROKU_API_KEY}}
  #         heroku_app_name: ${{ secrets.HEROKU_APP_NAME }}
  #         heroku_email: ${{secrets.HEROKU_EMAIL}}
  #         # TODO: add a route for health check
  #         healthcheck: "<https://preliquo.herokuapp.com>"

現状打破策①

set databaseを削除。

MySQL関連のエラーが永遠に出現したので、今回はGithub Actionにデータベースをチェックする記述を入れることを断念した。

現状打破策②

デプロイは自分でやる。

下記エラーが出てきて、そのままコピペでググったところ、github のissueが立っていた。

Error: Command failed: git push heroku HEAD:refs/heads/main --force

読んだところ、デプロイは自分でやるのがベストと記載されていたので、github actionsに導入するのを諦めることにした。

Error: Error: Command failed: git push heroku HEAD:refs/heads/main --force · Issue #68 · AkhileshNS/heroku-deploy

今後の意気込み

絶対デプロイもGithub Actionのワークフローに入れたる!

参考文献

RailsアプリケーションでGithub Actionsを試す

戦ったエラー等

Can't connect to local MySQL server through socket '/tmp/mysql.sock'

'/tmp/mysql.sock'からMySQLに接続できません。

mysqlが起動できない(Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)) - Qiita

$ mysql -v ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

root@localhostでアクセスできません。

ERROR 1045 (28000): Access denied for userとなったときの対応方法 - Qiita

The server quit without updating PID file (/usr/local/var/mysql

  1. そもそもpidファイルが存在していない。
  2. pidファイルに適切な権限が設定されていない

mysql 起動時のThe server quit without updating PID file エラーの回避法 - Qiita

mysqld daemon not started

原因: 古いバージョンのmysqlデータが残っていた。

最初はmysql8をダウンロードしていて、色々不具合が生じて面倒だったので、グレードを落としてmysql5.6に変更した。

記事によると、sudoを使ってディレクトリを削除すればいけるとのこと。

実際にやってみた。

$ sudo rm -rf /usr/local/mysql
$ sudo rm -rf /Library/StartupItems/MYSQL
$ sudo rm -rf /Library/PreferencePanes/MySQL.prefPane
$ sudo rm -rf /Library/Receipts/mysql-.pkg
$ sudo rm -rf /usr/local/Cellar/mysql*
$ sudo rm -rf /usr/local/bin/mysql*
$ sudo rm -rf /usr/local/var/mysql*
$ sudo rm -rf /usr/local/etc/my.cnf
$ sudo rm -rf /usr/local/share/mysql*
$ sudo rm -rf /usr/local/opt/mysql*
$ echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
$ /usr/local/opt/mysql@5.6/bin/mysql.server start

Starting MySQL
. SUCCESS!

いけた。

Please remove the file manually and start /usr/local/Cellar/mysql@5.6/5.6.51/bin/mysqld_safe again

ファイルを自分で消して、また/usr/local/Cellar/mysql@5.6/5.6.51/bin/mysqld_safeを打ってください。

Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)

「'/tmp/mysql.sock' (38)を経由してMySQLサーバーにアクセスできません。」

$ ps -ef | grep mysql
501 64915 60061   0  3:08PM ttys003    0:00.00 grep mysql
$ ls -la /usr/local/var/mysql
total 221248
drwxr-xr-x  10 _mysql  _mysql       320 10 13 15:07 .
drwxrwxr-x   9 subaru  admin        288 10 13 12:33 ..
-rw-r-----   1 _mysql  _mysql     28337 10 13 15:07 Subarunookpuro3.err
-rw-rw----   1 _mysql  _mysql        56 10 13 12:42 auto.cnf
-rw-rw----   1 _mysql  _mysql  50331648 10 13 15:07 ib_logfile0
-rw-rw----   1 _mysql  _mysql  50331648 10 13 12:33 ib_logfile1
-rw-rw----   1 _mysql  _mysql  12582912 10 13 15:07 ibdata1
drwx------  81 _mysql  _mysql      2592 10 13 12:33 mysql
drwx------  55 _mysql  _mysql      1760 10 13 12:33 performance_schema
drwx------   2 _mysql  _mysql        64 10 13 12:33 test
$ sudo chown -R $USER /usr/local
chown: /usr/local: Operation not permitted

解決方法

Mysqlをリスタートさせる。

$ mysql.server restart
 ERROR! MySQL server PID file could not be found!
 Starting MySQL
.. SUCCESS!

mysqlが起動できない - Qiita

MySQL起動エラーの対処の仕方【Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)】 - Qiita

解決法

再インストールする。

ターミナル

$ brew uninstall mysql@5.7
$ brew install mysql@5.7

現在起動しているmysqlを確認

$ ps ax | grep mysqld

mysqlをshutdown

mysqladmin --host=192.168.10.100 shutdown
$ docker-compose down --volumes
$ docker-compose up -d --build

GitHub Actionsを使ったRSpec実行環境をつくるときにはまったエラーと対処法

Mysql2::Error::ConnectionError: Access denied for user

Mysql2::Error::ConnectionError: Access denied for user 'Root'@'localhost' (using password: YES)

Mysql2::Error::ConnectionError: Access denied for user 'root'@'localhost' (using password: YES)への対処 - Qiita

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

MySQLでmysqld.sockのエラーが出た (Ubuntu16.04) - Libra Studio エンジニアブログ

MySQLに接続できません...|teratail