docker-compose cheatsheet

docker-compose cheatsheet

# docker-compose cheatsheet

## はじめに
- docker勉強用のまとめです。
- 開発環境でちょっと使いたいとき用です。
- ディレクトリは参考程度に。

## 環境
- docker:17.09
- docker-compose:1.17
- docker-machine:0.13

## 更新内容

- 2018/01/24 [Rails + PostgreSQL](##Rails + PostgreSQL)を追加

## Rails + PostgreSQL

- Railsアプリを動かします。
- ruby:2.5.0

### ディレクトリ構成
```
/application_name
  /Dockerfile
  /docker-compose.yml
  /app
  /bin
  /config
  /config.ru
  /data
  /db
  /lib
  /log
  /public
  /spec
  /tmp
  /vendor
  /Gemfile
  /Gemfile.lock
  /Rakefile
```

- rspecを利用しているため、specディレクトリになっています。

### ファイル

```docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    container_name: db
    ports:
      - "5432:5432"
    volumes:
      - ./data:/var/lib/postgresql/data
  web:
    build: .
    container_name: web
    command: bundle exec rails server -p 3000 -b '0.0.0.0'
    volumes:
      - .:/application_name
    ports:
      - "3000:3000"
    depends_on:
      - db
```

- dbのvolumesを設定しないと、コンテナを停止するたびにDBがなくなります。
- depends_onは、webアプリのコンテナからDBのコンテナを利用するための設定です。

```Dockerfile
FROM ruby:2.5.0

ENV LANG C.UTF-8
RUN apt-get update -qq 
RUN apt-get install -y build-essential libpq-dev postgresql nodejs

RUN gem install bundler
WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install

ENV APP /application_name
RUN mkdir -p $APP
WORKDIR $APP
ADD . $APP
```

### dockerコマンド

コンテナをビルドします。（Gemfileを更新するたびに実行します。）

```
docker-compose build
```

DB作成・テーブル作成・データ投入　。（適時）

```
docker-compose exec web rails db:create db:migrate db:seed
```

WebコンテナとDBアプリを起動します。

```
docker-compose up -d
```


## nginx

- httpでダウンロードできるようにします。

### ディレクトリ構成
```
/docker
  /nginx
    /docker-compose.yml
    /data
      /test.csv
```

### ファイル

```docker-compose.yml
version: '3'
services:
  nginx:
    container_name: nginx
    image: nginx
    volumes:
      - ./data:/usr/share/nginx/html
    ports:
      - "80:80"
      - "8080:80" # 自分の環境だと80でつながらないため
```

### コメント

- http://localhost/test.csv or http://localhost:8080/test.csv でダウンロード
- これぐらいなら、dockerコマンドで良さそう。
  - ``` docker run --rm -d -p 8080:80 -v data:/usr/share/nginx/html nginx ```

## sftp

- sftpでファイルのやり取りができるようにします。

### ディレクトリ構成

```
/docker
  /sftp
    /docker-compose.yml
    /data
      /upload
        /test.csv
```

### ファイル

```docker-compose.yml
version: '3'
services:
  sftp:
    container_name: sftp
    image: atmoz/sftp
    volumes:
      - ./data/upload:/home/sample/upload
    ports:
      - "22:22"
    command: sample:sample:::upload
```

### コメント

- ID/PASSWORDはsample/sample
- ログインとファイルの取得の確認

```
$ sftp sample@localhost
sample@localhost's password:
Connected to localhost.
sftp> cd upload
sftp> get test.csv
Fetching /upload/test.csv to test.csv
```
- ホストの ``` /docker/sftp/data/upload ``` と コンテナの ``` /home/sample/upload ``` がマウントされているので、 ``` /docker/sftp/data/upload ``` 以下に置いたファイルが以下で確認できる。


### 参照
- https://github.com/atmoz/sftp#using-docker-compose

## ftp

- ftpでファイルのやり取りができるようにします。

### ディレクトリ構成

```
/docker
  /ftp
    /docker-compose.yml
    /Dockerfile
    /add_user.exp
    /data
      /upload
        /test.csv
```

### ファイル

```docker-compose.yml
version: '3'
services:
  ftp:
    container_name: ftp
    build: .
    volumes:
      - ./data/upload:/home/ftpusers/sample
    ports:
      - "21:21"
      - "30000-30009:30000-30009"
    environment:
      - PUBLICHOST=localhost
```

```Dockerfile
FROM stilliard/pure-ftpd:hardened

RUN apt-get update && apt-get install -y expect

RUN mkdir -p /home/ftpusers/sample && chown ftpuser:ftpgroup /home/ftpusers/sample
COPY add_user.exp /tmp/
RUN expect /tmp/add_user.exp
```

```add_user.exp
#!/usr/bin/expect

set timeout 20

spawn pure-pw useradd sample -f /etc/pure-ftpd/passwd/pureftpd.passwd -m -u ftpuser -d /home/ftpusers/sample
expect {
  "Password:" {
    send "sample\n"
    exp_continue
  }
  "Enter it again:" {
    send "sample\n"
  }
}

expect {
  "\\\$" {
    exit 0
  }
}
```

### コメント

- ID/PASSWORDはsample/sample
- ログインとファイルの取得の確認

```
$ ftp -p localhost
Trying ::1...
ftp: Can't connect to `::1': Connection refused
Trying 127.0.0.1...
Connected to localhost.
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 5 allowed.
220-Local time is now 13:11. Server port: 21.
220-This is a private system - No anonymous login
220 You will be disconnected after 15 minutes of inactivity.
Name (localhost:tsujiguchi): sample
331 User sample OK. Password required
Password:
230 OK. Current directory is /
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> get test.csv
local: test.csv remote: test.csv
229 Extended Passive mode OK (|||30006|)
150 Accepted data connection
     0        0.00 KiB/s
226 File successfully transferred
```

- stilliard/pure-ftpdというイメージを使うのですが、アカウントの登録がコンテナに入って、コマンド実行し、なおかつ対話式でパスワード入力が手間なので、expectを使って自動化。
- expectは、Dockerfileに直接書けるが、見にくいため別ファイルにする。

### 参照
- https://github.com/stilliard/docker-pure-ftpd#starting-it
- https://hondou.homedns.org/pukiwiki/pukiwiki.php?Docker%20Glassfish
- https://qiita.com/ine1127/items/cd6bc91174635016db9b