React 프런트엔드 애플리케이션을 사용하여 Ruby on Rails를 Docker화하면 개발 워크플로우와 배포 프로세스가 크게 향상될 수 있습니다. 앱에 대한 표준화된 환경을 생성하면 다양한 개발, 테스트, 생산 단계는 물론 다양한 시스템에서도 일관된 동작을 보장할 수 있습니다. 실제로 시스템 차이로 인한 문제를 최소화하도록 설계되었습니다. 이 가이드는 Docker 컨테이너에서 Rails 및 React 앱을 원활하게 실행하기 위한 필수 단계를 안내합니다.
Docker는 개발자의 컴퓨터, 테스트 환경, 프로덕션 서버 등 배포 위치에 관계없이 애플리케이션이 동일한 방식으로 실행되도록 보장합니다. 이러한 일관성은 모든 종속성과 구성을 컨테이너화하여 달성됩니다.
Docker 컨테이너에는 애플리케이션을 실행하는 데 필요한 모든 종속성이 포함되어 있습니다. 이는 시스템 라이브러리의 변형이나 다른 시스템에 대한 종속성 누락이 애플리케이션의 기능에 영향을 미치지 않음을 의미합니다.
Docker 컨테이너는 호스트 시스템과 서로 분리되어 실행됩니다. 이러한 격리는 서로 다른 응용 프로그램과 동일한 시스템에 대한 종속성 간의 충돌을 방지합니다.
Dockerization에는 이미지와 컨테이너라는 두 가지 주요 개념이 포함됩니다. 이미지는 종속성 및 배포 구성을 포함하여 컨테이너를 만드는 데 필요한 모든 정보를 포함하는 컨테이너의 청사진 역할을 합니다. 컨테이너는 이미지 자체, 실행 환경 및 런타임 명령으로 구성된 이미지의 런타임 인스턴스입니다. Docker는 일반적으로 소프트웨어 배송 표준을 설정합니다.
Docker를 간단한 비유로 설명하자면, 컨테이너는 마당에 있는 배송 컨테이너로, 이미지는 컨테이너 안에 배치된 품목으로, 배송 선박은 컨테이너가 실행되는 시스템으로 생각하세요.
애플리케이션을 설정하고 빌드할 때마다 특정 환경 구성이 필요합니다. 예를 들어 시스템에 Ruby 환경이 설치되어 있지 않으면 Rails 애플리케이션을 실행할 수 없습니다. 마찬가지로 Node.js
없이는 React 애플리케이션을 실행할 수 없으며, npm
이나 Yarn
등과 같은 Node 패키지 관리자 없이는 React 패키지를 설치할 수 없습니다.
컨테이너는 사용자 시스템과 분리되어 실행되므로 시스템에 직접 구축한 경우와 마찬가지로 이러한 모든 패키지를 컨테이너에서 사용할 수 있도록 하여 컨테이너가 시스템에서 시스템 역할을 하도록 할 것입니다. 가상 머신처럼 소유할 수 있습니다. docker와 가상 머신 사이에는 차이점이 있지만 이 예는 단지 추가 설명을 위한 것입니다.
이제 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 https://deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && \ apt-get install -y yarn
curl -fsSL https://deb.nodesource.com/setup_current.x | bash -
: NodeSource 설정 스크립트를 다운로드하고 실행하여 Node.js를 설치합니다.
apt-get install -y nodejs
: Node.js를 설치합니다.
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
: 패키지를 확인하기 위해 Yarn GPG 키를 추가합니다.
echo "deb https://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
필수적입니다. 기본 이미지를 정의하고, 환경 변수를 설정하고, 종속성을 설치함으로써 애플리케이션이 다양한 환경에서 원활하게 실행되도록 할 수 있습니다.
Docker는 개발 프로세스를 간소화할 뿐만 아니라 프로덕션 환경에서 애플리케이션의 안정성도 향상시킵니다. 최적화 영역이 있지만 이는 레일 애플리케이션을 도킹하는 방법에 대한 일반적인 개요일 뿐입니다.
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 https://deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://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 "${@}"