LoginSignup
3
1

More than 3 years have passed since last update.

今更Dockerの便利さに気がついたけど、最終的によく分からなくなった話

Last updated at Posted at 2019-11-29

はじめに

現実逃避のために、自分の遊びの環境をsakura vpsに作ることにしたがsakuraでは環境が保存できないらしいので、代案手段として、Dockerでやってみようと思い立ちました。

やりたいこと

Docker上に、Nginxのサーバーを立ててSSL化する。

いつもの更地化。

  • OSを再インストールして、更地にします。(CentOS7) 2019-11-26_14h26_00.png

Dockerのインストール

個人利用なので、無償版のDocker-ceを入れます。

  • コンソールからログイン用のユーザを作って。
  • 忘れちゃいけない。yumを更新。
$sudo yum update
  • 必要なパッケージをインストールします。
$sudo yum install -y yum-utils device-mapper-persistent-data lvm2
  • Docker CEをインストールするため、yumのリポジトリを追加します。
$sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  • Dockerインストール

最新バージョン入れます。

$sudo yum install docker-ce

インストール完了。

Dockerを起動します。

$ sudo systemctl start docker

Nginxを入れて起動してみる。

Nginxイメージを使ってコンテナを起動します、外部からはポート:8080でアクセスするようにして起動。

$ sudo docker container run -itd --name nginx-container -p 8080:80 nginx

ブラウザからURLを指定して、起動を確認。
2019-11-26_16h28_58.png

Dockerから状態をみるとNginxが起動してることが確認が取れました。

$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
7a5f699f72db        nginx               "nginx -g 'daemon of…"   6 hours ago         Up 6 hours          0.0.0.0:8080->80/tcp   nginx-container

DockerのNginxを停止する。

$ docker stop  7a5f699f72db
7a5f699f72db
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
7a5f699f72db        nginx               "nginx -g 'daemon of…"   6 hours ago         Exited (0) 2 seconds ago                       nginx-container

STATUSがExitedで停止してます。ブラウザから見ても停止していました。
ここでは、[CONTAINER ID]を指定しましたが、[NAMES]を指定してしても停止できます。

Dockerからnginxのコンテナを削除する。

$ docker rm 7a5f699f72db
7a5f699f72db
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

停止と同様に、ここでは[CONTAINER ID]を指定しましたが、[NAMES]を指定してしても削除できます。

DockerからNginxのイメージを削除する。

現在のイメージを確認します。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              231d40e811cd        3 days ago          126MB

Nginxのイメージが存在しているので、削除します。

$ docker rmi 231d40e811cd
Untagged: nginx:latest
Untagged: nginx@sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566
Deleted: sha256:231d40e811cd970168fb0c4770f2161aa30b9ba6fe8e68527504df69643aa145
Deleted: sha256:dc8adf8fa0fc82a56c32efac9d0da5f84153888317c88ab55123d9e71777bc62
Deleted: sha256:77fcff986d3b13762e4777046b9210a109fda20cb261bd3bbe5d7161d4e73c8e
Deleted: sha256:831c5620387fb9efec59fc82a42b948546c6be601e3ab34a87108ecf852aa15f

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

イメージが削除されました。
ここでは[IMAGE ID]を指定しましたが、[REPOSITORY]を指定してしても削除できます。

綺麗になりました。めっちゃ便利です。
なんで今まで使ってなかったのか悔やまれます。

Dockerの構造

Dockerの構造として、イメージとコンテナという概念があり、イメージが概念で、コンテナが実態のようです。
クラスとインスタンスの関係と同様のようです。
無題 2.png

NginxをHTTPS化したなと思って、Docker Hubを見てたら、Certbotはあったのですが、連携の仕方がわからず、なんかいい方法が無いものかと思って調べていたら、Docker HubにCentOSのイメージもあることに気が付きました。つまり、今までDockerの上にNginxやなんやらかんやらの載せて管理するのかなと思っていましたが、Dockerの上にOS載せて、その上でNginxを載せられる?もしそうならもっと楽に構築できるじゃないかと思い立ちました。
Dockerのイメージ変更.png

CentOSを起動する

イメージを取得する。

$ sudo docker pull centos:centos7
centos7: Pulling from library/centos
ab5ef0e58194: Pull complete
Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c
Status: Downloaded newer image for centos:centos7
docker.io/library/centos:centos7
$sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              centos7             5e35e350aded        2 weeks ago         203MB

イメージを起動して、ログインする。(exitするとDockerのCentOSから脱出できます。)

$ sudo docker run -it -d --name centos7 5e35e350aded
docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
9927906158a2        centos              "/bin/bash"              10 seconds ago      Up 9 seconds                               centos7
$ sudo docker exec -it centos7 /bin/bash
[root@9927906158a2 /]# ls
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr

コンテナのCentOSにNginxをインストールする

Docker上のCentOS上のyumを更新します。
Nginxをインストールします。NginxのInstallation instructionsにしたがってインストールします。

$ yum update
$ yum install yum-utils

/etc/yum.repos.d/nginx.repoファイルを作成します。

$ vi /etc/yum.repos.d/nginx.repo

記載内容

nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

Nginxのインストールし、起動しようとした処で、D-Busの権限エラーが発生しました。

$ yum-config-manager --enable nginx-mainline
$ yum install nginx
$ systemctl start nginx
Failed to get D-Bus connection: Operation not permitted

調べて見ると、 docker runする際に、--privilegedのオプションと、公開するにあたってポートの公開が必要なようです。
そこで、今のイメージを保存して、上記の2つのオプションをつけて起動し直すことにしました。
手順としては、今のコンテナを停止させてから、イメージを作成します。

