【Docker】Rails(API 모드) + MySQL 로의 환경 구축을 실시한다

소개



Docker 를 사용해 Rails(API 모드) + MySQL 로의 환경 구축을 행했으므로 그 때의 순서를 적는다.

환경 구축



※ docker 의 인스톨등은 끝나 둘 것.
htps : // / cs. 도 c r. jp / 도 c 케 루 ぉ r 마 c / 인 s 타르. HTML

1. 새로운 디렉토리를 만들어 필요한 파일을 작성한다



새 디렉토리 만들기
mkdir rails_api_app

디렉토리가 만들어지면 필요한 파일을 작성.

로컬 환경에서 준비하는 것은 아래 4개만.
모두 rails_api_app 바로 아래에 작성합니다.
  • Dockerfile
  • docker-compose.yml
  • Gemfile
  • Gemfile.lock

  • ※ 나머지 app/controllers/ 야라 config/ 야라는 나중에 컨테이너 내에서 명령을 두드려 생성한다.

    Dockerfile



    Dockerfile
    FROM ruby:3.0.0
    
    RUN apt-get update -qq && apt-get -y install \
        build-essential \
        libpq-dev
    
    RUN mkdir /app
    
    COPY Gemfile /app
    COPY Gemfile.lock /app
    
    WORKDIR /app
    
    RUN gem install bundler && bundle install
    

    docker-compose.yml



    docker-compose.yml
    services:
      web:
        build: .
        ports:
          - "3000:3000"
        depends_on:
          - db
        volumes:
          - .:/app
        command: bundle exec rails s -p 3000 -b '0.0.0.0'
      db:
        image: mysql:5.7
        volumes:
          - mysql_data:/var/lib/mysql/
        environment:
          MYSQL_ROOT_PASSWORD: password
        ports:
          - "3306:3306"
    volumes:
      mysql_data:
    

    Gemfile



    gem 일단 rails 그냥 OK
    ※ 스스로 쓰지 않아도 로컬에 Ruby 의 환경이 있으면, 디렉토리내에서 bundle init 하면 자동 생성된다.

    Gemfile
    # frozen_string_literal: true
    
    source "https://rubygems.org"
    
    git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
    
    gem "rails"
    
    

    Gemfile.lock



    Gemfile.lock은 비어 있습니다.

    Gemfile.lock

    2. build 한다

    必要な4ファイル(Dockerfile, docker-compose.yml, Gemfile, Gemfile.lock)が作成できたら docker compose コマンドでビルドする。

    rails_api_app$ docker compose build
    

    上記コマンドを叩き、特にエラーが起こらなければOK

    3. 컨테이너에서 rails new 한다

    コンテナ内で rails new を実行する。

    rails_api_app$ docker compose run web bundle exec rails new . --force --api -d mysql --skip-test
    

    ※ 自分は rpsec でテストを書くことが多いので --skip-test 옵션을 넣었지만 필요하지 않으면 OK

    docker-compose.yml 에 아래와 같이 volumes 를 쓰고 있는 효과로 마운트 되고 있으므로, 컨테이너내에서 생성되었다 app/ 이하의 파일은 로컬의 디렉토리에도 생성될 것.

    volumes:
      - .:/app
    

    4. DB 만들기



    컨테이너에서 rails db:create 명령을 두드리기
    rails_api_app$ docker compose run web rails db:create
    

    그러면 오류가 발생합니다 ...
    Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
    Couldn't create 'app_development' database. Please check your configuration.
    rails aborted!
    ActiveRecord::ConnectionNotEstablished: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
    /app/bin/rails:5:in `<top (required)>'
    /app/bin/spring:10:in `block in <top (required)>'
    /app/bin/spring:7:in `<top (required)>'
    
    Caused by:
    Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
    /app/bin/rails:5:in `<top (required)>'
    /app/bin/spring:10:in `block in <top (required)>'
    /app/bin/spring:7:in `<top (required)>'
    Tasks: TOP => db:create
    (See full trace by running task with --trace)
    

    MySQL과 잘 연결되어 있지 않은 것 같기 때문에 config/database.yml를 아래와 같이 수정한다

    config/database.yml
    default: &default
      adapter: mysql2
      encoding: utf8mb4
      pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
      username: root
      password: password # docker-compose.yml で設定したパスワード
      host: db # docker-compose.yml でサービス名を db と設定しているので db とする
    

    원인은...

  • host 를 그대로 두고 있던 Rails 에서는 host 를 비우고 있으면 자동으로 로컬의 DB 에 접속하려고 한다. Rails 컨테이너 내에서 본 MySQL은 같은 로컬이 아니므로 docker-compose.yml 로 설정한 서비스명을 host 로 설정하면 접속할 수 있다.

  • password를 설정하는 것을 잊어 버렸습니다. 당연히 연결할 수 없으므로 조심하십시오 ...

    수정할 수 있었으므로 다시 컨테이너에서 rails db:create 명령을 두드리면 성공
    rails_api_app$ docker compose run web rails db:create
    
    [+] Running 1/0
     ⠿ Container qiita2_db_1  Running                                                0.0s
    Created database 'app_development'
    Created database 'app_test'
    

    5. localhost:3000에 연결



    성공!



    깨달은 것



    로컬과 컨테이너의 차이를 없애기 위해서 개발로 사용하는 커멘드 ( rails g scaffold 등)는 가능한 한 컨테이너내에서 실시하는 것이 좋다.

    하기 커맨드로 기동중의 컨테이너 안에 들어갈 수 있으므로 rails db:migraterails g migration , rails g scaffold 등의 커맨드는 하기의 상태로 해 두어 그 안에서 두드리는 느낌.
    rails_api_app$ docker compose exec web bash
    root@d8e9b9afea31:/app#
    
    rials c 등도 docker compose run web rails c로 하는 것이 아니라, 하기 상태에서 두드리면 원활하게 조작할 수 있다.
  • 좋은 웹페이지 즐겨찾기