LoginSignup
1
2

Dockerfileとdocker-composeでウェブページをデプロイする

Posted at

1. やりたいこと

git cloneしてdocker compose upしたらデプロイできるようにしたい

2. どうやって実現するか

以下をフォルダに置いてdocker compose upするだけです

・ソースコード
・Dockerfile
・docker-compose.yml

3. 試行環境

以下の記事で作った環境で実行しています
ホスト: Windows10
実行環境: WSL2 Ubuntu-22.04

4. 前提知識

4-1. Dockerfileの書き方

Dockerfileはdockerイメージ1つ分のビルド指示を書くファイルです
以下のコマンドでdockerイメージをビルドするときの指示を書けます

FROM:       ベースとするdockerイメージとバージョンを指定します (ubuntu:latestなど)
WORKDIR:    RUNなどのコマンドを実行するワーキングディレクトリを指定します
RUN:        dockerイメージビルド時にdockerのterminalからコマンドを実行します
COPY:       dockerイメージビルド時にホストからdockerにフォルダやファイルをコピーします
ADD:        dockerイメージビルド時にホストからdockerにフォルダやファイルをコピーします
VOLUME:     ホストのフォルダやファイルをdockerイメージにマウントします
EXPOSE:     コンテナがアクセスを許可するポートを書きます
ENV:        環境変数を登録します
ENTRYPOINT: コンテナを起動する際に実行するコマンドを指定します
CMD:        コンテナを起動する際に実行するデフォルト引数を指定します

FROMで指定するdockerイメージはdocker hubにある公式のイメージを利用することが多いと思います。COPYとADDは似てますがADDは圧縮ファイルを解凍してからコピーするのに対し、COPYはそのままコピーします。ENTRYPOINTとCMDも似てますが、CMDはdocker runするときに引数を指定することで変更されるのに対して、ENTRYPOINTは必ず実行されるコマンドであるという違いがあるようです

Dockerfileについての公式ドキュメントは以下にあります

4-2. docker-compose.ymlの書き方

docker-compose.ymlにはdockerコンテナを起動するときの条件を書いておきます。複数Dockerfileを指定して複数のコンテナを同時に起動することもできますのでフロントエンド、バックエンド、DBとまとめて起動する場合も1ファイルにまとめて書いて、docker compose upするだけでまとめて起動することができます

services:
  コンテナ名:
    image: "イメージ名"
    ports:
      - "ホスト側のポート:コンテナのポート"
    volumes:
      - ホスト側のパス:コンテナのパス
    environment:
      環境変数名: 環境変数値
  コンテナ名:
    build: Dockerfileのパス 
    ports:
      - "ホスト側のポート:コンテナのポート"
    volumes:
      - ホスト側のパス:コンテナのパス
    environment:
      環境変数名: 環境変数値
    depends_on:
      - コンテナ名

portsの書き方についてはこの記事が詳しいです

4-3. 起動する方法

docker-compose.ymlの内容を実行するにはdocker compose upします

terminal
docker compose up

--buildオプションを付ければ既にイメージがある状態でもビルドからやり直してくれます

terminal
docker compose up --build

4-4. 起動中のdockerコンテナへの接続

以下のコマンドで起動しているコンテナのterminalにアクセスできます

terminal
docker exec -i -t CONTAINER_ID /bin/bash

コンテナIDは以下で確認できます

terminal
docker container ls

上手く動かないときにはこれでterminalに入って確認すると良いと思います

5. 静的サイトをデプロイする

ファイル構成は以下のようにしました

5-1. Dockerfile

静的サイトなのでベースイメージにはhttpd:latestを使いたいと思います
htmlをhtml名のフォルダに入れる想定で、COPY欄にフォルダ内の内容をドキュメントルートにコピーするように設定しました

Dockerfile
FROM httpd:latest
COPY ./html/ /usr/local/apache2/htdocs/

5-2. docker-compose.yml

docker-compose.ymlでは上記Dockerfileをbuildして、ポートはdockerコンテナ内で80番のポートを80番のポートとするように設定しました

docker-compose.yml
version: "1"
services:
  web:
    build: .
    ports: 
      - "80:80"

後は表示したいhtmlファイルを書いたら完成です

html/index.html
<html>
    <head>
        <title>ページ</title>
        <link rel="icon" href="data:,">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">
        <meta name="viewport" content="width=device-width">
    </head>

    <body>
        ほげほげ
    </body>
</html>

5-3. 起動

あとはこのフォルダでdocker compose upすれば起動できます

terminal
$ docker compose up
[+] Running 1/0
 ✔ Container test2-web-1  Recreated                                                                                0.0s
