20200215のdockerに関する記事は9件です。

Podman(Docker互換のコンテナエンジン)で作成したDockerFileをDockerHubのDockerイメージとして保存する

概要

本書ではDocker互換のコンテナエンジンであるPodmanを使用し、DockerFileを作成します。その後、Github経由でPodmanからDockerHubにDockerイメージとして保存します。

前提条件

  • DockerHub,GitHubのアカウントを作成していること。
  • CentOS8をインストールしていること。
  • 本書ではWindows 10 Pro (Hyper-V)を使用します。
  • 本書では podman-docker パッケージをインストールします。
  • Podmanのインストールについてはこちらをご覧ください。リンク先

0.主な流れ

  1. PodmanでDockerFileを作成する。
  2. PodmanでDockerFileを検証する。
  3. GitHubにDockerFileを上げる。
  4. DockerHubにてGitHub上のDocerFileからDockerイメージを作成する。

1. GitHubの設定

0章の3,4のように、3章で作成するDockerFileをGitHubに上げる必要があります。その為、GitHub上でリポジトリ(repository)を作成してください。

2. DockerHubの設定

  1. ブラウザからDockerHubに移動し、ログインする。
    dockerhub_001.JPG

  2. 上部メニューから「Repositories」をクリックする。
    dockerhub_002.JPG

  3. 「Create Repository」をクリックする。
    dockerhub_003.JPG

  4. 下記の内容を入力し、「Create」をクリックする。

    • リポジトリ名
    • 説明
    • Visibillity : PublicかPrivateのどちらかを選択
    • Build Setting : GitHubを「Connected」にする。(GitHubの認証画面が表示されます) dockerhub_004.JPG
  5. リポジトリが作成されたことを確認する。
    dockerhub_005.JPG

  6. 上部メニューの「Builds」をクリックする。
    dockerhub_007 - コピー.JPG

  7. 「Link to GitHub」をクリックする。
    dockerhub_007.JPG

  8. 下記の内容をクリックし、「Save」をクリックする。

    • SOURCE REPOSITORY : リポジトリ名
    • AUTOTEST : Internal and External Pull Requests
    • Autobulid : ON
    • Build Caching : ON dockerhub_008.JPG
  9. 「Build Activity」の画面が表示されたことを確認する。
    dockerhub_009.JPG

3. DockerFileの作成

  1. 5章でGitHubに上げるために、リポジトリ専用のディレクトリを作成する。

    $ mkdir [ディレクトリ名]
    $ cd [ディレクトリ名]
    
  2. DockerFileをエディターにて作成する。例として本書ではviで作成する。

    $ vi DockerFile
    
  3. エディターにてDockerFileを作成する。例として本書では下記のようにDockerFileを作成した。

    FROM centos:8
    LABEL maintainer="yuichi1992"
    RUN dnf -y install mariadb mariadb-server
    RUN dnf -y install httpd
    RUN echo "test-page" > /var/www/html/index.html
    RUN systemctl enable mariadb
    RUN systemctl enable httpd
    
  4. 作成したDockerFileを保存する。(viではコマンドモードで:wq)

4. DockerFileの検証

  1. DockerFileをDockerImageに変換する。

    $ docker build ./ -t [名前]
    
  2. エラーが発生せずにコマンドが実行できたことを確認する。

  3. DockerFileから生成したDockerImageを確認・使用する。

    $ docker images
    $ docker run -t -i [イメージID] /bin/bash
    
    コンテナ内にてmariadb,httpdがインストールされているか確認
    $ rpm -qa | grep maria
    $ rpm -qa | grep httpd
    $ cat /var/www/html/index.html
    

5. GitHubにDockerFileを上げる

  1. 下記のコマンドを実行し、DockerFileをGitHubに上げる。

    $ git init
    $ git add .
    $ git commit -m "First Commit"
    $ git remote origin [リモートリポジトリ名]
    $ git push -f origin master
    
  2. GitHubに移動し、DockerFileが上がっていることを確認する。
    dockerhub_010.JPG

