Dockerとgithubを使って上手く行かないときは前回の状態に戻りながらDjangoのチュートリアルを進める

#目的
Djangoの学習のためにチュートリアルを行っていたのですが、途中でエラーが出て何を間違ったか分からなくなり、チュートリアルをある程度進めたにも関わらずチュートリアル1に戻ってやり直す、ということを何回も繰り返していました。
そこでDockerとgithubを利用してログを残しながら、失敗したときは前回の状態に戻りながらチュートリアルを進めました。
そうすることでようやく最後まで行きつくことができました。
そのときの記録を残しておこうと思います。

Django、Docker、githubともに初心者でして手探りで進めたので、最適な使い方ではないと思いますが、ご了承ください。
$ のところはホスト側の作業、#のところはコンテナ内の作業です。
githubのアカウントやリポジトリの作成等の手順については省略して記載しています。

#環境
UbuntuとDockerのバージョンは以下の通りです。

```shell-session

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"
$
```


```shell-session
$ docker version
Client:
 Version:      17.05.0-ce
 API version:  1.29
 Go version:   go1.7.5
 Git commit:   89658be
 Built:        Thu May  4 22:10:54 2017
 OS/Arch:      linux/amd64
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.29/version: dial unix /var/run/docker.sock: connect: permission denied
$
```

