質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.81%

Dockerfileは本番環境・開発環境で全く同じファイルが使えるのでしょうか

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 269

具体的に知りたいこと

現在社内システム(Webアプリ)をDockerベースで本番運用しています。
開発から環境構築まで全て私一人で行いました。
アプリケーションのフレームワークにはDjangoを使用しており、
本番環境にはAWSのFargateを使用しています。
CodePipelineでCI/CD環境を構築しており、
GitHubのProductionブランチにマージされたことをトリガーにユニットテストの実行、
Fargateへのデプロイが自動的に行われます。

開発は一通り終了しているのですが、
ローカル環境で開発する際にDockerを使用していないことに問題意識を抱えています。
よく「Dockerを使えば本番環境と開発環境が同じものになるから、環境差によるバグがかなり抑えらえる」
と聞きますが、その恩恵を受けていない状態です。

そもそも本番用のDockerfileはローカル環境でビルドすることができない作りになっています。
その理由はビルド時にDB(RDS)接続を行うが、ローカル環境から本番DBには繋がらないためエラーとなるからです。

ローカルでビルドする際はdocker build時に--build-argコマンドを使って何かしらの値を渡し、
Dockerfile内で本番とローカルでDBの接続先を変えるような処理をする必要があるのでしょうか。
もしくは、まったく同じDockerfileを本番と開発で使うという考え自体誤っているのでしょうか。
社内にコンテナに精通しているエンジニアが居ないため質問させていただきました。
恐れ入りますが、ご回答宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

そもそも本番用のDockerfileはローカル環境でビルドすることができない作りになっています。

まず、ビルドされるコンテナは本番用と開発用で同じものを使うようにしましょう。そのためには、ビルド時ではなくコンテナの起動時のオプションで本番用と開発用の動きを切り替える必要があります。起動時のオプションで環境変数に接続先データベースを指定するのが常套手段です。
起動時のオプションを毎回指定したり、担当者間で共有するのが大変なので、 docker-compose を使うのがおすすめです。

https://qiita.com/nokonoko_1203/items/242367a83c313a5e46bf