6. DockerHubの確認

  1. ブラウザにてDockerHubに移動し、リポジトリのメニューから「Builds」をクリックする。
    dockerhub_007 - コピー.JPG

  2. 「Automated Builds」にてGitHubのDockerFileが認識されていることを確認する。その後、「Trigger」をクリックする。
    dockerhub_011.JPG

  3. 「PENDING」と表示されるので待機する。
    dockerhub_013.JPG

  4. 「SUCCESS」と表示されたことを確認する。
    dockerhub_015.JPG

  5. 上部メニューの「Tags」をクリックする。
    dockerhub_018 - コピー.JPG

  6. Dockerイメージが生成されたことを確認する。
    dockerhub_018.JPG

最後に

Podmanを使用しDockerHubにDockerFileを上げることで、DockerHubにDockerイメージが保存されます。これによって他端末にDockerをインストールすることで、DockerHubで保存したDockerイメージを使用することができます。保存したDockerイメージは同一の環境なので、検証用の使い捨て環境などとして利用することができます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker run -p で、ホスト側のポート番号が被ったらどうなるか

最近会社で、聞かれていないけれど答えることになるかもしれないことをまとめてみました。

"docker run -p" でポート公開しているホスト側のポート番号が、複数のコンテナ間で被ったらどうなるか、です。

この程度のことなら、実験するのが手っ取り早いです。

実験環境

ホストには、VirtualBox上の "Lubuntu 18.04.4" を用いています。この環境に "Docker 19.03.6" をパッケージインストールし、これを実験環境としています。

Dockerのインストール方法には "Ubuntuにdockerをインストールする" の "リポジトリからインストール" を使用しました。

実験

まずは実験用コンテナのベースイメージを取得します。
今回はCentOSを使用しました。

$ docker pull centos
     :
$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
     :
centos              latest              470671670cac        4 weeks ago         237MB
     :
linuser@linuser:~$

上記のイメージをベースにコンテナAを起動します。
起動時のオプション指定で、コンテナのポート22をホストのポート10022に割り当てます。

$ docker run -it --rm -p 10022:22 --name test_a centos

CentOSの起動直後の状態です。
コンテナ内でsshdを実行していません。
これは、コンテナ内のポート使用状況を見れば分かります。

[root@4bd739598429 /]# ss -lntp
State               Recv-Q                 Send-Q                                  Local Address:Port                                 Peer Address:Port
[root@4bd739598429 /]#

コンテナAが稼働中の状態で、コンテナ名だけ変更した同じコマンドを用いて、コンテナBを実行します。

$ docker run -it --rm -p 10022:22 --name test_b centos
docker: Error response from daemon: driver failed programming external connectivity on endpoint test_b (7ad7dfd88f361777e6147b65d38e7fd585abce640b70ce180ba8b7406ea30709): Bind for 0.0.0.0:10022 failed: port is already allocated.
ERRO[0000] error waiting for container: context canceled
$

まあ予想通りです。
ポート10022への "bind" の失敗により、コンテナBの起動に失敗しました。

ホストの状態

このとき、ホストはどのようになっているでしょうか?
もう少し、ポートの競合の状況を見ていきましょう。

まず、LISTENしているポートはこのような感じです。但し、Dockerに関係のない部分は省いて表示しています。

# ss -lntp
State   Recv-Q   Send-Q      Local Address:Port       Peer Address:Port
     :
LISTEN  0        128                     *:10022                 *:*       users:(("docker-proxy",pid=3171,fd=4))
     :
#

このように、コンテナAのサービスが稼働していなくても、ポート転送オプションに伴うホスト上でのLISTENが行われています。
LISTENしているプロセスは、docker-proxyと呼ばれるプロセスのようです。
同じことはコンテナBでも起こります。
ホスト上で同一ポート10022でのLISTEN(bind)を試みることになるため、競合が起こるわけです。
そのため、コンテナの起動は行われません。

これらの事情は、コンテナの外で発生しています。
つまり、コンテナ内のsshサーバープロセスの稼働停止に依存しません。

もう一つ見ておきましょう。iptablesの設定状況です。

# iptables -t nat -L -n --line-numbers
    :
Chain DOCKER (2 references)
num  target     prot opt source               destination
1    RETURN     all  --  0.0.0.0/0            0.0.0.0/0
2    DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:10022 to:172.17.0.2:22
#

最後のエントリが、コンテナAへのポート転送に伴うエントリです。
ポート番号10022に到着したパケットが、コンテナA(172.17.0.2)のポート番号22に送られるのが分かります。

