Rails API + MySQL + docker-compose 환경 구축

DB를 MySQL 로 한 Rails API 환경을 docker-compose 를 사용해 구축했습니다.

전제



Docker & docker-compose 설치됨

운영 환경


  • macOS Catalina 10.15.7
  • Ruby 2.7.1
  • Ruby on Rails 6.0.3
  • MySQL 8.0.23
  • Docker 20.10.2
  • docker-compose 1.27.4

  • 디렉토리 구성



    최종 디렉토리 구성은 다음과 같습니다. MySQL의 데이터를 격납하는 mysql 와, rails 내의 각 디렉토리 이하의 내용은 생략하고 있습니다.
    rails_api_mysql
      ├── docker-compose.yml
      ├── db
      └── app
          ├── Dockerfile
          ├── Gemfile
          ├── Gemfile.lock
          ├── README.md
          ├── Rakefile
          ├── app
          ├── bin
          ├── config
          ├── config.ru
          ├── db
          ├── lib
          ├── log
          ├── public
          ├── storage
          ├── test
          ├── tmp
          └── vendor
    

    절차



    프로젝트를 만듭니다.
    mkdir rails_api_mysql
    cd rails_api_mysql
    
    docker-compose.yml 를 작성합니다.

    docker-compose.yml
    version: '3'
    services: 
      db:
        image: mysql:8.0.23
        environment: 
          MYSQL_ROOT_PASSWORD: password
        volumes: 
          - ./mysql:/var/lib/mysql
        command: ["--default-authentication-plugin=mysql_native_password"]
        ports: 
          - 3306:3306
      app:
        build: rails
        volumes: 
          - ./rails:/usr/src/app
        command: ["rails", "server", "-b", "0.0.0.0"]
        ports: 
          - 3000:3000
        depends_on:
          - db
    

    MySQL의 데이터를 호스트 측에서 관리하기 위해서 servicesdbvolume 를 지정하고 있습니다.

    MySQL 데이터를 저장하기 위한 db 디렉토리를 작성합니다. 내용은 비어 있고 괜찮습니다.
    mkdir db
    

    Rails 애플리케이션을 저장하기 위한 app 디렉토리를 작성하고, 그 안에 Gemfile Gemfile.lock Dockerfile 를 작성합니다.

    /app/Gemfile
    source 'https://rubygems.org'
    
    gem 'rails', '6.0.3'
    

    /app/Gemfile.lock
    空で大丈夫です
    

    /app/Dockerfile
    FROM ruby:2.7.1-alpine3.11
    
    ENV BUNDLER_VERSION=2.1.4
    
    WORKDIR /usr/src/app
    
    COPY Gemfile .
    COPY Gemfile.lock .
    
    RUN apk update && \
        apk add --no-cache \
        shared-mime-info \
        linux-headers \
        libxml2-dev \
        curl-dev \
        make \
        gcc \
        libc-dev \
        g++ \
        build-base \
        mariadb-dev \
        tzdata && \
        gem install bundler && \
        bundle install
    
    COPY . .
    
    EXPOSE 3000
    

    rails new 를 실행하여 응용 프로그램을 만듭니다. 이제 rails 디렉토리에 각 파일이 생성됩니다.
    docker-compose run --rm --no-deps app rails new . --force --database=mysql --skip-keeps -M -C -S -J -B
    
    /app/config/database.yml 를 편집합니다.

    database.yml
    default: &default
      adapter: mysql2
      encoding: utf8mb4
      pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
      username: root
      password: password # docker-compose.ymlのMYSQL_ROOT_PASSWORDと同じにします
      host: db # docker-compose.ymlのservicesのdbのことです
    
    development:
      <<: *default
      database: app_development
    
    test:
      <<: *default
      database: app_test
    
    production:
      <<: *default
      database: app_production
      username: app
      password: <%= ENV['APP_DATABASE_PASSWORD'] %>
    


    docker 이미지를 다시 빌드합니다. 위의 rails new를 실행하면 Gemfile Gemfile.lock의 내용이 변경되었기 때문입니다.
    docker-compose build
    

    컨테이너를 시작합니다.
    docker-compose up
    

    컨테이너에 액세스하고 DB를 빌드합니다.
    docker-compose run app rails db:create
    
    localhost:3000 에 접속해, 기동 화면이 표시되면 성공입니다.



    동작 확인



    MySQL이 제대로 작동하는지 확인합니다.

    컨테이너에 로그인합니다.
    docker-compose exec app sh
    
    controllermodel를 만듭니다.
    rails g controller Users index --no-template-engine --no-test-framework --no-assets
    
    rails g model User name:string --no-test-framework
    
    /db/seeds.rb 에 다음을 추가하여 테스트 데이터를 정의합니다.

    seeds.rb
    User.create name: "Pythagoras"
    


    DB를 초기화하고 테스트 데이터를 반영합니다.
    rails db:migrate
    rails db:seed
    
    /app/controllers/users_controller.rb 의 index 액션을 다음으로 변경합니다.

    users_controller.rb
    def index
      @users = User.all
      render json: @users
    end
    

    localhost:3000/users/index에 접속하면 다음과 같이 표시되어야합니다.



    컨테이너를 한 번 버리고 다시 시작합니다.
    docker-compose down
    
    docker-compose up
    

    다시 한번 localhost:3000/users/index 에 액세스하여 아래와 같이 표시되면 성공입니다. 제대로 호스트 측의 MySQL 데이터가 읽혀지고 있네요.



    읽어 주셔서 감사합니다! 지적이나 의견 등 있으면 댓글을 주시면 기쁩니다 🐳

    좋은 웹페이지 즐겨찾기