#手順
##Dockerインストール
[こちら](http://qiita.com/koara-local/items/ee887bab8c7186d00a88)を参考にしました。

```shell-session
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates
$ sudo apt-key adv \
                --keyserver hkp://ha.pool.sks-keyservers.net:80 \
                --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
$ echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list
$ sudo apt-get update
$ sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
$ sudo apt-get install docker-engine
$ sudo service docker start
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

$ sudo systemctl enable docker

```

##初回Docker Image作成
Google先生にDocker Fileの作成方法を教えてもらいながら、作成しました。Djangoとgitが入っています。
※api-aiを使ってWebアプリケーションを作りたかったので、合わせてインストールしてますが、Djangoのチュートリアルだけであれば不要です。

```shell-session
$ vi Dockerfile
$ cat Dockerfile
FROM ubuntu:latest

RUN apt-get update
RUN apt-get install apt-file -y
RUN apt-file update
RUN apt-file search add-apt-repository
RUN apt-get install software-properties-common -y
RUN add-apt-repository ppa:jonathonf/python-3.6 -y
RUN apt-get update
RUN apt-get install openssh-server wget python3.6 vim git -y
RUN apt-get install python-pip -y
RUN pip install --upgrade pip
RUN pip install apiai
RUN pip install requests
RUN apt-get install python-django -y
RUN pip install django==1.10
RUN django-admin startproject mysite
RUN cd /mysite && python manage.py startapp polls
RUN git init
RUN git config --global user.name "r-takebayashi"
RUN git config --global user.email r-takebayashi@xxxxxx.xx.xx
RUN git remote add origin https://github.com/r-takebayashi/api-ai
RUN touch .gitignore && echo *.pyc >> .gitignore && echo *.sqlite3 >> .gitignore
EXPOSE 8000
CMD python /mysite/manage.py runserver 0.0.0.0:8000
$
```

###Dockerイメージのビルド

```shell-session
$ sudo docker build -t api-ai-image .
```


```shell-session
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
api-ai-image        latest              73e26c58272d        2 minutes ago       820MB
ubuntu              latest              f7b3f317ec73        2 weeks ago         117MB
hello-world         latest              48b5124b2768        3 months ago        1.84kB
$
```

###Dockerコンテナの起動

```shell-session
$ sudo docker run -p 8000:8000 -d api-ai-image
4448fad06ebe087191cff6492150bf1329c86d4596c1371a976269a1beae8840
$
```
コンテナにログインするには
sudo docker exec -it 444 /bin/bash
といった形でコマンドを実行します。

###gitでDjangoのディレクトリをaddしてpush

```shell-session
# git add /mysite/
# git commit -m "1st commit" -a
# git push -u origin master
```

##Django 1st tutrial
https://docs.djangoproject.com/ja/1.11/intro/tutorial01/
を参照しながら進めます。
DockerFile内で実行したコマンドは省きます。

###新期ファイルはgit addで追加し、push
```shell-session
# git add /mysite/polls/urls.py
# git commit -m "1st tutorial" -a
# git push -u origin master
```


###次回からgit pullできるようにするためDockerFileの編集
```shell-session
$ cat Dockerfile
FROM ubuntu:latest

RUN apt-get update
RUN apt-get install apt-file -y
RUN apt-file update
RUN apt-file search add-apt-repository
RUN apt-get install software-properties-common -y
RUN add-apt-repository ppa:jonathonf/python-3.6 -y
RUN apt-get update
RUN apt-get install openssh-server wget python3.6 vim git -y
RUN apt-get install python-pip -y
RUN pip install --upgrade pip
RUN pip install apiai
RUN pip install requests
RUN apt-get install python-django -y
RUN pip install django==1.10
RUN django-admin startproject mysite
RUN cd /mysite && python manage.py startapp polls
RUN git init
RUN git config --global user.name "r-takebayashi"
RUN git config --global user.email r-takebayashi@xxxxxx.xx.xx
RUN git remote add origin https://github.com/r-takebayashi/api-ai
RUN touch .gitignore && echo *.pyc >> .gitignore && echo *.sqlite3 >> .gitignore
RUN find /mysite -name "*.py"|xargs rm
EXPOSE 8000
CMD git pull origin master && python /mysite/manage.py runserver 0.0.0.0:8000

```

##Django 2nd tutorial


###dbファイルをコンテナからホストにコピー
データベースはコンテナに含めない方が良いと思ったためです。

```shell-session
$ sudo docker cp c33:/mysite/db.sqlite3 db.sqlite3
```

```shell-session
$ mkdir upload
$ mv db.sqlite3 ./upload/
```

ホスト側に保管したデータベースファイルをDockerコンテナでマウントして、起動させます。

```shell-session
$ sudo docker run -p 8000:8000 -d -v $(pwd)/upload/db.sqlite3:/mysite/db.sqlite3 api-ai-image
```

https://docs.djangoproject.com/ja/1.11/intro/tutorial02/
を参考に進めます。
チュートリアル2を進めて再度、git commit、pushします。

```shell-session
# git commit -m "2nd tutorial" -a
# git push -u origin master
```

##Django 3rd tutorial

https://docs.djangoproject.com/ja/1.11/intro/tutorial03/
を進めてCommitしてpushます。追加したファイルはgit addします。

```shell-session
# git add /mysite/polls/templates/polls/detail.html
# git add /mysite/polls/templates/polls/index.html
# git commit -m "3rd tutorial" -a
# git push -u origin master
```

##Django 4th tutorial

https://docs.djangoproject.com/ja/1.11/intro/tutorial04/
を進めて、同じようにgit commit、pushをします。

```shell-session
# git add /mysite/polls/templates/polls/results.html
# git commit -m "4th tutorial" -a
# git push -u origin master
```

##Django 5th tutorial
https://docs.djangoproject.com/ja/1.11/intro/tutorial05/
を進めながら同様にgit add, commit, pushをします。

```shell-session
# git add /mysite/polls/tests.py
# git commit -m "5th tutorial" -a
# git push -u origin master
```

DockerFileを編集して、新イメージを作成します。
Djangoのmigrateを追加します。これをやらないと上手くいかなかったためです。

```shell-session
$ cat Dockerfile
FROM ubuntu:latest

RUN apt-get update
RUN apt-get install apt-file -y
RUN apt-file update
RUN apt-file search add-apt-repository
RUN apt-get install software-properties-common -y
RUN add-apt-repository ppa:jonathonf/python-3.6 -y
RUN apt-get update
RUN apt-get install openssh-server wget python3.6 vim git -y
RUN apt-get install python-pip -y
RUN pip install --upgrade pip
RUN pip install apiai
RUN pip install requests
RUN apt-get install python-django -y
RUN pip install django==1.10
RUN django-admin startproject mysite
RUN cd /mysite && python manage.py startapp polls
RUN git init
RUN git config --global user.name "r-takebayashi"
RUN git config --global user.email r-takebayashi@xxxxxx.xx.xx
RUN git remote add origin https://github.com/r-takebayashi/api-ai
RUN touch .gitignore && echo *.pyc >> .gitignore && echo *.sqlite3 >> .gitignore
RUN find /mysite -name "*.py"|xargs rm
EXPOSE 8000
CMD git pull origin master && python /mysite/manage.py makemigrations polls && python /mysite/manage.py runserver 0.0.0.0:8000
$
```

##Django 6th Tutorial

https://docs.djangoproject.com/ja/1.11/intro/tutorial06/
を参考に進めます。

これまでと同様にgit add, commit, pushです。

```shell-session
# git add /mysite/polls/static/polls/style.css
# git commit -m "6th tutorial" -a
# git push -u origin master
```

Djangoのチュートリアルに画像ファイルが出てきました。
これもDocker Volumeで外出した方が良いと思ったので、Docker RUN時に以下のようにしました。

```shell-session
$ sudo docker run -p 8000:8000 -d -v $(pwd)/upload/db.sqlite3:/mysite/db.sqlite3 -v $(pwd)/images:/mysite/polls/static/polls/images/ api-ai-image
```

##Django 7th Tutorial

https://docs.djangoproject.com/ja/1.11/intro/tutorial07/
を進めます。
同様に行います。

```shell-session
# git add /mysite/templates/base_site.html
# git commit -m "7th tutorial" -a
# git push -u origin master
```


チュートリアルがようやく完了しました！