📅 · Programming ⏰  10 分で読めます

Dockerのインストール

Dockerのインストール cloud9を使用する場合でamazon linuxを選択した場合はデフォルトでDockerが入っているのでインストールの必要はありません。 確認のためにターミナルでコマンドを入力してみましょう。 $ docker -v  Docker version...

Dockerのインストール

cloud9を使用する場合でamazon linuxを選択した場合はデフォルトでDockerが入っているのでインストールの必要はありません。 確認のためにターミナルでコマンドを入力してみましょう。

$ docker -v

Docker version 18.09.9-ce, build 039a7df

↑のような出力がされればdockerがインストールされています。

docker-composeのインストール

開発環境ではRubyイメージだけでなく、データベースイメージも同時に使用するので、Dockerのオーケストレーションツール、docker-composeを使用します。 Docker Desctopの場合はdocker-composeも同時にインストールされるので、この作業は必要ありません。

インストールのために下記コマンドを入力してください。

ref: https://docs.docker.com/compose/install/

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.25.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

実行権限を付与します

$ sudo chmod +x /usr/local/bin/docker-compose

docker-composeが正しくダウンロードできたか確認しましょう

$ docker-compose -v

docker-compose version 1.25.1, build 4667896b

上記のような出力がされれば正常にインストールできています。

ディレクトリの作成

作業するディレクトリを作成します。 ターミナルに以下のコマンドを打ち込みディレクトリを作成しましょう。

$ mkdir sharing_economy

作成したディレクトリに移動します。

$ cd sharing_economy

今後はこの作成したディレクトリ内で作業します。

Dockerfileを作成します。

ターミナルからtouchコマンドを実行すると、空のファイルを作成できます。

$ touch Dockerfile
Dockerfile
FROM node:14.17.6
FROM ruby:3.0.2
COPY --from=node /opt/yarn-* /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
  && ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx \
  && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg

RUN apt-get update -qq && \
  apt-get install -y build-essential \
  libpq-dev \
  postgresql-client \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

RUN mkdir /myapp
WORKDIR /myapp

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

RUN bundle install

COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

Gemfileを作成します。 このファイルをもとにRailsをinstallします。

$ touch Gemfile

Gemfileが生成されたので以下を記述します。

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

次に空のGemfile.lockを作成します

$ touch Gemfile.lock

Gemfile.lockbundle installコマンドで自動で書き込まれるため、中身は空のままで問題ありません。 本来であれば作成する必要はないのですが、 前述のDockerfileでCOPYをしているので、 空でもファイルが存在している必要があるため作成しています。

つぎにコンテナ起動時に実行されるentrypointを作成します。 pidファイルが存在するときにRailsのサーバーが起動しないことがあるので、この問題を修正するためにentrypoint.shを追加します。

$ touch entrypoint.sh

entrypoint.shが作成されたので以下を記述します。

entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

docker-compose.ymlを作成します。 databaseはpostgresqlを使用します。 docker-composeがあることで、Railsサーバーとdatabaseサーバーを同時に起動し、容易に連携することができます。

$ touch docker-compose.yml

docker-compose.ymlに以下を記述します。

docker-compose.yml
version: '3'
services:
  db:
    image: postgres:12
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=password
  web:
    build: .
    image: mercari-clone:latest
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

cloud9を使用する場合はportを8080に変更します。

docker-compose.yml
     volumes:
       - .:/myapp
     ports:
      - "8080:3000"
     depends_on:
       - db

これらのファイルを用意したら空のRailsプロジェクトを作成します。 Railsではプロジェクトを開始する際に、雛形を作成するコマンドが用意されています(rails new)。 様々なオプションが用意されています。 rails new .は多くの場合.ではなくmercari_cloneのようなアプリケーション名を指定するのですが、今回はカレントディレクトリに作成したいので.を指定します。 今回使用するオプションの説明です。

オプション説明
—forceファイルが存在する場合に上書きする
—databaseデータベースの指定(default sqlite3)

オプションの全てはrails new --helpで確認することができます。

$ docker-compose run web rails new . --force --database=postgresql

PermissionError: [Errno 13] Permission denied

↑のエラーが出た場合は以下のコマンドをターミナルで打ち込んでください。

LinuxでDockerを実行した場合、作成されたファイルの所有権はrootです。コンテナがrootユーザーとして実行されるために発生します。この場合、新しいファイルの所有権を変更します。

$ sudo chown -R $USER:$USER .
$ docker-compose down

新しいGemfileが作成されたので、イメージを再度buildする必要があります。

$ docker-compose build

これでRailsアプリを起動することができるようになりましたが、databaseと接続ができません。 database接続設定を修正しましょう。

config/database.yml
 default: &default
   adapter: postgresql
   encoding: unicode
+  host: db
+  username: postgres
+  password: password
   # For details on connection pooling, see Rails configuration guide
   # https://guides.rubyonrails.org/configuring.html#database-pooling
   pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

これでdatabaseと接続できるようになりました。

docker-compose upでアプリを起動します。

$ docker-compose up

cloud9の場合はこの状態でpreview画面を開いてみましょう。 macやwindowsの方は

http://localhost:3000

にアクセスしてみましょう。

image-1639150108693.jpg

image-1639150126760.jpg

image-1639150140929.jpg

エラー画面が出ました。