このあたりのことは、公式ドキュメントにも少し記載されています。

まとめ

  • コンテナ内のサーバープロセスの稼働停止にかかわらず、ホスト側のポートが被るようなコンテナ複数を起動することはできない。
  • Dockerコンテナのポートの外部公開は、コンテナ内のサーバープロセスの稼働停止に依存しない。
  • Dockerコンテナのポートの外部公開は、プロセス"docker-proxy"とiptablesが協調して行っている。
  • プロセス"docker-proxy"は、ホスト側のポート待ち受けを担っている。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker+React 環境構築手順

自分用メモとしてDocker+Reactの環境構築テンプレを書いときます。

ディレクトリ内にアプリを作成

create-react-app アプリ名
cd アプリ名

Dockerfile

アプリの内に作る

# base image
FROM node:10.16.3-alpine

# set working directory
WORKDIR /app

# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH

# install and cache app dependencies
# COPY package.json /app/package.json
RUN npm install --silent
RUN npm install react-scripts@3.0.1 -g --silent

# start app
CMD ["npm", "start"]

docker-compose.yml

アプリ内に作る

version: '3.7'

services:

  アプリ名:
    container_name: アプリ名
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - '.:/app'
      - '/app/node_modules'
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=development

コンテナ起動

docker-compose up -d --build

localhost:3000にアクセスして問題なければおk。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(備忘)Dockerを使ってRStudio環境を構築する

はじめに

最近、Twitterで大変参考にしているデータサイエンティストさんがいる。
そのデータサイエンティストさんがブログにて開催(?)しているデータサイエンティストになるための講座の一発目がDockerによる環境構築だった。

▼こちら
Docker超入門①〜Dockerってなに?〜【初心者向け】

超入門というだけあって、Dockerが何かから始まって、どう起動するかまで丁寧に説明してくださっている。ちなみにこの後、Python入門が始まっているので、データサイエンスに興味がある方は要チェック。

しかし、一回コンテナ構築しただけでは当然覚えるはずもない。
かといって、いくつもJupyter構築するのものなぁ…と思ったので、
Rによる優しい統計学」を使って勉強するのも兼ねて、RstudioをDocker上(ローカル)で動かしてみることにした。

結論から言うと、あまりにも簡単すぎたのだが、いくつか別サイトも参考にしたので、
今後のためにここにまとめておくことにした。

コマンド

※前提:Dockerインストール済であること

docker pull tokyo/rstudio
docker run -d -p 8787:8787 tokyor/rstudio

これだけ。
本当に。
(今振り返ると、なんであんなにググったのか意味わからないくらい一瞬だった)

pullするのはrocker/とか色々あるけれど、
とりあえず日本語環境があるtokyo/rstudioをpull。

その後

早速本を読み進めている。
私はPython派なので、本が終わったあとおそらくRは使わないので、
このままコンテナのみ破棄する予定。
それにしても便利だなぁ、Docker。

▼参考サイト
データ分析環境の構築にDockerを利用しよう
(3年も前の記事であることにびっくり…)
DockerでRの環境構築

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerコンテナでの設定ファイル生成にテンプレートとしてERBを使う

Dockerコンテナを起動する際に、環境変数で渡したパラメーターを使って設定ファイルを作りたいことがある。
例えばsambaにアクセスするとき、ユーザー名が foo なら許可、それ以外は不許可としたければ設定ファイルは以下のようにする。

[global]
        log file = /var/log/samba/%m

[share]
        path = /mount
        guest ok = no
        valid users = foo # ユーザー foo ならアクセスを許可する

このユーザー名を可変にしたいとしよう。Docker で docker run -e USER=foo -e PASSWORD=pass ... のようにしたいなら、以下のようになる。

Dockerfile

FROM ubuntu:latest

RUN apt update \
    && apt install -y \
    samba

COPY samba.sh /root/

EXPOSE 139 445

CMD ["/root/samba.sh"]

samba.sh

#!/bin/sh

# /etc/samba/smb.conf を生成する
cat <<SMBCONF >> /etc/samba/smb.conf
[global]
        log file = /var/log/samba/%m

[share]
        path = /mount
        guest ok = no
        valid users = $USER