$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
4073d82ac893        5e35e350aded        "/bin/bash"         9 minutes ago       Up 9 minutes                            centos7
$ sudo docker stop 4073d82ac893
$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                        PORTS               NAMES
4073d82ac893        5e35e350aded        "/bin/bash"         13 minutes ago      Exited (137) 12 seconds ago                       centos7

イメージのステータスがExitedになり、止まった状態になったので、イメージを作成します。

docker commit NAMES(または、CONTAINER ID) 作成イメージ名

$ sudo docker commit 4073d82ac893 centos7n
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos7n            latest              0c30b8b87f37        19 seconds ago      347MB
centos              centos7             5e35e350aded        2 weeks ago         203MB

作成したイメージの先程のオプションつけて起動します。Exitedを起動します。

$ sudo docker run -d --privileged -p 80:80 -p 443:443 centos7n /sbin/init
$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                        PORTS                  NAMES
550d5d2474b9        centos7n            "/sbin/init"        9 seconds ago       Up 8 seconds                  0.0.0.0:80->80/tcp   stupefied_moser
4073d82ac893        5e35e350aded        "/bin/bash"         23 minutes ago      Exited (137) 10 minutes ago                          centos7
$ sudo docker exec -it stupefied_moser /bin/bash
$ systemctl start nginx

今度は無事起動でき、外部からアクセスできことを確認しました。次にやりたいのはHTTPS化です。
以前、使ったLet's EncryptからSSL証明書を取得してHTTPS化します。

HTTPS化する。

Certbotをインストールします。certbotの手順を見ながらインストールします。

$ yum -y install yum-utils
$ yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
$ yum install certbot python2-certbot-nginx
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
 * base: ftp-srv2.kddilabs.jp
 * extras: ftp-srv2.kddilabs.jp
 * updates: ftp-srv2.kddilabs.jp
No package certbot available.
No package python2-certbot-nginx available.
Error: Nothing to do

なんかエラーが出ました。パッケージがないとのこと。
epelを追加して、再度インストールでうまくいきました。

$ yum install epel-release
$ yum install certbot python2-certbot-nginx

証明書を取得します。
管理者のメールアドレスが求められるので入力します。

$ certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to

ライセンスに同意するか聞かれるので、Aを入力します。

Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel:

メールアドレスをシェアするとか言ってるので、Nを入力します。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

ドメイン名を入力します。(Let's Encryptでドメイン指定する際はwwwをつけた状態にします。)

No names were found in your configuration files. Please enter in your domain

エラーが発生した。

Obtaining a new certificate
Resetting dropped connection: acme-v02.api.letsencrypt.org
Performing the following challenges:
http-01 challenge for ドメイン名
Using default address 80 for authentication.
Waiting for verification...
Challenge failed for domain ドメイン名
http-01 challenge for ドメイン名
Cleaning up challenges
Some challenges have failed.

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: ドメイン名
   Type:   connection
   Detail: Fetching
   http://ドメイン名/.well-known/acme-challenge/dlxpxIAt0fMvR90N0bBWnTTcAvu_XTHSV6jyKOC872M:
   Connection refused

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

[http://ドメイン名/.well-known/acme-challenge/]にアクセスしようとしてるようなので、Nginx設定ファイルの編集して場所を設定します。

以下にアクセスの場所を作ります。
/var/www/acme-challenge

設定ファイルをバックアップを作成し、編集します。
console
$ cp /etc/nginx/conf.d/default.conf default.conf.org
$ vi /etc/nginx/conf.d/default.conf

[location ^~ /.well-known/acme-challenge/]の振替先を追加

default.conf
server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # 追加した
    location ^~ /.well-known/acme-challenge/ {
        root /var/www/acme-challenge;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
-- INSERT --

Nginxをリスタートします。certbotを再び起動しドメイン名を登録します。

$ systemctl restart nginx
$ certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
No names were found in your configuration files. Please enter in your domain
name(s) (comma and/or space separated)  (Enter 'c' to cancel): ドメイン名
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for ドメイン名
Using default address 80 for authentication.
Waiting for verification...
Cleaning up challenges
Could not automatically find a matching server block for ドメイン名. Set the `server_name` directive to use the Nginx installer.

IMPORTANT NOTES:
 - Unable to install the certificate
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/ドメイン名/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/ドメイン名/privkey.pem
   Your cert will expire on 2020-02-27. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"

成功したら、再び設定ファイルを編集し、SSL接続の設定を追加します。

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/ドメイン名/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem;

$ vi /etc/nginx/conf.d/default.conf
default.conf
server {
    listen       80;
    server_name  localhost;

    # 追加した
    listen 443 ssl;
    ssl_certificate     /etc/letsencrypt/live/ドメイン名/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/acme-challenge;
    }


    #error_page  404              /404.html;

Nginxを再起動して、HTTPSで接続の確認します。

systemctl restart nginx

無事HTTPSで接続できました。
2019-11-29_16h00_31.png

が、なんか違う…こんなに面倒な設定は、Dockerに任せたいはずだった。

自分がやりたかったことを一回整理

  • 環境を破壊したりするので、状態を保存して、適度なタイミングで復帰したい。
  • 自家製のコンテンツも環境と同じように切り替えられるようにしたい。
  • ログは、コンテンツ扱いにすると消えるので、指定の場所に保存したい。

もう一回構成を含めて検討してきます。

3
1
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
3
1