image-1639150175746.jpg

cloud9のpreviewURLを許可しましょう。

エラー画面に出たhostをコピーしてペーストします。 この値は各自異なるので画面の値をコピーしてください。

config/environments/development.rb
   # Use an evented file watcher to asynchronously detect changes in source code,
   # routes, locales, etc. This feature depends on the listen gem.
   config.file_watcher = ActiveSupport::EventedFileUpdateChecker

   config.hosts << "xxxxxxxxx.vfs.cloud9.us-east-1.amazonaws.com"
 end

他の環境でも動くように環境変数にしましょう。

cloud9の場合はhostがlocalhostにならないので、修正をしていきます。 docker-composeを使用している場合は環境変数ファイルを設定しましょう。

docker-compose.yml
       - ./tmp/db:/var/lib/postgresql/data
   web:
     build: .
     env_file: .env
     command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
     volumes:
       - .:/myapp

docker-composeを使用していない場合はdotenv-railsgemを利用しましょう。

Gemfile

group :development, :test do
  gem 'dotenv-rails'
end
$ bundle install

dotenv-railsの場合は.envファイルが自動的に読み込まれます。 .envファイルを追加します。

$ touch .env

mailerのURLのホストの設定をします。 各環境(development,staging,production)で異なるホストを設定したいので、環境変数で設定します。

cloud9の場合は各自のcloud9のpreviewURLをHOST環境変数に設定してください。

.env
DOMAIN_NAME=https://xxxx.vfs.cloud9.us-east-1.amazonaws.com
PORT=8080

.env.exampleというサンプルファイルを用意しておくとローカル環境に移行した場合や、複数人で開発する際に設定するべき環境変数の値がわかりやすくなります。

$ touch .env.example
.env.example
DOMAIN_NAME=https://xxxx.vfs.cloud9.us-east-1.amazonaws.com
PORT=8080
config/environments/development.rb
@@ -73,4 +73,5 @@ Rails.application.configure do

   # Uncomment if you wish to allow Action Cable access from any origin.
   # config.action_cable.disable_request_forgery_protection = true
+  config.hosts << ENV["DOMAIN_NAME"]

環境変数ファイルはgit管理対象から外しましょう。

.gitignore
  /yarn-error.log
  yarn-debug.log*
  .yarn-integrity
+ .env

gitのキャッシュを削除しないと反映されないので、下記コマンドを実行します。

$ git rm -r --cached .

この状態で再度アクセスしてみましょう。 データベースが存在しないエラーが発生します。

image-1639150209286.jpg

次にdatabaseを作成します。

$ docker-compose run --rm web rake db:create

Starting rails_db_1 ... done
Created database 'myapp_development'
Created database 'myapp_test'

http://localhost:3000にアクセスしてみましょう。

Railsのwelcomeページが表示されれば成功です。

image-1639150231206.jpg

アプリケーションの再構築

このままだとGemfileに変更を加えた場合、新しいnode_modulesを追加した場合に、Dockerの再構築が必要になります。 volumesを追加してbundle installとyarn installした結果を永続化するようにしましょう。

Dockerfileを修正します。

Dockerfile
 RUN bundle install

+COPY package.json yarn.lock ./
+RUN yarn install
+
 COPY . /myapp

 # Add a script to be executed every time the container starts.

docker-compose.ymlを修正します。

docker-compose.yml
     command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
     volumes:
       - .:/myapp
+      - bundle:/usr/local/bundle
+      - node_modules:/myapp/node_modules
     ports:
       - "3000:3000"
     depends_on:
       - db
+volumes:
+  bundle:
+  node_modules:

Dockerfileとdocker-compose.ymlを編集したので、再度buildします。

$ docker-compose build

これでdockerを使用してRailsアプリケーションを作成する準備ができました。

ここまでのコード

https://github.com/ihatov08/mercari_clone/tree/docker-compose

pecoの導入

pecoの導入

pecoの導入 標準入力されたデータをインクリメンタルサーチをして選択したら出力するコマンドです。 linuxのhistoryと組み合わせるとコマンド実行が楽になるので導入しましょう。 バイナリファイルの取得 pecoのバイナリファイルをwgetコマンドで入手します。 $ cd ...

開発環境の構築

開発環境の構築

開発環境の構築 メルカリクローンを開発するための開発環境を構築していきます。 cloud9のセットアップ 今回は開発環境構築の複雑さを避けるためにAWS cloud9を使用します。 AWS Cloud9はGitやDockerなどWebアプリケーション開発環境の構築に必要なソフトウ...

はじめに

はじめに

はじめに この本ではメルカリのようなフリマwebアプリケーションの作り方を学んでいきます。 メルカリのようなWebアプリケーションが作れるようになれば、 Airbnbやクラウドワークスなどの他のシェアリングエコノミーWebアプリケーションも応用して作れるようになります。 またフリ...

エンジニアとしてフルリモートワークで8年生き残るための技術スタック

エンジニアとしてフルリモートワークで8年生き残るための技術スタック

こんにちは。吉田智哉です。 岩手県盛岡市に住みながらエンジニアとしてフルリモートワークで東京の開発案件を請けてます。 気が付くとこの働き方で8年間も経過していました。 8年生き残ることができた技術スタックをシェアしたいと思います。 今までの8年間で、これから先はどうなるかわかりま...