SMBCONF

# システムに foo ユーザーを追加し、foo ユーザーとしてアクセスできるようにする
useradd $USER
cat <<PASSWORD | passwd $USER
$PASSWORD
$PASSWORD
PASSWORD
cat <<PASSWORD | smbpasswd -a -s $USER
$PASSWORD
$PASSWORD
PASSWORD

# samba サーバーを起動する
/usr/sbin/smbd -F -S --no-process-group

しかしこのファイル生成方法は、smb.conf のテンプレートがスクリプト中にあって気持ちが悪い。
こんなとき Ruby なら ERB が使えるのだが、インストールすると依存する複数のパッケージも入ってしまうし、テンプレートを使いたいだけなのにちょっと大げさだ。

# Ubuntu 19.10 の場合
$ root@f86b2af49215:/# apt install ruby
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  ca-certificates fonts-lato javascript-common libgdbm-compat4 libgdbm6 libjs-jquery libruby2.5 libyaml-0-2
  openssl rake ruby-did-you-mean ruby-minitest ruby-net-telnet ruby-power-assert ruby-test-unit ruby-xmlrpc
  ruby2.5 rubygems-integration unzip zip
Suggested packages:
  apache2 | lighttpd | httpd gdbm-l10n ri ruby-dev bundler
The following NEW packages will be installed:
  ca-certificates fonts-lato javascript-common libgdbm-compat4 libgdbm6 libjs-jquery libruby2.5 libyaml-0-2
  openssl rake ruby ruby-did-you-mean ruby-minitest ruby-net-telnet ruby-power-assert ruby-test-unit
  ruby-xmlrpc ruby2.5 rubygems-integration unzip zip
0 upgraded, 21 newly installed, 0 to remove and 23 not upgraded.
Need to get 7568 kB of archives.
After this operation, 31.9 MB of additional disk space will be used.
Do you want to continue? [Y/n]

Ruby には軽量版の mruby がある。
素の mruby のバイナリは Ubuntu 19.10 なら apt install mruby でインストールできるが、これには ERB がバンドルされておらず利用できないので、代わりに mitamae を使うことにする。
プロビジョニングツールであり ERB を使ってテンプレートから設定ファイルを生成し配置する機能をもともと備えているし、シングルバイナリで 2.28MB (v1.10.5の場合)とコンパクトなので、インストールも手間がかからない。

Dockerfile

FROM ubuntu:latest

RUN apt update \
    && apt install -y \
    samba

# mitamae の latest の URL を指定する。
# 最新版のバイナリへのリダイレクトを伴うためか、変更がなくとも docker build の度に毎回ダウンロードが走るので、気になる場合は指定バージョンの URL を使う。
ADD https://github.com/itamae-kitchen/mitamae/releases/latest/download/mitamae-x86_64-linux /root/mitamae
RUN chmod +x /root/mitamae

COPY samba.sh mitamae /root/

EXPOSE 139 445

CMD ["/root/samba.sh"]

samba.sh

#!/bin/sh

(cd /root && mitamae local setup.rb)
# mitamae にはユーザー追加機能も任意のコマンド実行機能もあるので、`passwd` `smbpasswd` も `setup.rb` に切り出してしまう。

# samba サーバーを起動する
/usr/sbin/smbd -F -S --no-process-group

setup.rb

# /etc/samba/smb.conf 生成
template "/etc/samba/smb.conf" do
  variables(user: ENV["USER"])
end

# ユーザー追加
user ENV["USER"] do
  password ENV["password"]
end

execute "Add a samba user" do
  command <<-COMMAND.gsub(/^ */, "")
    cat <<PASSWORD | smbpasswd -a -s #{ENV["USER"]}
    #{ENV["PASSWORD"]}
    #{ENV["PASSWORD"]}
    PASSWORD
  COMMAND
end

mitamae/templates/etc/samba/smb.conf.erb

[global]
        log file = /var/log/samba/%m

[share]
        path = /mount
        guest ok = no
        valid users = <%= @user %>

テンプレート部を別ファイルに切り出せた。

また mitamae 化の他の利点として、実行時にシステムへの変更がわかりやすく差分表示されることを記しておきたい。

パラメーターを JSON にしてみる

mitamae は JSON をパースできる。パラメーターを JSON で渡すことを考えてみる。