を参考にデータベースの接続先を環境変数で切り替えるようにしてください。そのうえで、
docker-compose.yml を本番用と開発用を作ると良いでしょう。
本番用の docker-compose.yml では、接続先データベースに本番用を指定し、開発用の docker-compose.yml では、参考サイトのようにデータベースもコンテナを使用し、接続先データベースにそのコンテナ名を指定すると良いと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/09/02 11:06

    ご回答ありがとうございます。
    参考にさせていただきます。

    私が構築した環境の都合上、どうしてもビルド時にDB接続まで行う必要あります。
    理由としては、CodeBuild時にDockerfileのビルド、ユニットテストをしたいのですが、ユニットテスト時にはDBに接続する必要があるからです。
    そのためビルド時の起動オプションで開発と本番を切り分ける手法があればそれを使いたいのですが、それだと何か問題はあるでしょうか。

    キャンセル

  • 2020/09/02 19:36

    時間ができたので参考記事を見させていただいたのですが、この記事ではdocker-compose.ymlだけではなくDockerfileも本番用・開発用と二つ用意しているように見えます…。

    >ビルドされるコンテナは本番用と開発用で同じものを使うようにしましょう。
    とのことですが、結局のところDockerfileは本番用・開発用の二つ用意する必要があるという理解で良いのでしょうか。

    キャンセル

  • 2020/09/03 11:19

    > 結局のところDockerfileは本番用・開発用の二つ用意する必要があるという理解で良いのでしょうか。

    いえ、その必要はないはずです。具体的には

    DATABASES = {
    'default': {
    'ENGINE': os.environ.get('DATABASE_ENGINE', 'django.db.backends.sqlite3'),
    'NAME': os.environ.get('DATABASE_DB', os.path.join(BASE_DIR, 'db.sqlite3')),
    'USER': os.environ.get('DATABASE_USER', 'user'),
    'PASSWORD': os.environ.get('DATABASE_PASSWORD', 'password'),
    'HOST': os.environ.get('DATABASE_HOST', 'localhost'),
    'PORT': os.environ.get('DATABASE_PORT', '5432'),
    }
    }

    というように os.environ.get を使うことで具体的な接続先情報を環境変数から取得しています。こうしておいて、 docker-compose.yml に

    environment:
    # 1ならデバックモード
    - DEBUG=1
    - SECRET_KEY=hoge
    - DATABASE_ENGINE=django.db.backends.postgresql
    - DATABASE_DB=django_db
    - DATABASE_USER=django_db_user
    - DATABASE_PASSWORD=password1234
    - DATABASE_HOST=postgres
    - DATABASE_PORT=5432

    のように指定しています。本番環境用の docker-compose.yml と開発用 docker-compose.yml で別の接続先を指定できると思いますが、いかがですか?

    キャンセル

  • 2020/09/14 12:07 編集

    教えていただいた方法と全く同じではないのですが、以下の手法でクリアしました。

    [前提]
    Dockerfileは本番・開発で同じものを使用
    docker-compose.ymlは開発環境のもの一つのみ用意
    シークレットな情報はdocker build時に引数として渡し、Dockerfileではそれら情報をイメージの環境変数として焼いてしまう

    ★開発環境
    docker-compose.ymlに以下の内容を記述して実行
    args:
    - SECRET_KEY=hoge
    - DATABASE_ENGINE=django.db.backends.postgresql
    - DATABASE_DB=django_db
    - DATABASE_USER=django_db_user
    - DATABASE_PASSWORD=password1234




    [本番環境]
    AWSマネジメントコンソールからCodebuild設定画面より環境変数で本番用のシークレットな情報を設定
    前手順で設定したCodebuild環境変数をCodebuildでdocker buildコマンド実行時に引数で渡す



    イメージにシークレットな情報を焼くと、誤ってdocker pushしてしまった時にシークレットな情報が公開されてしまう可能性が有るためNGパターンとする記事もありましたが、以下理由により今回は採用しました
    ・GitHubにプッシュ後のDockerbuild~デプロイまでの流れは完全自動化されており、人の手によって誤って本番用のイメージがパブリックなリポジトリにpushされるようなタイミングは無い
    ・Codebuild時にユニットテストを実行する必要があり、テストは本番環境と同じ環境で実行したいので、Dockerbuild内のコマンドでDB接続とユニットテスト実行までできるのが理想だった

    アドバイスいただきありがとうございました。

    キャンセル

0

Dockerfileの書き方次第ですが、よくあるのは環境変数で切り替える方法です。
この記事の環境変数の部分などが参考になると思います。
DockerでDjangoの開発環境を再構築!!!!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/09/02 19:37

    ご回答ありがとうございます。
    参考記事読ませていただきました。

    もう一人の回答者の方への返信と内容が重複してしまうのですが、
    結局のところDockerfileは本番用・開発用の二つ用意する必要があるという理解で良いのでしょうか。

    キャンセル

  • 2020/09/02 19:48

    参考記事ではDockerfileは共通で、envファイルが各環境毎になっていませんか?

    キャンセル

  • 2020/09/03 20:51

    大変失礼しました。参考としてあげてくださった記事の元記事を見ていたようです。
    申し訳ないです。

    記事を読み実際に私の環境に手を加えていたのですが、今一つ私のやりたいことがかなわない状況です。

    ・nginxは使用せずDjango標準の開発サーバー(runserver)を使用してデバッグしたい
    ・IDE(PyCharm Pro)からローカルで起動したコンテナ内のインタープリタとリモートインタープリタで接続し、ブレイクポイントやウォッチ式等使用しながらデバッグしたい

    上記2点もクリアしたいと考えているのですが、追加でご助言いただけないでしょうか。

    キャンセル

  • 2020/09/03 21:59

    そうなると当初の質問と異なり開発環境と本番環境で構成が異なるのでDockerfileは別々になります。
    PyCharmならDocker連携してデバッグできるので以下の解説が参考になると思います。
    https://pleiades.io/help/pycharm/using-docker-compose-as-a-remote-interpreter.html

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.81%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る