Attaching to web-1
web-1  | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.18.0.2. Set the 'ServerName' directive globally to suppress this message
web-1  | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.18.0.2. Set the 'ServerName' directive globally to suppress this message
web-1  | [Sun Jan 21 14:56:31.806008 2024] [mpm_event:notice] [pid 1:tid 140235577243520] AH00489: Apache/2.4.58 (Unix) configured -- resuming normal operations
web-1  | [Sun Jan 21 14:56:31.806069 2024] [core:notice] [pid 1:tid 140235577243520] AH00094: Command line: 'httpd -D FOREGROUND'
web-1  | 172.18.0.1 - - [21/Jan/2024:14:56:34 +0000] "GET / HTTP/1.1" 200 357
web-1  | 172.18.0.1 - - [21/Jan/2024:14:57:26 +0000] "-" 408 -

ブラウザでlocalhostを開くと表示されている筈です

6. ビルドしたSPAをデプロイする

VueやReactで作ったSPAアプリはビルドしてあれば静的サイトと同じなので、デプロイ時にやることも静的サイトと同じです

6-1. Vueプロジェクトを準備する

node.jsが入っている環境で以下を実行するとVueのプロジェクトが作成されます

terminal
npm install vue
npm init vue@latest

以下でビルドします

terminal
npm run build

6-2. ファイル構成と手順

Dockerfileとdocker-compose.ymlを追加してフォルダ構成は以下のようにしました

6-3. Dockerfile

Dockerfile
FROM httpd:latest
COPY ./myapp/dist/ /usr/local/apache2/htdocs/

6-4. docker-compose.yml

docker-compose.yml
services:
  web:
    build: .
    ports: 
      - "80:80"

6-5. 起動する

あとはこのフォルダでdocker compose upすれば
http://localhost にVueアプリが待機します

7. Djangoで作った動的サイトをデプロイする

次はDjangoでつくった動的サイトをデプロイしてみましょう

7-1. Djangoプロジェクトをつくる

Python + Djangoが入っている環境で以下を実行すればプロジェクトの最小構成が作成されます

terminal
django-admin startproject mysite

requirement.txtを以下で作成します
以下で書き出す場合は必要なパッケージがすべてpipで入っている必要がありますので、condaなどを併用してる方はpipreqsを使うのが良いようです

terminal
python -m pip freeze > requirements.txt

7-2. ファイル構成と手順

Dockerfileとdocker-compose.ymlを追加してフォルダ構成は以下のようにしました

やらなければならない手順は以下になります

  1. apache2をインストールする
  2. mod-wsgiをインストールする
  3. pythonをインストールする
  4. djangoをインストールする
  5. apache2の設定ファイルにdjango, mod-wsgiの設定を追加する
  6. ソースコードをマウントする

7-3. apache2の設定ファイル

apache2の設定に追加する内容は以下のようにしました。Django公式のドキュメント通りにpythonのパスやDjangoプロジェクトのパスを指示してやります

apache_django.conf
ServerName localhost:80
WSGIScriptAlias / /var/web/mysite/html/mysite/wsgi.py
WSGIPythonPath /var/web/mysite/html

<Directory /var/web/mysite/html/mysite>
  <Files wsgi.py>
    Require all granted
  </Files>
</Directory>

Alias /static/ /var/web/mysite/html/static/
<Directory /var/web/mysite/html/static>
  Require all granted
</Directory>

7-4. Dockerfile

Djangoの公式イメージがdeprecatedになって、代替イメージとしてUbuntuを使うように書かれていますのでUbuntuでやってみたいと思います

Dockerfile
FROM ubuntu

# アップデート
RUN apt-get update

# apache2, python, mod-wsgiをインストールする
RUN apt-get install -y apt-utils vim curl apache2 apache2-utils apache2-dev
RUN apt-get -y install python3 libapache2-mod-wsgi-py3
RUN ln /usr/bin/python3 /usr/bin/python
RUN apt-get -y install python3-pip

# pythonにdjangoをインストールする
RUN pip install --upgrade pip
RUN pip install django ptvsd

# pythonにmod-wsgiをインストールする
RUN pip install mod_wsgi mod-wsgi-httpd

# apacheの設定ファイルにmod-wsgiの設定を追加
COPY ./apache_django.conf /etc/apache2/sites-available/apache_django.conf
RUN a2ensite apache_django.conf

# Djangoソースコードをマウント
VOLUME ./web/mysite ./var/web/mysite

EXPOSE 80
CMD ["apache2ctl", "-D", "FOREGROUND"]

7-5. docker-compose.yml

あまりビルドし直したくないのでvolumesでソースコードをマウントしていますが、毎回docker compost up --buildするのであればDockerfileのCOPYでコピーするのでも良いと思います

docker-compose.yml
services: 
  django-apache2:
    build: .
    container_name: django-apache2
    ports:
      - '80:80'
    volumes: 
      - ./web/mysite:/var/web/mysite/html

7-6. 起動する

あとはこのフォルダでdocker compose upすれば
http://localhost にDjangoウェブアプリが待機します

まとめ

フォルダでdocker compose upするだけでデプロイできるようにしました。フォルダの内容をGithubにpushしておけば、git cloneしてdocker compose upするだけでデプロイできる筈です

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2