param = JSON.parse(ENV["SMB_PARAM"])
user = param["user"]

template "/etc/samba/smb.conf" do
  variables(user: user["name"])
end

user user["name"] do
  password user["password"]
end

execute "Add a samba user" do
  command <<-COMMAND.gsub(/^ */, "")
    cat <<PASSWORD | smbpasswd -a -s #{user["name"]}
    #{user["password"]}
    #{user["password"]}
    PASSWORD
  COMMAND
end
$ smb_param=$(cat <<PARAM
{
  "user": {
    "name": "foo",
    "password": "pass"
  }
}
PARAM

$ sudo docker run --rm -p 139:139 -p 445:445 -e SMB_PARAM="$smb_param"

コード量をそれほど変えることなく JSON に対応することができた。
これにより

  • パラメーターを階層化でき、追加や削除、環境変数の名前空間管理が楽 (プレフィックス付きの長い環境変数名にしなくていい)
  • 配列が扱える (上記の例だとユーザーを複数にするとき USER1, USER2, ... などとせず "user": [...] とできる)
  • 環境ごとにパラメーターをまとめて管理できる (それぞれの JSON ファイルを作ればいい)

などの利便性を得られる。

なお実装は nowlinuxing/docker-samba においてあるので、気になる方は参照されたし。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

2020年、改めて React に入門する

僕がはじめて React をさわったのは 2016 年の 3 月頃、まだ Version 0.14 くらいのときでした。

スプレッドシートやガントチャートなどのコンポーネントを 1 年くらいがっつり作り込み、

React スゴい!
さすが FB!
キミに決めた!

と意気込みましたが、その後バックエンド開発がメインになり1 、React からは完全に遠ざかってしまいました。

気が付けば 2020 年、Version はいつの間にか 16.12 とか。

TypeScript で書けるんだっけ?
React Hooks? なにそれ? おいしいの?
へぇー、componentWill〜は非推奨になるんだ。って一体なにがあった!?2

…と、気になることが山積みですw

TL;DR;

取り急ぎ、クリーンな環境で React アプリを起動してみます

$ docker run --detach --interactive --rm --name app --publish 3000:3000 node:12-alpine
$ docker exec app npx create-react-app app
$ docker exec --interactive --tty --workdir /app app npm start

ブラウザで開いてみましょう
http://localhost:3000
image01.gif

OK,
では一旦 ctrl + c でアプリを停止して、React アプリの開発を開始しましょう!

TL;DR; for the next step

$ docker exec app apk add curl git vim zsh zsh-vcs
$ docker exec app git config --global user.email "you@example.com"
$ docker exec app git config --global user.name "Your Name"
$ docker exec --workdir /app app git init
$ docker exec --workdir /app app git add -A
$ docker exec --workdir /app app git commit -m "Initial commit"
$ docker exec --workdir /root app curl --remote-name https://raw.githubusercontent.com/hysh8392/dotfiles/master/.zshrc
$ docker exec --interactive --tty --workdir /app app zsh

とりあえず、最低限必要なコマンドのみインストールします

Mac で開発する場合、本当は Docker Desktop for MacVisual Studio Code を組み合わせた開発が最強だと思うんですが、ホスト側の作業フォルダをコンテナにマウントするとパフォーマンスが激しく劣化する、という長年解決されていない問題があるため、vim を入れときますw

この問題はおそらく Visual Studio Code の神アプデ「VS Code Remote Development3で解決されるものと思われますが、この機能の検証は別の記事で書きたいと思います

そして開発へ…

それではいよいよ開発に入っていきましょう!

To be continued...笑

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker 基礎的なコマンド

目的

  • dockerのコンテナを扱う際の基礎的なコマンドを記載する

動いているコンテナの一覧を出力

  • 下記にコマンドを記載する。
  • CONTAINER IDに記載された内容がコンテナのIDとなる。

    $ docker ps
    >CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                  NAMES
    >08e5ce32dacf        httpd               "httpd-foreground"   11 minutes ago      Up 11 minutes       0.0.0.0:8080->80/tcp   serene_fermi
    

コンテナのストップ

  • 下記にコマンドを記載する。

    $ docker stop コンテナID
    

コンテナのスタート

  • 下記にコマンドを記載する。

    $ docker start コンテナID
    

コンテナの削除

  • 下記にコマンドを記載する。

    $ docker rm コンテナID
    

イメージの一覧を出力

  • 下記にコマンドを記載する。
  • REPOSITORYに記載されたものがイメージとなる。

    $ docker images
    >REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    >httpd               latest              c562eeace183        12 days ago         165MB
    

イメージの削除

  • 下記にコマンドを記載する。
  • 本コマンドは$ docker stopを行わないと実行できない。

    $ docker image rm イメージ名
    

コンテナが削除され現在使用されていないイメージの全削除

  • 下記にコマンドを記載する。

    $ docker images prug
    
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker コンテナ内のrailsコマンドが呼び出せなくなったのでメモ

概要

docker環境で、
railsチュートリアルを進めていたら、
急に下記のようにrailsコマンドが呼び出せなくなったので、
対処方法をメモ

bash: rails: command not found

環境

こちらの記事を参考にrailsのdocker環境を構築
https://qiita.com/reflet/items/f73cac406760ee4ecc13

解決策

railsのDockerファイルに下記のようにパス通しを記載しrailsコマンドを呼び出せるようにした。

ENV PATH $PATH:/usr/local/src/bin

そもそもコマンドって?

我々が普段使っているcdlsなどは、魔法でもなんでもなく、全てプログラム
このプログラムを呼び出すための略称がコマンドという認識で良いと思います。

自分は、元々windowsユーザなのですが、Windowsユーザだと
exeファイルがイメージし易いかと思います。
C言語とかで、コマンドプロンプトにHelloWorldと表示するhellow.exeファイルを作成して、
hellow.exeをダブルクリックするとコマンドプロンプトが開きHelloWorldと表示されます。
lsコマンドだったらls.exeをダブルクリックしたら、ファイルのリストがコマンドプロンプト上に表示されるそんなイメージで自分はいます。
間違ってたらすみません。。。。

パスって?

コマンドが、プログラムということがわかりましたが、
パソコンは、そのプログラムが何処にあるか知りません。
hellow.exeがどのファイルに存在するのかパソコンは理解できないわけです。
そこで、PATHという環境変数に、コマンドは、このパスの配下にあるプログラムだよ
と教えてあげることで、パソコンが、どのファイルの配下にhellow.exeがあるか理解できるという仕組みです。
これが俗にいうパスを通すというやつです。

小学生の時に友人から、インストールって本質的には、パスを通すことなんだよって
言われて、その時は、何が何だかって感じでしたが、今となっては、なるほどって感じです。

環境変数って?

お使いのMacやWindowsに設定されている、変数です。
パソコンに設定されているもや、ログインしているユーザごとに設定されている変数もあります。

後書き

何故急にコマンドが呼び出せなくなったのか不明ですが、
コマンドってなんだっけパスとかなんだっけというLinuxの基礎知識を得るいい機会でした。

何か、間違ってることありましたら、優しくご指摘いただけますと幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【 Docker+Nginx+Django+RDS】WEBアプリができるまで⑪本番環境へデプロイ+色々手直し

前置き

独学で、子供の成長アプリを作った時のことを、記録として残していきます。
間違っているところなどあれば、ご連絡お願いします。
 ①Djangoのようこそページへたどり着くまで
 ②NginxでDjangoのようこそページへたどり着くまで
 ③カスタムユーザーを作ってadminにたどり着く
 ④ログインログアウトをしよう
 ⑤ユーザー登録(サインイン)機能を作ろう
 ⑥ユーザーごとのデータ登録できるようにする〜CRU編
 ⑦ユーザーごとのデータ登録できるようにする〜削除編
 ⑧画像ファイルのアップロード
 ⑨身長体重を記録する@一括削除機能つき
 ⑩成長曲線グラフを描いてみよう
 ⑪本番環境へデプロイ+色々手直し<--最後です

Goal

本番環境(AWS EC2)へデプロイ
加えてデプロイするときに躓いたところを手直し。

アプリのバグ修正

これまでのコードだと、子供情報を登録する前に各データを参照すると
システムエラーになることがわかりました。以下のように直します。

*解説*
KidsProfile.objects.filter(user=user_name).first().id

ユーザー情報に紐づくKidsProfileが見つからなかった場合、
objects.filter()の場合、空クエリが返ってきます。
空クエリに対して「そのidを返せ」と言うので、AttributeErrorが返されます。
※objects.get()の場合、DoseNoteExistが返ってきます

それをtryで受け止めて、その場合はHTMLへの返却をNoneにします。
ついでに「子供情報を入れてね」とメッセージを添えます。

shoes/views.py
#靴リスト
@login_required
def shoes_data_list(request, **kwargs):
    user_name = request.user
    try:
        if len(kwargs) > 0:
            kids_profile_id = kwargs["kidsProfileId"]
        else:
            kids_profile_id = KidsProfile.objects.filter(user=user_name).first().id

        kids_profiles = KidsProfile.objects.filter(user=user_name) #子供情報選択用
        kids_profile_name  = KidsProfile.objects.get(id=kids_profile_id).name
        shoes_data_posts = ShoesData.objects.filter(user=user_name, kidsProfile=kids_profile_id).order_by('buy_date')

    except AttributeError:
        shoes_data_posts = None
        kids_profiles = None
        kids_profile_name = "子供情報を登録してください"

    params = {
        'shoes_data_posts' : shoes_data_posts,
        'kidsProfiles' : kids_profiles,
        'kidsName' : kids_profile_name,
    }
    return render(request, 'shoes/shoes_data_list.html', params)

Githubへコードを上げる

Githubへの上げるためにやったことは、4つ。

1.setting.pyの分割
  このファイルにはSEACRET_KEYやRDSの情報が書いてあるので、
  Githubに上げられない。settings.pyからsettings_localをimportする形にして、
  .gitignoreで指定してあげる。

settings_local.py
SECRET_KEY = '*************'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': '*************',
        'PASSWORD': '*************',
        'HOST': '*************',
        'PORT': 5432,
    }
}
mysite/settings.py
import os
from .settings_local import *
(略)

