Rails on Docker (alpine)로 API 컨테이너를 만들어 보았습니다.

소개



Rails에는 API 모드가 있습니다. 백엔드측에서 Rails를 사용하고 싶은 경우에 편리해 보인다.
이 기사의 Goal은 Rails on Docker에서 API 컨테이너를 구축하기로 결정합니다. DB는 PostgreSQL을 이용한다. 마지막으로 curl에서 제대로 API로 사용할 수 있는지 테스트도 해 둡니다.
docker 또는 docker-compose는 준비된 전제입니다.

목표


  • Rails on Docker (API 모드) 구축
  • curl에서 API가 제대로 작동하는지 테스트합니다.

    목차


  • Rails on Docker아래 준비
  • rails new에서 API 앱 만들기
  • 【TEST】 CRUD를 테스트 해 본다

  • 1. Rails on Docker아래 준비



    우선은 Dockerfile 를 만들어 갑니다. 「 Quickstart: Compose and Rails | Docker Documentation 」에서도 쓰여진 것처럼
  • Dockerfile
  • docker-compose.yml
  • Gemfile
  • Gemfile.lock

  • 근처를 준비합니다. 이러한 파일은 만들려는 앱의 루트 디렉토리에 있습니다.

    Dockerfile
    FROM ruby:2.6.3-alpine3.10
    
    ENV RUNTIME_PACKAGES="linux-headers libxml2-dev make gcc libc-dev nodejs tzdata postgresql-dev postgresql" \
        DEV_PACKAGES="build-base curl-dev" \
        HOME="/app_name" \
        LANG=C.UTF-8 \
        TZ=Asia/Tokyo
    
    WORKDIR $HOME
    
    ADD Gemfile $HOME/Gemfile
    ADD Gemfile.lock $HOME/Gemfile.lock
    
    RUN apk update && \
        apk upgrade && \
        apk add --update --no-cache $RUNTIME_PACKAGES && \
        apk add --update --virtual build-dependencies --no-cache $DEV_PACKAGES && \
        bundle install -j4 && \
        apk del build-dependencies
    
    ADD . $HOME
    
    CMD ["rails", "server", "-b", "0.0.0.0"]
    

    image의 경량화를 목표로 alpine 사용 버리고 있습니다.

    docker-compose.yml
    version: "3"
    
    services:
      db:
        container_name: app_name_db
        image: postgres:11.4-alpine
    
      app:
        container_name: app_name_app
        build: .
        volumes:
          - .:/app_name
        ports:
          - 3000:3000
        depends_on:
          - db
    

    이쪽도 PostgreSQL을 alpine로.

    Gemfile
    source 'https://rubygems.org'
    gem 'rails', '~>5'
    

    Gemfile은 이런 식으로.
    Gemfile.lock은 파일을 만들어 둘 뿐.
    $ touch Gemfile.lock
    

    2. rails new로 API 앱 만들기


    $ docker-compose run app rails new . -f -d postgresql --api
    

    포인트는 --api 부분입니다. 이 옵션을 사용하면 api 앱에 더 이상 필요하지 않습니다.
    그리고는 DB 작성해 둡니다.

    config/database.yml
    #####
    default: &default
      adapter: postgresql
      encoding: unicode
      host: db            # add
      username: postgres  # add
      password:           # add
      pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 
    #####
    
    $ docker-compose build
    $ docker-compose run --rm app rails db:create
    $ docker-compose up -d
    
    http://localhost:3000 를 방문하여 평소 Rails Hello World 페이지가 나오면 성공합니다.


    이 페이지는 표시되지만 API 모드로 앱을 만들고 있으므로 다른 뷰를 만드는 것은 귀찮습니다. scaffold해도 view가 생기거나는 하지 않습니다.

    일단 컨테이너를 멈출 때.
    $ docker-compose down
    

    3. 【TEST】 CRUD를 테스트해 본다



    테스트용으로 적당하게 모델을 만들어 보겠습니다. name 를 가지는 User 모델로 합니다.
    $ docker-compose run --rm app rails generate scaffold user name:string
    $ docker-compose run --rm app rails db:migrate
    $ docker-compose up -d
    

    3-1. Create


    $ curl -X POST http://localhost:3000/users -d 'user[name]=test1'
    {"id":1,"name":"test1","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}
    
    $ curl -X POST http://localhost:3000/users -d 'user[name]=test2'
    {"id":2,"name":"test2","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}
    

    오, 사용자가 할 수있었습니다.

    3-2. Read


    $ curl -X GET http://localhost:3000/users
    [{"id":1,"name":"test1","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"},{"id":2,"name":"test2","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}]
    
    $ curl -X GET http://localhost:3000/users/1
    {"id":1,"name":"test1","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}
    
    index 의 취득도 show 의 취득도 할 수 있었는데. 덧붙여서 GET의 경우는 -X GET 옵션은 없어도 OK.

    3-3. Update


    $ curl -X PUT http://localhost:3000/users/1 -d 'user[name]=test3'
    {"id":1,"name":"test3","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}
    
    id=1의 사용자 nametest1에서 test3로 업데이트되었습니다.

    3-4. Delete


    $ curl -X DELETE http://localhost:3000/users/1
    
    $ curl -X GET http://localhost:3000/users
    {"id":2,"name":"test2","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}
    
    id=1의 사용자가 사라졌습니다!

    Reference


  • DockerCompose에서 컨테이너 기반 Rails 앱을 만들고 그대로 Heroku에 배포 - Qiita
  • Rails에 대한 Curl 명령 비망록 - Qiita
  • 좋은 웹페이지 즐겨찾기