React 프런트엔드 애플리케이션을 사용하여 Ruby on Rails를 Docker화하면 개발 워크플로우와 배포 프로세스가 크게 향상될 수 있습니다. 앱에 대한 표준화된 환경을 생성하면 다양한 개발, 테스트, 생산 단계는 물론 다양한 시스템에서도 일관된 동작을 보장할 수 있습니다. 실제로 시스템 차이로 인한 문제를 최소화하도록 설계되었습니다. 이 가이드는 Docker 컨테이너에서 Rails 및 React 앱을 원활하게 실행하기 위한 필수 단계를 안내합니다.
애플리케이션을 설정하고 빌드할 때마다 특정 환경 구성이 필요합니다. 예를 들어 시스템에 Ruby 환경이 설치되어 있지 않으면 Rails 애플리케이션을 실행할 수 없습니다. 마찬가지로 Node.js
없이는 React 애플리케이션을 실행할 수 없으며, npm
이나 Yarn
등과 같은 Node 패키지 관리자 없이는 React 패키지를 설치할 수 없습니다.
이제 Rails 애플리케이션을 도킹해 보겠습니다. 이를 위해서는 Rails 애플리케이션에 Dockerfile
, docker-compose.yml
및 bin/docker-entrypoint
세 가지 파일이 필요합니다. 각 파일을 자세히 살펴보겠습니다.
주의:
Dockerfile
Docker 컨테이너를 생성하기 위한 청사진입니다. 여기에는 Docker가 이미지를 빌드하는 데 사용하는 일련의 지침이 포함되어 있으며, 해당 이미지는 컨테이너를 실행하는 데 사용할 수 있습니다. Ruby on Rails 및 React 애플리케이션용 Dockerfile
분석해 보겠습니다.
ARG RUBY_VERSION=3.1.4 FROM ruby:$RUBY_VERSION
ARG RUBY_VERSION=3.1.4
: 기본값이 3.1.4
인 RUBY_VERSION
이라는 빌드 인수를 정의합니다. 이는 빌드 시 재정의될 수 있습니다.
FROM ruby:$RUBY_VERSION
: RUBY_VERSION
에 지정된 버전의 ruby
기본 이미지를 사용합니다. 그러면 Ruby 런타임으로 컨테이너가 설정됩니다. 앞서 언급한 것처럼 Rails 애플리케이션을 실행하려면 Ruby가 설치되어 있어야 합니다. RUN apt-get update -qq && \ apt-get install -y build-essential libvips bash bash-completion libffi-dev tzdata postgresql curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man
apt-get update -qq
: 조용한 출력을 위해 -qq
사용하여 리포지토리에서 패키지 목록을 업데이트합니다.
apt-get install -y
... : 다양한 패키지를 설치합니다. build-essential
: GCC와 같은 소프트웨어 구축을 위한 필수 패키지입니다.
libvips
: 이미지 처리를 위한 라이브러리입니다.
bash
, bash-completion
: Bash 쉘 및 자동 완성.
libffi-dev
: 외부 함수 인터페이스 라이브러리.
tzdata
: 시간대 데이터입니다.
postgresql
: PostgreSQL 데이터베이스 클라이언트입니다.
curl
: URL에서 데이터를 전송하는 도구입니다.
apt-get clean
: 검색된 패키지 파일의 로컬 저장소를 정리합니다.
rm -rf /var/lib/apt/lists/ /usr/share/doc /usr/share/man
: 이미지 크기를 줄이기 위해 패키지 목록과 문서를 제거합니다. RUN curl -fsSL //deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS //dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb //dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && \ apt-get install -y yarn
curl -fsSL //deb.nodesource.com/setup_current.x | bash -
: NodeSource 설정 스크립트를 다운로드하고 실행하여 Node.js를 설치합니다.
apt-get install -y nodejs
: Node.js를 설치합니다.
curl -sS //dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
: 패키지를 확인하기 위해 Yarn GPG 키를 추가합니다.
echo "deb //dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
: Yarn의 저장소를 소스 목록에 추가합니다.
apt-get update && apt-get install -y yarn
: 패키지 목록을 업데이트하고 Yarn을 설치합니다. ENV NODE_OPTIONS=--openssl-legacy-provider
ENV NODE_OPTIONS=--openssl-legacy-provider
: Node.js에 대한 레거시 OpenSSL 지원을 활성화하도록 환경 변수를 설정합니다. WORKDIR /rails
WORKDIR /rails
: 후속 지침을 위한 작업 디렉터리를 /rails
로 설정합니다. ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV
ARG RAILS_ENV
: Rails 환경( development
, test
, production
등)을 지정하기 위해 RAILS_ENV
라는 빌드 인수를 정의합니다.
ENV RAILS_ENV=$RAILS_ENV
: 환경 변수 RAILS_ENV
빌드 인수의 값으로 설정합니다. COPY Gemfile Gemfile.lock ./ RUN bundle install
COPY Gemfile Gemfile.lock ./
: Gemfile
및 Gemfile.lock
작업 디렉터리에 복사합니다.
RUN bundle install
: Gemfile
에 지정된 Ruby gem을 설치합니다. COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile
COPY package.json yarn.lock ./
: package.json
및 yarn.lock
작업 디렉터리에 복사합니다.
RUN yarn install --frozen-lockfile
: Yarn을 사용하여 프런트엔드 종속성을 설치하여 yarn.lock
의 정확한 버전을 사용하도록 합니다. COPY . .
COPY . .
: 모든 애플리케이션 코드를 작업 디렉터리에 복사합니다. RUN bundle exec bootsnap precompile --gemfile app/ lib/
RUN bundle exec bootsnap precompile --gemfile app/ lib/
: Rails 애플리케이션 부팅 시간을 단축하기 위해 Bootsnap 캐시를 사전 컴파일합니다. Bootsnap은 비용이 많이 드는 계산을 캐싱하여 Ruby 및 Rails 부팅 시간을 단축하는 보석입니다. RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi
RUN if [ "$RAILS_ENV" = "production" ]; then
... : RAILS_ENV
production
으로 설정된 경우에만 자산 사전 컴파일을 조건부로 실행합니다. 이 단계는 프로덕션 환경을 위한 자산을 준비하는 데 중요합니다. COPY bin/docker-entrypoint /rails/bin/ RUN chmod +x /rails/bin/docker-entrypoint
COPY bin/docker-entrypoint /rails/bin/
: 사용자 정의 진입점 스크립트를 컨테이너에 복사합니다.
RUN chmod +x /rails/bin/docker-entrypoint
: 진입점 스크립트를 실행 가능하게 만듭니다. ENTRYPOINT ["/rails/bin/docker-entrypoint"] EXPOSE 5000 // you can use any port of your choice CMD ["./bin/rails", "server"]
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
: 컨테이너가 시작될 때 실행될 진입점 스크립트를 설정합니다. 이 스크립트는 일반적으로 환경을 설정하고, 데이터베이스를 준비하고, 애플리케이션을 시작합니다.
EXPOSE 5000
: 컨테이너가 포트 5000에서 수신 대기함을 나타냅니다. 이는 문서 기능이며 포트를 게시하지 않습니다.
CMD ["./bin/rails", "server"]
: 컨테이너가 시작될 때 실행할 기본 명령, 즉 Rails 서버를 시작하도록 지정합니다. docker-compose.yml
파일은 다중 컨테이너 Docker 애플리케이션을 정의하고 실행하는 데 사용됩니다. 이를 통해 애플리케이션의 서비스, 네트워크 및 볼륨을 단일 파일로 구성할 수 있습니다. 이 경우에는 두 가지 서비스를 사용하겠습니다. Rails 애플리케이션용 docker-compose.yml
파일은 다음과 같습니다.
db
) codedb: image: postgres:14.2-alpine container_name: demo-postgres-14.2 volumes: - postgres_data:/var/lib/postgresql/data command: "postgres -c 'max_connections=500'" environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "5432:5432"
image: postgres:14.2-alpine
: 이 서비스에 사용할 Docker 이미지를 지정합니다. 이 경우 Alpine Linux 배포판을 기반으로 하는 PostgreSQL 14.2 이미지입니다. 알파인 이미지는 크기가 작은 것으로 알려져 있어 전체 이미지 크기를 작게 유지하는 데 도움이 됩니다.
container_name: demo-postgres-14.2
: 컨테이너 이름을 demo-postgres-14.2
지정합니다. 이 이름은 명령 및 로그에서 컨테이너를 참조하는 데 사용됩니다.
volumes
: postgres_data:/var/lib/postgresql/data:
명명된 볼륨 postgres_data
컨테이너 내부의 /var/lib/postgresql/data
에 마운트합니다. 이 디렉터리는 PostgreSQL이 데이터를 저장하는 곳으로, 컨테이너를 다시 시작해도 데이터베이스 데이터가 유지되도록 합니다.
command: "postgres -c 'max_connections=500'"
: PostgreSQL 이미지의 기본 명령을 재정의합니다. 최대 연결 수를 500으로 늘리는 구성 옵션으로 PostgreSQL을 시작합니다.
environment
: POSTGRES_DB: ${POSTGRES_DB}
: 환경 변수 POSTGRES_DB
를 사용하여 생성할 기본 데이터베이스의 이름을 설정합니다.
POSTGRES_USER: ${POSTGRES_USER}
: POSTGRES_USER
환경 변수를 사용하여 PostgreSQL 데이터베이스에 액세스하기 위한 기본 사용자 이름을 설정합니다.
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
: POSTGRES_PASSWORD
환경 변수를 사용하여 기본 사용자의 비밀번호를 설정합니다.
ports
:"5432:5432"
: 호스트의 포트 5432를 컨테이너의 포트 5432에 매핑합니다. 이를 통해 포트 5432를 통해 호스트 시스템의 PostgreSQL에 액세스할 수 있습니다.demo-web
) codedemo-web: build: context: . args: - RAILS_ENV=${RAILS_ENV} command: "./bin/rails server -b 0.0.0.0" environment: - RAILS_ENV=${RAILS_ENV} - POSTGRES_HOST=${POSTGRES_HOST} - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - RAILS_MASTER_KEY=${RAILS_MASTER_KEY} volumes: - .:/rails - app-storage:/rails/storage depends_on: - db ports: - "3000:3000"
build:
context: .
: Docker 이미지의 빌드 컨텍스트를 지정합니다. 이 경우 .
현재 디렉터리를 나타냅니다. 이는 Docker가 현재 디렉터리의 Dockerfile을 사용하여 이미지를 빌드한다는 의미입니다.args
: RAILS_ENV=${RAILS_ENV}
: RAILS_ENV
빌드 인수를 Docker 빌드 프로세스에 전달하여 Rails 환경( development
, test
또는 production
등)을 지정할 수 있도록 합니다.
command: "./bin/rails server -b 0.0.0.0"
: Docker 이미지의 기본 명령을 재정의합니다. Rails 서버를 시작하고 이를 컨테이너 외부에서 서비스에 액세스하는 데 필요한 모든 네트워크 인터페이스( 0.0.0.0
)에 바인딩합니다.
environment:
RAILS_ENV=${RAILS_ENV}
: RAILS_ENV
환경 변수를 사용하여 컨테이너 내부에 Rails 환경을 설정합니다.
POSTGRES_HOST=${POSTGRES_HOST}
: PostgreSQL 호스트 주소를 설정합니다.
POSTGRES_DB=${POSTGRES_DB}
: 데이터베이스 이름을 설정합니다.
POSTGRES_USER=${POSTGRES_USER}
: PostgreSQL 사용자를 설정합니다.
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
: PostgreSQL 사용자 비밀번호를 설정합니다.
RAILS_MASTER_KEY=${RAILS_MASTER_KEY}
: 자격 증명 및 기타 비밀을 암호화하는 데 사용되는 Rails 마스터 키를 설정합니다.
volumes
:
.:/rails
: 현재 디렉터리( docker-compose.yml
파일이 있는 위치)를 컨테이너 내부의 /rails
에 마운트합니다. 이를 통해 호스트의 파일을 편집하고 해당 변경 사항을 컨테이너 내부에 반영할 수 있습니다.
app-storage:/rails/storage
: 명명된 볼륨 app-storage
컨테이너 내부의 /rails/storage
에 마운트합니다. 이는 일반적으로 로그, 업로드, 캐시된 파일과 같은 Rails 관련 파일을 저장하는 데 사용됩니다.
depends_on
:
db
: demo-web
서비스가 시작하기 전에 db
서비스가 준비될 때까지 기다리도록 합니다. Docker Compose는 이 설정에 따라 서비스 시작 순서를 처리합니다. ports:
"3000:3000"
: 호스트의 포트 3000을 컨테이너의 포트 3000에 매핑합니다. 이를 통해 포트 3000을 통해 호스트 시스템의 Rails 애플리케이션에 액세스할 수 있습니다. codevolumes: postgres_data: app-storage:
postgres_data
: PostgreSQL 데이터를 유지하기 위해 db
서비스에서 사용하는 명명된 볼륨 postgres_data
정의합니다.app-storage
: 업로드 및 로그와 같은 애플리케이션별 데이터를 유지하기 위해 demo-web
서비스에서 사용하는 명명된 볼륨 app-storage
정의합니다. bin/docker-entrypoint
스크립트는 Docker 설정의 중요한 부분입니다. 컨테이너가 시작될 때 실행되며 일반적으로 기본 애플리케이션을 시작하기 전에 필요한 환경 설정, 데이터베이스 준비 및 기타 초기화 작업을 처리합니다. 다음은 bin/docker-entrypoint
스크립트의 예와 각 부분에 대한 자세한 설명입니다.
bashCopy code#!/bin/bash set -e
#!/bin/bash
: 이 줄은 Bash 셸을 사용하여 스크립트를 실행해야 함을 지정합니다.
set -e
: 명령이 0이 아닌 종료 코드를 반환하는 경우 즉시 종료하도록 스크립트에 지시합니다. 이렇게 하면 단계가 실패할 경우 스크립트 실행이 중지되어 후속 단계가 잘못된 상태로 실행되는 것을 방지할 수 있습니다.
조건부 데이터베이스 생성 또는 마이그레이션
# If running the rails server then create or migrate existing database if [ "${*}" == "./bin/rails server" ]; then ./bin/rails db:create ./bin/rails db:prepare fi
"${*}"
)에 전달된 명령이 ./bin/rails server
인지 확인합니다. *
스크립트에 전달된 모든 위치 매개변수를 보유하는 특수 매개변수입니다.
./bin/rails DB
: 조건이 충족되면 이 명령은 데이터베이스 생성을 시도합니다. 이는 데이터베이스 구성 파일( config/database.yml
)에 정의된 대로 데이터베이스를 설정하는 rails db:create
실행하는 것과 동일합니다.
./bin/rails DB
: 이 명령은 데이터베이스가 설정되고 마이그레이션되었는지 확인하는 rails db:prepare
실행합니다. 데이터베이스가 없으면 데이터베이스를 생성하고 데이터베이스가 이미 생성된 경우 마이그레이션을 실행합니다. 이는 rails db:create
및 rails db:migrate
의 조합입니다.
bashCopy codeexec "${@}"
exec "${@}"
: 현재 쉘 프로세스를 스크립트에 인수로 전달된 명령으로 대체합니다. @
기호는 스크립트에 전달된 모든 위치 매개변수를 보유합니다. 예를 들어 스크립트가 ./bin/rails server
로 호출되면 이 줄은 ./bin/rails server
컨테이너의 기본 프로세스로 효과적으로 실행합니다. Ruby on Rails 및 React 애플리케이션을 위한 안정적이고 일관된 환경을 생성하려면 잘 만들어진 Dockerfile
필수적입니다. 기본 이미지를 정의하고, 환경 변수를 설정하고, 종속성을 설치함으로써 애플리케이션이 다양한 환경에서 원활하게 실행되도록 할 수 있습니다.
Dockerfile
, docker-compose.yml
및 bin/docker-entrypoint
에 대한 전체 스크립트 ARG RUBY_VERSION=3.1.4 FROM ruby:$RUBY_VERSION # Install dependencies RUN apt-get update -qq && \ apt-get install -y build-essential libvips bash bash-completion libffi-dev tzdata postgresql curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man # Install Node.js and Yarn RUN curl -fsSL //deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS //dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb //dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && \ apt-get install -y yarn # Set environment variable to enable legacy OpenSSL support ENV NODE_OPTIONS=--openssl-legacy-provider # Rails app lives here WORKDIR /rails # Set environment variable for the build ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV # Install application gems COPY Gemfile Gemfile.lock ./ RUN bundle install # Install frontend dependencies COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile # Copy application code COPY . . # Precompile bootsnap code for faster boot times RUN bundle exec bootsnap precompile --gemfile app/ lib/ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi # Entrypoint prepares the database. COPY bin/docker-entrypoint /rails/bin/ RUN chmod +x /rails/bin/docker-entrypoint # Use an absolute path for the entry point script ENTRYPOINT ["/rails/bin/docker-entrypoint"] # Start the server by default, this can be overwritten at runtime EXPOSE 5000 CMD ["./bin/rails", "server"]
services: db: image: postgres:14.2-alpine container_name: demo-postgres-14.2 volumes: - postgres_data:/var/lib/postgresql/data command: "postgres -c 'max_connections=500'" environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "5432:5432" demo-web: build: context: . args: - RAILS_ENV=${RAILS_ENV} command: "./bin/rails server -b 0.0.0.0" environment: - RAILS_ENV=${RAILS_ENV} - POSTGRES_HOST=${POSTGRES_HOST} - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - RAILS_MASTER_KEY=${RAILS_MASTER_KEY} volumes: - .:/rails - app-storage:/rails/storage depends_on: - db ports: - "3000:3000" volumes: postgres_data: app-storage:
#!/bin/bash set -e # If running the rails server then create or migrate existing database if [ "${*}" == "./bin/rails server" ]; then ./bin/rails db:create ./bin/rails db:prepare fi exec "${@}"