2..gitignoreファイルの作成
http://gitignore.io
この変を参考にしながら設定。
migrations履歴は移動しないほうが良いらしい。
でも_init_.pyがないとmigrationで失敗するはずなので、本番へ持っていく。

.gitignore
*.log
*.pot
*.pyc
pycache/
src/mysite/settings_local.py
db.sqlite3


**/media/**
!**/media

**/migrations/**
!**/migrations
!**/migrations/__init__.py

3..gitignoreで/media/をgithubに上げないようにしたので、
  靴画像のデフォルト画像を/media/から/static/へ移動。
  staticにファイルを増やしたので、Collectstaticを実施。

4.uwsgiの設定見直し
  djangoはローカルで試しながら作るときはrunserverのほうが良い。
  その結果、コメントアウトで使い分ける形にしてみた。
  合わせて本番向けにはuwsgiの起動はiniファイルを読ませるように修正。

docker-compose.yml
version: "3"

services:



  db-postgres:
    image: postgres

# 本番デプロイ用定義
# 開発中は、こっちは全部コメントアウトするよ
  nginx:
    image: nginx:1.13
    ports:
      - "8000:8000"
    volumes:
      - ./nginx/conf:/etc/nginx/conf.d
      - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
      - ./static:/static
    depends_on:
      - web
  web:
    build: ./web
    volumes:
      - ./src:/code
      - ./static:/static
    depends_on:
      - db-postgres
    command: uwsgi --ini /code/mysite/uwsgi.ini #ここが②から変わってます
    expose:
     - "8000"


# 開発中定義
# 本番にあげるときはこっちをコメントアウトするよ
#
#  web:
#    build: ./web
#    volumes:
#      - ./src:/code
#      - ./static:/static
#    depends_on:
#      - db-postgres
#    command: python manage.py runserver 0.0.0.0:8000
#    ports:
#      - "8000:8000"
src/mysite/uwsgi.ini
[uwsgi]
socket = :8000
chmod-socket = 666
module = mysite.wsgi
wsgi-file = /code/mysite/wsgi.py
logto = /code/mysite/uwsgi.log
processes = 1
vacuum=True
max-requests=5000

あとは
・ローカルからGithubにpush
・EC2にGithubにpull
・EC2上でsetting_local.pyを作成

で、EC2上で、起動!

docker-compose up
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む