お世話になっております。
現在、個人アプリ制作で、railsとdocker,mysql,circleCIを用いて、本番環境の環境構築をしています。
docker-compose run web rails db:migrate RAILS_ENV=production
と入力したら、次の様なエラーが出てしまいました。
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2 "No such file or directory")
#行ったこと
mysqlが起動していないと仮説を立て、
sudo service mysqld start Starting mysqld: [ OK ]
となったが、エラーは変わりませんでした。
mysql.sockの場所が曖昧でしたので、
mysql_config --socket
を打ったところ、
/tmp/mysql.sock
と返ってきたのであわせて下記の様にdatabaseを変更しましたが、エラーは変わらなかったです。
default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password host: db socket: /tmp/mysql.sock
次に、エラーログを確認したところ、
Unknown MySQL server host 'db' (25) (Mysql2::Error::ConnectionError)
という風になっており、dbに接続できていないことを確認できました。
host部分をdbにしたり、
compose.ymlのdbに
volumes: - ./tmp/db:/var/lib/mysql/data
を追記してもエラーでした。
現状のエラーですが、
docker-compose run web rails db:create RAILS_ENV=production
は通過するのですが、
docker-compose run web rails db:migrate RAILS_ENV=production
だけ通りません。
ご教授願います。
database.yml
default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password host: localhost socket: /tmp/mysql.sock development: <<: *default database: LuggageMGT_development test: <<: *default host: localhost database: LuggageMGT_test production: <<: *default host: <%= ENV['DB_HOST'] %> database: <%= ENV['DB_DATABASE'] %> username: root password: <%= ENV['DATABASE_PASSWORD'] %> socket: /var/lib/mysql/mysql.sock
docker-compose.yml
version: '3' services: web: build: . ports: - "3000:3000" links: - db tty: true command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/app_name db: image: mysql:5.6 environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: root ports: - "4306:3306" volumes: - ./tmp/db:/var/lib/mysql/data volumes: bundle: mysql_data:
dockerfile
FROM ruby:2.5.3 RUN apt-get update -qq && \ apt-get install -y build-essential \ libpq-dev \ nodejs RUN mkdir /app_name ENV APP_ROOT /app_name WORKDIR $APP_ROOT ADD ./Gemfile $APP_ROOT/Gemfile ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock RUN bundle install ADD . $APP_ROOT
(関係ないかもですが、)
circleci/config.yml
version: 2 jobs: build: docker: - image: circleci/ruby:2.5.3-node-browsers environment: RAILS_ENV: 'test' - image: circleci/mysql:5.6 environment: MYSQL_ROOT_PASSWORD: "password" MYSQL_ROOT_HOST: "%" working_directory: ~/app_name steps: - checkout - restore_cache: # キャッシュを読み込む keys: - gem-cache-v1-{{ checksum "Gemfile.lock" }} - gem-cache-v1- - run: name: Bundle Install command: bundle check --path vendor/bundle || bundle install --deployment - save_cache: # キャッシュを保存する key: gem-cache-v1-{{ checksum "Gemfile.lock" }} paths: - vendor/bundle - run: name: Wait for DB command: dockerize -wait tcp://127.0.0.1:3306 -timeout 120s - run: bundle exec rake db:create - run: bundle exec rake db:schema:load - run: name: run tests command: | mkdir /tmp/test-results TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)" bundle exec rspec --format progress \ --out /tmp/test-results/rspec.xml \ --format progress \ $TEST_FILES - store_test_results: path: /tmp/test-results - store_artifacts: path: /tmp/test-results destination: test-results - add_ssh_keys: fingerprints: - "1f:d5:4b:1c:ed:c1:92:6e:47:a1:e0:18:a0:ff:27:ca" - deploy: name: Capistrano deploy command: | if [ "${CIRCLE_BRANCH}" != "master" ]; then exit 0 fi bundle exec cap production deploy unicorn:restart
追記です。
mysql_config --socket
の結果が、ローカルとEC2ターミナルでは違いました。
ローカル
% mysql_config --socket /tmp/mysql.sock
EC2
% mysql_config --socket /var/lib/mysql/mysql.sock
そこで、database.ymlをこの様に変更しましたが、エラーは変わりませんでした。
# MySQL. Versions 5.1.10 and up are supported. # # Install the MySQL driver # gem install mysql2 # # Ensure the MySQL gem is defined in your Gemfile # gem 'mysql2' # # And be sure to use new-style password hashing: # https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html # default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password host: db socket: /tmp/mysql.sock development: <<: *default database: LuggageMGT_development # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default database: LuggageMGT_test # As with config/secrets.yml, you never want to store sensitive information, # like your database password, in your source code. If your source code is # ever seen by anyone, they now have access to your database. # # Instead, provide the password as a unix environment variable when you boot # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database # for a full rundown on how to provide these environment variables in a # production deployment. # # On Heroku and other platform providers, you may have a full connection URL # available as an environment variable. For example: # # DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase" # # You can use this database configuration with: # # production: # url: <%= ENV['DATABASE_URL'] %> # production: <<: *default host: <%= ENV['DB_HOST'] %> database: <%= ENV['DB_DATABASE'] %> username: <%= ENV['DB_USERNAME'] %> password: <%= ENV['DB_PASSWORD'] %> socket: /var/lib/mysql/mysql.sock
ps ax | grep mysqld
の結果です。
9762 ? Ssl 0:01 mysqld 13734 pts/1 S+ 0:00 grep --color=auto mysqld 21504 ? S 0:00 /bin/sh /usr/libexec/mysql56/mysqld_safe --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock --pid-file=/var/run/mysqld/mysqld.pid --basedir=/usr --user=mysql 21718 ? Sl 0:14 /usr/libexec/mysql56/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql56/plugin --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock