Dockerを使い、devopsの環境を構築してみた

# 概要

devopsを勉強するために、dockerを使って、簡単なdevops環境を構築してみた。

# step1: jenkinsを立ち上がる

dockerを使うので、jenkinsもdockerのコンテナの中に入れている。jenkinsを起動しているコンテナにはイメージをビルドする必要があるため、そのコンテナの中に、dockerコマンドを実行できる環境を構築する必要があった。dockerコマンドを叩ける環境を作れば良いので、`DooD(docker outside of docker)`の形で構築する方が簡単です。

## DooD vs DinD

### DooD
- コンテナはホストマシンと共有している (コンテナ内部作成したコンテナはホストマシンに反映されている)
- docker.sockをマウントする必要がある


##### 構築方法:

- ホストマシンで、dockerをインストールする必要がある

- Dockerfile


```Dockerfile
FROM jenkins/jenkins:lts

USER root

RUN apt-get update

RUN apt-get install wget vim -y

## install docker
RUN apt-get install ca-certificates curl gnupg lsb-release -y

RUN curl -fsSL https://download.docker.com/linux/debian/gpg |  gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

RUN apt-get update

RUN apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y

## grant docker
ENV DOCKER_GROUP_GID 999
RUN usermod -g docker jenkins

```

- docker-compose.yml

```yml
version: "3"

services:
  jenkins:
    build: .
    ports:
      - 8080:8080
    volumes:
      - ./jenkins_home:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
```

### DinD

- コンテナはホストマシンと共有していない(コンテナ内部作成したコンテナはホストマシンに反映されない)
- docker.sockをマウントする必要がない

##### 構築方法:
  - Dockerfile

```Dockerfile
# DockerfileDinD
FROM jenkins/jenkins:lts

USER root

RUN apt-get update

RUN apt-get install wget vim -y

## install docker-compose

RUN curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

RUN chmod +x /usr/local/bin/docker-compose

RUN echo 'export PATH=$PATH:/usr/local/bin/docker-compose' >> /etc/profile
```

- docker-compose.yml

```yml
version: '3'
services:
  dind:
    image: docker:dind
    user: root
    privileged: true
    container_name: dind
    expose:
      - 2375
    networks:
      - jenkins_dind
    environment:
      DOCKER_TLS_CERTDIR: ""

  jenkins:
    build:
      context: .
      dockerfile: ./DockerfileDinD
    container_name: jenkins
    depends_on:
      - dind
    ports:
      - 8080:8080
      - 50000:50000
    volumes:
      - ./jenkins:/var/jenkins_home
    environment:
      DOCKER_HOST: "tcp://dind:2375"
    networks:
      - jenkins_dind

networks:
  jenkins_dind:
    driver: bridge
```

# step2: jenkinsのコンテナで秘密鍵を作成し、デプロイしたいサーバに公開鍵を配置する

参考: 
- https://superuser.com/questions/8077/how-do-i-set-up-ssh-so-i-dont-have-to-type-my-password

- https://stackoverflow.com/questions/27504187/ssh-key-generation-using-dockerfile

詳細は割愛


# step3: piplineファイルを作成

```
pipeline {
  stages {
      stage('pull code from github') {
            steps {
                sh```
                   if [ -d test ]; then rm -Rf test; fi
                   git clone http://git.repository.git
                   cd test
                   git checkout {branch}
                ```
            }
      }
     stage('build and push docker image') {
        steps {
         sh```
         docker login  --username xxxx --password xxxx
         cd test
         docker-compose build
         docker-compose push
         ```
        }
    }

     stage('build and push docker image') {
        steps {
         sh```
         docker login  --username xxxx --password xxxx
         cd test
         docker-compose build
         docker-compose push
         ```
        }
    }

     stage('restart remote server') {
        steps {
         sh```
            ssh user@example.com restart
         ```
        }
    }
  }
}
```

以上