20201123のdockerに関する記事は25件です。

Dockerでsupervisor (docker execでsupervisorctl利用、docker logsでプロセスログ確認、Webインターフェース機能でブラウザ表示)

はじめに

Dockerでsupervisorを起動し以下の項目の確認まで実施します。

  • docker execでsupervisorctl利用
  • docker logsでログ確認
  • supervisordのWebインターフェース機能でブラウザ表示

supervisor is 何?

Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems.

用意するプログラム

Sleepで10秒に一度出力をするGoプログラム

構成

.
├── Dockerfile
├── go.mod
├── go.sum
├── main.go
└── supervisord.conf
supervisord.conf
[supervisord]
nodaemon=true ; Docker利用ではtrueにする必要あり

[unix_http_server]
file=/var/run/supervisor.sock ; このパスにしないとdocker execで入りsupervisorctlで操作できない

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock

[inet_http_server]
port=0.0.0.0:9001 ; HTTPでのプロセス監視機能。9001ポートで受ける。
username=user     ; ログインするのに必要なBasic認証のユーザーとパス
password=123

[program:mytool]
command=/usr/local/bin/mytool  ; プログラムはmytoolという名前にした
stdout_logfile=/dev/stdout     ; 今回は標準出力へ出すことでdocker logsで確認する
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
Dockerfile
FROM golang:1.15.5-buster as builder

WORKDIR /workspace

ENV GO111MODULE="on"
COPY go.mod go.sum ./
RUN go mod download

COPY . ./

RUN CGO_ENABLED=0 GOOS=linux go build -o mytool

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor # TODO: need?

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

COPY --from=builder /workspace/mytool /usr/local/bin/

CMD ["/usr/bin/supervisord"]
main.go
package main

import (
    "fmt"
    "time"

    "github.com/vikyd/zero"
)

func main() {
    for {
        var v int
        fmt.Println("hello supervisor!?", zero.IsZeroVal(v))
        time.Sleep(10 * time.Second)
    }
}

動かす

Docker起動

$ docker build -t supervisor-image .
$ docker run --name supervisor -p 9001:9001 -d supervisor-image

コンテナに入りsupervisorctlを使う

$ docker exec -it supervisor bash
root@e70e1f0c07ef:/# supervisorctl help

default commands (type help <topic>):
=====================================
add    exit      open  reload  restart   start   tail
avail  fg        pid   remove  shutdown  status  update
clear  maintail  quit  reread  signal    stop    version

root@e70e1f0c07ef:/# supervisorctl status
mytool                           RUNNING   pid 8, uptime 0:09:25

docker logsでプロセス確認

$ docker logs -f supervisor
hello supervisor!? true
hello supervisor!? true
hello supervisor!? true
hello supervisor!? true
hello supervisor!? true
hello supervisor!? true
hello supervisor!? true
hello supervisor!? true
hello supervisor!? true
hello supervisor!? true

Webインターフェース機能でブラウザ表示

http://localhost:9001 へアクセス

image.png

image.png

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

Docker for MacをやめてUbuntu + VagrantでDocker開発環境を構築する方法

はじめに

Docker for Macを使ってチーム開発を行っていたんですが、遅いのでDocker for Macをやめて仮想環境を立ち上げて爆速のDocker環境を作ろう!!と至りました。

Docker for Macが遅い理由

Linux上ではホストとコンテナ間で VFS を基盤に共有しているので、オーバーヘッドのない反映を保証します。しかしながら、 macOS (および他の Linux 以外のプラットフォーム)では、完全な一貫性を保つために著しいオーバーヘッドがあります、、、、、、
Docker日本語ドキュメントや他の方のQiitaの記事でもそう書かれていましたがあんまりわからない、、、
とりあえず、Docker for Macのファイル共有システムのosxfsに対するマウントが遅いっぽい、
OSXのFSEvents APILinux’s inotify APIをマッピングさせてたりするのが主な原因なんですね
遅い原因

Docker for Macと今回構築する環境(Virtual Box + Docker)との違い
DXを大幅に低下させるDocker for Macを捨ててMac最速のDocker環境を手に入れる
上記の方の記事がものすごくわかりやすかったです!!図が助かるー( ;∀;)

動作環境

PCスペック

Mac OS Catalina 10.15.7

Docker バージョン

20.10.0-beta1

Vagarnt バージョン

Vagrant 2.2.13

Ubuntu バージョン

Ubuntu 18.04.5 LTS

補足

今回、誤ってubuntu16.04LTSから18.04LTSへバージョンアップしてしまったためVagrant Box(OS)をbionic64にしています。
本来ならばxenial64です。(Ubuntu16.04の場合)
Ubutnuのコードネームに関してまとめてくれている記事が下記です。
ubuntu コードネーム

ただ、bionic64のところをxenial64に変えていくだけで大丈夫です⭕

概要

①VirtualBoxとVagrantをインストールする

②Dockerとmutagen(後述)用のvagrantプラグインをインストール

③vagrantファイルの作成

④mutagenでファイル同期する

⑤Dockerを起動する

手順が多く見えますが頑張っていきましょう、、、(笑)

①VirtualBoxとVagrantをインストールする

Homebrewを使用して、必要なツールをインストールしていきます。
Homebrewインストール

VirtualBoxをインストール
brew cask install virtualbox
Vagrantをインストール
brew cask install vagrant
Vagrant Boxをダウンロード

Vagrant Box(OS)をダウンロードしていきます。(結構時間かかりました)
ubuntu/bionic64を選んだ理由は下記
Ubuntu18.04の中でもメジャーのほうがいいのかなと選ばせていただきました
Ubuntu 18.04のVagrant box比較

vagrant box add ubuntu/bionic64 

ダウンロード完了後以下のコマンドで確認できます

vagrant box list
ubuntu/bionic64 (virtualbox, 20200229.0.0)

②Dockerとmutagen(後述)用のvagrantプラグインをインストール

必要となるVagrant Pluginをインストールします。
mutagenについては後ほど説明します。

vagrant plugin install vagrant-disksize vagrant-hostsupdater vagrant-mutagen vagrant-docker-compose

③vagrantファイルの作成

開発ディレクトリにvagrant init

cd ~/my_app       (開発ディレクトリに移動)
vagrant init ubuntu/bionic64      (vagrantで初期化)

以下の文が出てくるのでvagrantfileができてます!

A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

Vagrantfileを編集していきます!!!
Vagrantファイルの内容は以下のように編集してください!
config.vm.hostname は 開発ディレクトリでOKだよー!
その他よくわからなかったら
VagrantコマンドとVagrantfileの設定メモ
上記の方の記事の「vagrantfileの設定」を見るとわかりやすかったです。ありがとうございます(:_;)

~/my_app/Vagrantfile
Vagrant.configure('2') do |config|
  config.vm.box = 'ubuntu/bionic64'

  config.vm.hostname = 'my_app'

  config.vm.network :private_network, ip: '192.168.50.10'

  config.vm.network "forwarded_port", guest: 80, host: 8080

  config.vm.provider :virtualbox do |vb|
    vb.gui = false
    vb.cpus = 4
    vb.memory = 8192
    vb.customize ['modifyvm', :id, '--natdnsproxy1', 'off']
    vb.customize ['modifyvm', :id, '--natdnshostresolver1', 'off']
  end

  config.disksize.size = '30GB'
  config.mutagen.orchestrate = true

  config.vm.synced_folder './', '/home/vagrant/app', type: "rsync",

  rsync_auto: true,

  rsync__exclude: ['.git/', 'node_modules/', 'log/', 'tmp/', 'vendor']

  config.vm.provision :docker, run: 'always'
  config.vm.provision :docker_compose
end

config.vm.synced_folderのホスト側のパスは、"./"のようにしてしまうと作業をシェアする際に、作業環境ごとにパスを書き換える必要がないので楽になります。

以上で、Vagrant+VirtualBoxの準備は完了です。

④mutagenでファイル同期する

編集したファイルをMacとLinuxで同期させます。Mutagenというツールで実現します。
以下のコマンドで、mutagenをインストールします。(これも時間かかりました)

brew install mutagen-io/mutagen/mutagen

インストール後、mutagenの設定ファイルmutagen.ymlを作成します。作成する場所は、Vagrantfileと同じディレクトリにしてください。

~/my_app
touch mutagen.yml

内容は以下のようになります。

~/my_app/mutagen.yml
sync:
  app:
    mode: "two-way-resolved"
    alpha: "./"
    beta: "my-app:/home/vagrant/app"
    ignore:
      vcs: true
      paths:
        - "/node_modules"
        - "/log"
        - "/tmp"

その後 $ vagrant up でVMを起動すると、Mutagenによって双方向のファイル同期が行われます。
この同期は双方向にほぼリアルタイムで行われ、ファイルシステムのマウントではなくファイルの転送で実現されているため、最終的にDockerコンテナへマウントされた際のオーバーヘッドはほぼ発生しません。

⑤Dockerを起動する

Vagrantを起動

コマンド実行後に、エラーが発生しました,,,,,

~my_app
vagrant up
/Users/hoge/.vagrant.d/gems/2.4.9/gems/vagrant-mutagen-0.1.2/lib/vagrant-mutagen/Mutagen.rb:22:in `initialize': No such file or directory @ rb_sysopen - /Users/hoge/.ssh/config (Errno::ENOENT)

configがないよって言ってますね(汗)
作ってあげましょう!!

~my_app
touch /Users/hoge/.ssh/config

もう一度!!

~my_app
vagrant up

今度はうまくできたみたいですε-(´∀`*)ホッ

仮想環境にSSH接続

vagrant ssh

すると今度はなんかupdateの案内が、、

New release ''20.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

これに関してはしないほうがいいかもですね。

vagrant box add ubuntu/bionic64
でしっかりバージョンに合わせたOSをダウンロードする必要があるっぽいので、、

Vagrantの中で、Dockerを起動

以下のコマンドは、プロジェクトディレクトリにdocker-compose.ymlが存在している場合の例です。

cd app
docker-compose up

参考文献

VirtualBoxとVagrantでUbuntuの仮想環境を構築してSSH接続するまで

https://temlog.net/ubuntu-vagrant/

vagrant+docker-compose環境を構築

https://qiita.com/maro_amoeba/items/740c9e84abaf89fc625f

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

Rails wheneverをdockerで実行する

動機

Railsの定期実行を行うwheneverを使おうとしたのですが、Mac上で直接実装すると環境変数や権限管理で大変だったのでdockerで行うことにしました

前提条件

実行環境は下記のようになります
・ ruby 2.6.3
・ Rails 5.2.4
・ MySQL 8.0.19 

Docker関係

Dockfiledocker-compose.ymlは以下のようになります
通常のdockerの設定とあまり変わらないのですが、今回はwheneverを利用するのでcornのインストールとcronをフォアグラウンド実行するための設定を追記しています。

FROM ruby:2.6.3
#rubyのバージョン指定

#gemのインストール
RUN apt-get update -qq && \
    apt-get install -y build-essential \ 
                       libpq-dev \        
                       nodejs

# cronインストール
RUN apt-get install -y cron 

RUN mkdir /my_app

WORKDIR /my_app

COPY Gemfile /my_app/Gemfile
COPY Gemfile.lock /my_app/Gemfile.lock

RUN gem install bundler
RUN bundle install

COPY . /my_app

# wheneverでcrontab書き込み
RUN bundle exec whenever --update-crontab 

# cronをフォアグラウンド実行
CMD ["cron", "-f"] 

docker-compose.yml
version: '2'
services:
  db:
    image: mysql:8.0.19
    command: 
      --default-authentication-plugin=mysql_native_password
    volumes:
      - ./mysql-confd:/etc/mysql/conf.d
      - mysql-data:/var/lib/mysql    #データの永続化のため
    ports:
      - "3306:3306"
    restart: always
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
      # MYSQL_DATABASE: app_development
      MYSQL_USER: root
      # MYSQL_PASSWORD: password
      TZ: Asia/Tokyo
  app:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/my_app   
      - bundle:/usr/local/bundle   
    ports:
      - "3000:3000"
    links:
      - db

volumes:
  mysql-data:
  bundle:      #bundle installした後buildし直さなくてよくなる

whenever関係

config/schedule.rb
# wheneverにrailsを起動する必要があるためRails.rootを使用
require File.expand_path(File.dirname(__FILE__) + "/environment")

# 環境変数をうまい感じにやってくれる
ENV.each { |k, v| env(k, v) }

# ログを書き出すようファイル
set :output, error: 'log/crontab_error.log', standard: 'log/crontab.log'
set :environment, :development

#2分毎に`sample_task`の`scheduled_task`を実行する
every 2.minutes do
  rake 'sample_task:scheduled_task'
  # runner "Test.yakisoba", :environment => :development # runnnerの例
end

実行したいコマンド

/lib/tasks/sample_task.rb
namespace :sample_task
  desc "scheduled_task"
  task scheduled_task: :environment do
     ..... 実行したい関数
    end
  end
end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【2020年11月版】Kubernetesをk3d+Lensで超速で立ち上げる

k3d を使ってみました。

k3d = k3s on docker。つまり docker上でk3sをうごかすものです。
そして・・・、簡単です。とっても。

前提条件

dockerは動かしておいてください。

1. k3d のインストール&クラスタの作成

1-1. インストール

以下のコマンドでk3dをインストールします。

$ curl -s https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash

1-2. クラスタの立ち上げ

インストール後、以下のコマンドでクラスタを作成します。

$ k3d cluster create test-cluster

このtest-clusterは作成するクラスタの名前です。好きなお名前でどうぞ。

1-3. クラスタに接続

以下のコマンドでkubectlの接続先を上記で作成したクラスタに指定します。

$ k3d kubeconfig merge test-cluster --switch-context

以上で、kubectl が使えるようになっております。

2. Lensのインストールと立ち上げ

以下の公式サイトからgithubサイトへのリンクがありますのでバイナリがダウンロード可能です。

インストール後、lensを立ち上げると・・・

スクリーンショット 2020-11-23 19.48.48.png

左上のクラスタ追加ボタンがありますので、クリックすると・・・

スクリーンショット-2020-11-23-19-49-58.png

はい、上記で作成したk3d-test-clusterへの接続準備、オーライでございます。
Add cluster(s)をクリックすると・・・

スクリーンショット 2020-11-23 19.55.33.png

はい、このような感じでクラスタに接続完了です。このままLensからいろいろとクラスタの操作が行えてしまいます。

だいたい5分くらい?ですよ。。。

クラスタの削除

以下のコマンドでクラスタの削除です。

$ k3d cluster delete test-cluster

k3d、めっちゃお手軽やん。。。

以上です!!

参考サイト

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

WSL上のubuntuにDockerを入れてみる

WSL2上のUbuntu18.04にDockerをインストールし触ってみたので、メモを残しておきます。

作業環境

Ubuntuセットアップ

WSL2上のUbuntu構築は以下の記事にまとめています。
WSL上にUbuntu18.04を構築してみた

Dockerバージョン

19.03.13

流れ

  1. Dockerインストール
  2. Dockerコマンド諸々

1.Dockerインストール

以下サイトを参考にインストールを行います。
Ubuntu 18.04 LTS に Docker をインストールする

Dockerのリポジトリを設定する

パッケージのアップデート、必要なパッケージのインストールを実行し、Docker 公式の GPG 公開鍵をインストールします。

$ sudo apt update
$ sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) \
    stable"

Dockerインストール

最新版のDockerをインストールします。

$ sudo apt update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

インストールの確認をします。

$ sudo docker --version
$ sudo systemctl status docker

以下はProxy設定を行う場合に実施してください。

proxy設定用ファイルを作成し、必要な設定を書き込みます。

$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf
http-proxy.conf
[Service]
  Environment="HTTP_PROXY=http://proxy.example.com:8080/"
  Environment="HTTPS_PROXY=http://proxy.example.com:8080/"

変更を適用し、設定を反映させる。最後に設定できていることを確認します。

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
$ systemctl show --property=Environment docker

設定ファイルに記載した情報が表示されれば完了です。

Dockerコマンドをsudo無しで実行するための設定を行います。

まずは現状の確認をします。

$ docker images

Permission Deniedでエラーになります。

Dockerグループに対象ユーザーを入れます。
一度対象ユーザーにログインしなおしてください。

$ sudo usermod -aG docker ${USER}
$ su - ${USER}

設定できたことを確認します。

$ docker images

エラーが起きなくなっていれば完了です。

2.Dockerコマンド諸々

Docker起動・停止・ステータスチェック

$ sudo systemctl start docker
$ sudo systemctl stop docker
$ sudo systemctl status docker

イメージ検索

$ docker search [OPTIONS] TERM

TERMには、httpd、mysqlなどを入れることで、提供されているレポジトリが表示されます。

例えばhttpdで検索してみます。

$ docker search httpd

以下のような結果が返ってきました。

NAME                                    DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
httpd                                   The Apache HTTP Server Project                  3261                [OK]
centos/httpd-24-centos7                 Platform for running Apache httpd 2.4 or bui…   36
centos/httpd                                                                            33                                      [OK]
arm32v7/httpd                           The Apache HTTP Server Project                  9
polinux/httpd-php                       Apache with PHP in Docker (Supervisor, CentO…   4                                       [OK]
salim1983hoop/httpd24                   Dockerfile running apache config                2                                       [OK]
solsson/httpd-openidc                   mod_auth_openidc on official httpd image, ve…   1                                       [OK]
publici/httpd                           httpd:latest                                    1                                       [OK]
clearlinux/httpd                        httpd HyperText Transfer Protocol (HTTP) ser…   1
hypoport/httpd-cgi                      httpd-cgi                                       1                                       [OK]
jonathanheilmann/httpd-alpine-rewrite   httpd:alpine with enabled mod_rewrite           1                                       [OK]
dariko/httpd-rproxy-ldap                Apache httpd reverse proxy with LDAP authent…   1                                       [OK]
lead4good/httpd-fpm                     httpd server which connects via fcgi proxy h…   1                                       [OK]
dockerpinata/httpd                                                                      0
interlutions/httpd                      httpd docker image with debian-based config …   0                                       [OK]
appertly/httpd                          Customized Apache HTTPD that uses a PHP-FPM …   0                                       [OK]
amd64/httpd                             The Apache HTTP Server Project                  0
manasip/httpd                                                                           0
trollin/httpd                                                                           0
e2eteam/httpd                                                                           0
manageiq/httpd_configmap_generator      Httpd Configmap Generator                       0                                       [OK]
itsziget/httpd24                        Extended HTTPD Docker image based on the off…   0                                       [OK]
manageiq/httpd                          Container with httpd, built on CentOS for Ma…   0                                       [OK]
ppc64le/httpd                           The Apache HTTP Server Project                  0

The Apache HTTP Server Projectが公式でhttpdという名前のイメージを公開していることがわかります。

イメージ取得

$ docker pull [OPTIONS] NAME[:TAG|@DIGEST]

先ほど検索したhttpdのイメージを取得してみます。

$ docker pull httpd

TAGを指定しなければ、latest(最新版)がpullされます。

Using default tag: latest
latest: Pulling from library/httpd
852e50cd189d: Pull complete
67d51c33d390: Pull complete
b0ad2a3b9567: Pull complete
136f1f71f30c: Pull complete
01f8ace29294: Pull complete
Digest: sha256:fddc534b7f6bb6197855be559244adb11907d569aae1283db8e6ce8bb8f6f456
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest

イメージ一覧表示

$ docker images [OPTIONS] [REPOSITORY]

先ほどpullしたイメージを見てみます。

$ docker images

以下の通り表示されます。

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd               latest              0a30f4c29d25        4 days ago          138MB

コンテナの起動

$ docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

先ほどのhttpdを起動してみます。

$ docker run -d -p 8080:80 httpd

docker runコマンドを実行した際に下に表示される英数字が、コンテナIDとなり、今後このコンテナを指定する際には、このIDを指定します。
オプションの解説をしておきます。
-d:バックグラウンド実行(つけなければ、プロンプトがコンテナに奪われます。ログアウトすればホスト側に戻ってきます。)
-p:ポート指定(今回はローカルポートが8080でコンテナポートが80になっています)

別の起動方法。これで起動した場合は、プロンプトがコンテナ内のプロンプトになる。

$ docker run -p 8080:80 --name test01 -it httpd /bin/bash

--name:コンテナ名を指定
-it:image名を指定
/bin/bash:ログイン時のコマンドを指定

コンテナプロセスの確認

$ docker ps [OPTIONS]

停止中のプロセスも含めて確認するには、-aオプションを付けます。
基本的に以下のコマンドを打てばいいと思います。

$ docker ps -a

実行結果は以下のように表示されます。

CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                      PORTS                  NAMES
cf4beeb4be04        httpd               "httpd-foreground"   3 seconds ago       Up 2 seconds                0.0.0.0:8080->80/tcp   pedantic_cohen
168d4374aa73        httpd               "/bin/bash"          7 minutes ago       Exited (0) 4 minutes ago                           test01

見方は以下の通りです。

カラム名 説明
CONTAINER ID コンテナIDの最初の12桁
IMAGE コンテナの元イメージ名
COMMAND 起動時に与えられたコマンド(起動時に末尾で指定したもの)
CREATED コンテナの作成日からの経過時間
STATUS 起動・停止のステータス
PORTS バインドしているポート(ホスト側8080:コンテナ側80)
NAMES コンテナの名前(起動時に--nameで指定したもの)

起動中コンテナへのログイン

$ docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

上記のcf4beeb4be04コンテナにログインしてみます。

$ docker exec -it cf4beeb4be04 /bin/bash

コンテナの停止

$ docker stop [OPTIONS] CONTAINER [CONTAINER...]

先ほど起動したコンテナを停止してみます。

$ docker stop 5b43901894115d72415d265488225b957050accffcb27ce16382c97479be1d75

停止中コンテナの起動

$ docker start [OPTIONS] CONTAINER [CONTAINER...]

先ほど停止したコンテナを起動してみます。

$ docker start 5b43901894115d72415d265488225b957050accffcb27ce16382c97479be1d75

コンテナの削除

$ docker rm [OPTIONS] CONTAINER [CONTAINER...]

test01コンテナを削除してみます。

$ docker rm test01

再度docker psコマンドを実行してみます。

CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                      PORTS               NAMES
cf4beeb4be04        httpd               "httpd-foreground"   17 minutes ago      Exited (0) 4 minutes ago                        pedantic_cohen

削除されていることがわかります。

イメージの削除

docker rmi [OPTIONS] IMAGE [IMAGE...]

先ほどのhttpdイメージを削除してみます。
docker imagesで表示されるコンテナIDを指定します。

docker rmi 0a30f4c29d25

再度docker imagesで削除されていれば完了です。

最後に

今回はUbuntu 18.04上に、Dockerをインストールし、Dockerの基本の「キ」レベルのコマンドをまとめてみました。
今後は構築をしながら気づいたことをまとめていきたいなと思います。

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

さくっとdocker/nginx

概要

さくっとdockerでnginx/Hello Worldしたいときのメモ

用途

CloudRunやFargateでのHello Worldなど。。。

準備

ディレクトリー構成

.
├── Dockerfile
├── index.html
└── nginx.conf
Dockerfile
FROM nginx:latest

COPY ./index.html /usr/share/nginx/html

EXPOSE 80
nginx.conf
server {
    listen       80;
    server_name  hello_nginx;

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

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>nginx</title>
</head>
<body>
  <h1>Hello World</h1>
</body>
</html>

コマンド

# ビルド
$ docker build --tag hello-nginx .
# 確認
$ docker images -a hello-nginx
# 起動
$ docker run -d --name hello-nginx-container -p 80:80 hello-nginx
# 停止
$ docker stop hello-nginx-container
# 削除
$ docker rm hello-nginx-container

備考

毎回忘れてしまう。。。

サンプル
https://github.com/koffe0522/docker-nginx

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

【Rails6.0, Docker】ポートフォリオを作るために必要なDocker環境構築とコマンドをまとめてみた

筆者がRailsでポートフォリオを作る際に必要だったコマンドや環境構築についてまとめたいと思います。あくまでポートフォリオ作成レベルで必要なものになります。

概要

  1. docker-composeを扱う上でよく使うコマンド
  2. 各種ファイルの記載 (Dockerfile, docker-compose.yml, database.yml)

1. docker-composeを扱う上でよく使うコマンド

railsコマンド(rails g model userやrails db:migrateなど)

terminal
$ docker compose run --rm web <railsコマンド>

--rmオプションは実行後、コンテナを削除するコマンド。これをつけないと不要なコンテナができてしまい、メモリを圧迫してしまうため必ずつける。

標準入出力へ接続(ローカルで開発するときにterminalに表示されるもの)

terminal
$ docker attach <webサーバのコンテナ名>

サーバーでの標準入出力に接続し通信状況を見れる。binding.pryでデバックをする場合もこのコマンド。
きちんとした処理ででデタッチする。(ctrl + Cするとコンテナが落ちてしまう)

Ctrl + P, Ctrl + Q

データベース(mysql)へ接続

terminal
$ docker exec -it <dbのコンテナ名> bash

コンテナの中から

terminal
$ mysql -u root -p

Dockerイメージを作成し、コンテナを起動し実行する。

terminal
$ docker-compose stop
# Dockerfileまたはdocker-compose.yml修正後
$ docker-compose up -d --build

Dockerfileやdocker-compose.ymlを修正したとき用。

削除コマンド

--rmオプションを付けていても開発しているといらないコンテナやイメージが溜まっていきます。ここからはそれらを削除するコマンドです。

停止コンテナ、タグ無しイメージ、未使用ボリューム、未使用ネットワークを一括削除

terminal
docker system prune

※ 使用中のvolumeは削除されないので大丈夫。
※ 複数プロジェクトが走っている場合は非推奨

停止中のコンテナ一括削除

terminal
docker container prune

未使用のイメージ一括削除

terminal
docker image prune

各種ファイルの記載

Dockerfile

まずはDockerfile。まずは公式のDocumentに目を通す。
https://docs.docker.com/compose/rails/

Dockerfile
FROM ruby:2.7.1

# Debianのインストール
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq && apt-get install -y nodejs yarn imagemagick mariadb-client vim

RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

yarnのインストール

rails6.0からJavaScriptコンパイラがwebpackerに変更され、webpackerの導入に必要なパッケージマネージャであるyarnをインストール

ImageMagickのインストール

画像アップロード用にMiniMagicが使いたかったためインストール。
Rails アプリで MiniMagick を使おうとすると Rails アプリを実行している環境に ImageMagick をインストールする必要がある。以下はminimagicのReadMeより

ImageMagick or GraphicsMagick command-line tool has to be installed. You can check if you have it installed by running

mariadb-clientのインストール

rails db:consolを使いたい場合はインストール。
mysql-clientと書かれている記事もあるが、現在はmariadb-clientに統一されているため注意
データベースへは上述のコマンドでアクセスできるため不要かも

vimのインストール

エディターは何かと必要になるためインストールしておく。筆者は本番環境へアプリをデプロイした後、下コマンドでcredentials.yml.encを編集したかったのですが、その際にvimを使いました。

terminal
$ docker-compose run -e EDITOR=vim web rails credentials:edit

docker-compose.yml

お次はdocker-compose.yml

docker-compose.yml
version: "3"
services:
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 4306:3306

    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql

  web:
    build: .
    tty: true
    stdin_open: true
    # rails sした際に、A server is already running.というエラーが出ることがある。これを防ぐため、rm -f tmp/pids/server.pidしている。
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
      - bundle:/usr/local/bundle
    ports:
      - "3100:3000"
    depends_on:
      - db

volumes:
  bundle:
    driver: local
  mysql-data:
    driver: local

ポート番号設定

docker-compose.yml
db
  ports:
    - 4306:3306
web
  ports:
    - 3100:3000

左側がホストマシンのポート番号で、右側がコンテナのポート番号。
ホストでMySQLが(LISTEN)の場合やlocalhost:3000を使いたい場合は、使用するポートが重複するためマシンの使用するポート番号を4306、3100にそれぞれ設定。かぶらなければ3307でも10000でも何でも可

mysqlの認証方式を変更

docker-compose.yml
command: --default-authentication-plugin=mysql_native_password

MySQL8.0からデフォルトの認証方式が変更された(caching_sha2_password)が、まだRailsアプリが対応していないため、mysql_native_passwordに戻す。

標準入力の有効化

docker-compose.yml
tty: true
stdin_open: true

デバック用に非常に重要。これをしないとbinding.pryなどができないです。

tty: true

docker runの -tオプションに相当し、擬似端末を有効にする設定。有効にしても入力できないため、下のstdin_open: trueが必ずセットでついてくる。

stdin_open: true

docker runの -iオプションに相当し、標準入力を繋ぎっぱなしにする設定。これによりコマンド実行が可能になる。

コンテナの起動順序を制御

docker-compose.yml
depends_on:
      - db

depends_onでコンテナが起動する順番を制御する(この場合、db→web)

Data Volumeコンテナの作成

docker-compose.yml
volumes:
  bundle:
    driver: local
  mysql-data:
    driver: local

通常、コンテナを作り直すとbundle installしたファイルやデータベースのデータはすべて消えるため、再度buildしたりデータの登録を行わなければならない。それはあまりにも面倒なため、Data Volumeコンテナを使う。Data Volumeコンテナはデータだけを持つコンテナで、コンテナ間で共有する仕組みを使う。これをbundle, mysql-dataという名前で作る設定が上記になる。

volumeへマウント

docker-compose.yml
volumes:
  - mysql-data:/var/lib/mysql
volumes:
  - .:/myapp
  - bundle:/usr/local/bundle

先程作ったData Volumeコンテナを使ってデータの永続化を行います。これで、コンテナを破棄してビルドし直してもデータベースのデータはそのままで、かつGemがインストールされすぐに使える状態となります。

database.yml

最後にdatabase.yml

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch("MYSQL_USERNAME", "root") %>
  password: <%= ENV.fetch("MYSQL_PASSWORD", "password") %>
  host: <%= ENV.fetch("MYSQL_HOST", "db") %>

development:
  <<: *default
  database: myapp_development

文字コード

database.yml
encoding: utf8mb4

データベースに絵文字を登録したかったので、文字コードをutf8ではなくutf8mb4にしています。

何か他に便利な設定やコマンドがあれば教えてください^^

参考

https://docs.docker.com/compose/rails/
Docker/Kubernetes実践コンテナ開発入門
https://qiita.com/neko-neko/items/abe912eba9c113fd527e
https://qiita.com/chisaki0606/items/68e21d9a31f1eaaeac00
https://qiita.com/nsy_13/items/9fbc929f173984c30b5d

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

【備忘録】ubuntuにてdockerインストールからJupyterLab起動までの流れ

はじめに

VPSサーバのubuntu内にdokcerをインストールして、jupyterlabの起動までを行います

前提

今回はAWSのlightsailを用いてubuntu環境を用意しました 
https://qiita.com/s-inoue-git/items/1bcf1a28ed73090c3d86

目次

  1. dockerインストール
  2. Dockerfileの転送
  3. containerの起動

1. dockerのインストール

sudo apt-get update
#sudo apt-get install docker.io #古いバージョンがインストールされてしまう
sudo apt-get install docker-ce
docker --version
#Docker version 19.03.8, build afacb8b7f0

バージョン情報が確認できればインストールの成功です!
※docker.ioとdocker-ceの違い
https://qiita.com/nnagashima/items/79887825ce9d7c8b24ab

dockerコマンドのたびにsudoを入力するのが面倒なため、ユーザ(ubuntu)をdocker groupのなかに加えます

sudo gpasswd -a ubuntu docker
#Adding user ubuntu to group docker
exit
#ログアウトしないとグループの追加が反映されません

2. Dockerfileの転送

#sftp接続
sftp -i ~/.ssh/Lightsail_ubuntu_20201123.pem ubuntu@3.112.200.82
sftp> put Dockerfile

今回は以下チュートリアルで作成したDockerfileを転送しました
https://qiita.com/s-inoue-git/items/2b5c65a1f11a1ba4a38e

3. containerの起動

docker runのコマンドを実行

docker run -v $(pwd)/volume:/home/work -p 8888:8888 --name anaconda-env -it anaconda-img

あとは、ファイヤウオールの設定を変更して、どこからでもアクセスできるようにすれば、「パブリックIP:ポート番号」でアクセスできるようになります
今回は学習用なのでセキュリティー設定ガバガバです。。。
image.png

jupyter-labにアクセスできれば完了です!
image.png

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

Docker コンテナで x11 アプリを動かす (コンテナからのネットワークアクセス対応)

Docker コンテナで x11 アプリを動かす (コンテナからのネットワークアクセス対応)

Docker コンテナ上で動く X11 アプリケーションのウィンドウをディスプレイに表示させる という記事で xeyes を動作させることができたのですが、

以下のように --net host を指定しています。

$ docker run --rm -it \
    --net host \
    -e DISPLAY=$DISPLAY \
    -v $HOME/.Xauthority:/root/.Xauthority \
    xeyes

--net host は docker host と docker container の間だけで通信できるネットワークを利用します。

なので、 docker container からインターネットに接続したい場合には使用することができません。

この記事では、container からネットワークにアクセスできてかつ X11 アプリを使えるようにします。

Dockerfile

オリジナル との違い

  • xeyes を直接 CMD で起動していましたが、ネットワークアクセスを試すために /bin/bash を起動します。
  • bash を image にインストールします。

conf/Dockerfile の中身

FROM alpine

RUN apk --no-cache add bash xeyes

CMD ["/bin/bash"]

docker image のビルド

docker build -t xeyes conf

local ユーザーのみ X の接続を許可する

xhost +local:

container の起動

オリジナル との違い

  • 環境変数 DISPLAYunix${DISPLAY} を渡す。
  • /tmp/.X11-unix-v でホストと共有する。
docker run --rm -it \
    -e DISPLAY=unix${DISPLAY} \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $HOME/.Xauthority:/root/.Xauthority \
    xeyes

コンテナからのネットワークアクセス確認

bash-5.0# ping www.example.com
PING www.example.com (93.184.216.34): 56 data bytes
64 bytes from 93.184.216.34: seq=0 ttl=51 time=149.040 ms
64 bytes from 93.184.216.34: seq=1 ttl=51 time=172.391 ms
64 bytes from 93.184.216.34: seq=2 ttl=51 time=195.793 ms
^C
--- www.example.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 149.040/172.408/195.793 ms

コンテナから x11 アプリを起動

bash-5.0# xeyes

エラーメッセージ

xhost +local: を実施していない場合、以下のエラーになります。

bash-5.0# xeyes 
No protocol specified
Error: Can't open display: unix:0

GitHub

GitHub にこの記事で書いた Dockerfile やスクリプトなどを置いています。

https://github.com/m-tmatma/xeyes-docker

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

dockerメモ

はじめに

この記事は、自分がdockerでよく利用したコマンドを自分用に書き残したものです。

環境

  • macOS Catalina 10.15.7
  • Docker version 19.03.13

Dockerイメージの取得

DockerHub等からimageを取得する。

docker pull ubuntu

イメージの確認

取得したイメージをimagesで取得。

docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu-python       latest              91d4b5ba1c2d        4 weeks ago         605MB
ubuntu              18.04               56def654ec22        8 weeks ago         63.2MB

上記の場合、ubuntuとubuntu-pythonというimageがある。

imageの削除

docker rmi [imageID or image名]

ubuntu-pythonを消す場合、

docker rmi ubuntu-python
docker rmi 91d4b5ba1c2d
docker rmi 9

で消すことができる。
IDは前方一致のため、最後のコマンドでは9から始まるimageIDを持つimageがすべて削除される。

Dockerfileからimageを作成

docker build -t [image名]:[TAG名] [Dockerfileのディレクトリ] 

コンテナ(停止した)からimageを作成

docker commit [コンテナ名 or コンテナID] [image名]:[TAG名]

コンテナの起動

作成したimageからコンテナを起動する。

docker run -itd --name [コンテナ名 or コンテナID] [image名]

よく利用するオプションについて

--name [コンテナ名]は省略できますがランダムで名前がつけられます。
-it 標準入出力をコンテナに結びつける(キー入力する場合)。
-d コンテナをバックグランドで実行
-p [ホストのポート]:[コンテナのポート]

コンテナ作成時にボリュームをマウントしたい場合、
(以下例はカレントディレクトリをマウント)

docker run --name myubuntu -itd \
--mount type=volume,src=$(pwd),dst=/vol ubuntu /bin/bash

(-v [ホストDIRの絶対パス]:[コンテナの絶対パス])
上記(-v)の場合、volumeかbindのどちらでマウントされているのかわからない。
ホストとコンテナ間でデータを同期させたいとき(非推奨)は、
--mount type=bind,src=<パス>,dst=<パス>
コンテナにボリュームをマウントしたいときは、
--mount type=volume,src=<ボリューム名>,dst=<パス>

 コンテナの確認

docker ps 

docker ps -aで停止しているものもすべて表示
docker ps -aqで停止しているコンテナも含めコンテナIDを表示

コンテナの停止、再スタート、削除

docker stop [コンテナ名 or コンテナID]  #停止
docker start [コンテナ名 or コンテナID]  #再スタート
docker rm [コンテナ名 or コンテナID]     #削除

コンテナをすべて削除したい場合、

docker rm $(docker ps -aq)

コンテナにログイン

作成したコンテナにログインしてshellを起動する。

docker exec -it [コンテナ名 or コンテナID] bash

コンテナから抜け出す

Ctrl + D または exit と入力すると抜け出せます。

root@b789a85f6d39:/# exit

ログの出力

dockerアプリで出たログを出力して見る。

docker logs [コンテナ名 or コンテナID]

コンテナ情報の確認

指定コンテナに関する全ての情報を取得。

docker inspect [コンテナ名 or コンテナID]

基本的には一部の情報しかいらないので、
--format optionでピンポイントで出力する。

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [コンテナ名 or コンテナID]
## コンテナに割り振られているIPアドレスの取得

--format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
でNetworkSettings.Networks内のIPAddressを取得している。

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

OpenProject on AWS ECS その2

OpenProjectが公開しているdocker-compose.ymlをAWS ECSにデプロイしてみました その2

以前OpenProject on AWS ECSという記事で、ecs-cliを使ってECSにOpenProjectをデプロイしてみたんですが、今回は同じことをdockerのECS拡張を使ってやってみました。
OpenProjectのもともとの構成ではmemcachedとpostgresqlもコンテナ動作させてますが、そこは個人の趣味でマネージドサービスを使用しています。

dockerのECS拡張とは

2020/7に発表された拡張機能です。AWS and Docker collaborate to simplify the developer experienceにあるとおり、dockerクライアントで直接ECS上のコンテナを操作できるという代物です。docker-composeも使用可能になってます。

以前のデプロイ方法の困ったところまとめ

  • ecs-cliがdocker-composeのver3.xに対応していないため、凝った作りのdocker-compose.ymlの場合はかなりの部分を編集しなければならない
  • fargateへのデプロイが困難
  • コンテナ間依存の記述が困難

コマンド実行環境インストール概要

Deploying Docker containers on ECSの通り作業して、コマンド実行環境を作ります。

awscli

Ubuntu 20.04でコマンド実行環境を作りました。まずaws cliをインストールし、credential設定します。
なお、以下のIAM権限が必要でした。

  • EC2
  • IAM
  • ElasticLoadBalancing
  • CloudMap
  • ElasticFileSystem
  • CloudFormation

その他に、以下の権限も与えてましたが、docker compose upに必要かどうかは未確認です。

  • ECS
  • CodeDeploy
  • CloudWatchLogsFullAccess

docker-cli

docker-ceおよびdocker-composeをインストールしました。
マニュアルにあるとおり、AWS contextを設定してやる必要があります。

その他AWS環境

postgresqlとmemcached

リージョン内にpostgresqlとmemcachedのマネージドサービスを作成しておきます。postgresqlのユーザとパスワードは、docker-compose.yml記載のものをそのまま使って作成しました。
接続先情報はdocker-compose.ymlに記述します。

default VPC

default VPCがリージョンに存在している必要があります。普通あるとは思いますが、何かの理由で消してしまった場合は作成しておいてください。

docker-compose-yml

dockerのECS拡張では、docker-compose.ymlファイルをcloudformationに食わせるように変換して、cloudformation経由でECS環境を作るということをやっています。

まず、OpenProjectのマニュアル通りdocker-compose.ymlファイルを入手します。

> git clone https://github.com/opf/openproject-deploy --depth=1 --branch=stable/11 openproject

このファイルに対して修正します。
最終的に使用したdocker-compose.ymlは以下の通りとなりました。

docker-compose.yml
version: "3.7"                                                                                                                                                                                       

networks:                                                                                                                                                                                            
  frontend:                                                                                                                                                                                          
  backend:                                                                                                                                                                                           

volumes:                                                                                                                                                                                             
  opdata:                                                                                                                                                                                            

x-op-restart-policy: &restart_policy                                                                                                                                                                 
  restart: unless-stopped                                                                                                                                                                            
x-op-image: &image                                                                                                                                                                                   
  image: openproject/community:${TAG:-11}                                                                                                                                                            
x-op-app: &app                                                                                                                                                                                       
  <<: *image                                                                                                                                                                                         
  <<: *restart_policy                                                                                                                                                                                
  environment:                                                                                                                                                                                       
    RAILS_CACHE_STORE: "memcache"                                                                                                                                                                    
    OPENPROJECT_CACHE__MEMCACHE__SERVER: "cache.yyyy.cfg.usw2.cache.amazonaws.com:11211"                                                                                                           
    OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}"                                                                                                            
    DATABASE_URL: "postgres://postgres:p4ssw0rd@openproject.xxxxx.us-west-2.rds.amazonaws.com/openproject"                                                                                    
    USE_PUMA: "true"                                                                                                                                                                                 
    # set to true to enable the email receiving feature. See ./docker/cron for more options                                                                                                          
    IMAP_ENABLED: "${IMAP_ENABLED:-false}"                                                                                                                                                           
  volumes:                                                                                                                                                                                           
    - "opdata:/var/openproject/assets"                                                                                                                                                               

services:                                                                                                                                                                                            
  proxy:                                                                                                                                                                                             
    <<: *image                                                                                                                                                                                       
    <<: *restart_policy                                                                                                                                                                              
    command: "./docker/proxy"                                                                                                                                                                        
    ports:                                                                                                                                                                                           
      - "${PORT:-8080}:80"                                                                                                                                                                           
    environment:
      APP_HOST: web
      OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}"
    depends_on:
      - web
    networks:
      - frontend

  web:
    <<: *app
    command: "./docker/web"
    networks:
      - frontend
      - backend
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 2048M

  worker:
    <<: *app
    command: "/bin/sh -c './docker/worker && /bin/sh'"
    networks:
      - backend

  cron:
    <<: *app
    command: "./docker/cron"
    networks:
      - backend

3.7の記法をそのまま使えるため、大幅に楽になりました。
オリジナルとの差分は以下の通りです。

  • dbコンテナ削除に伴う対応
    • volume削除
    • 接続先設定変更
    • 依存関係でのdb削除
    • service dbの削除
  • cacheコンテナ削除に伴う対応
    • 接続先設定変更
    • 依存関係でのdb削除
    • service cacheの削除
  • seederコンテナ削除に伴う対応
    • service seederの削除
    • 依存関係でのseeder削除
  • essential設定が出来ないことへの対応
    • workerコンテナのコマンドを修正
  • webコンテナの使用リソース設定
    • CPUとメモリの設定を追加

下の3つについて説明します。

「seederコンテナ削除に伴う対応」
seederコンテナというのは、compose up時に動作してDBの初期化を行ったのち、常駐せずにexitするコンテナです。
ECS環境ではこういうコンテナにはessential = falseという設定を入れてやらないといけないのですが、docker-compose.ymlへのessential設定の方法がマニュアルやサンプルで説明されていません。
また、seederがモタモタ動いているうちに環境全体が終了してしまうという事態が頻発したため、DB設定のためseederだけ動かすdocker-compose.ymlを作成したあと、上に引用のdocker-compose.ymlを使って最終的な環境を作るということにしました。

「essential設定が出来ないことへの対応」
上述の通り、seederコンテナは常駐しないのですが、他にもそういう動作をしているらしきコンテナ(worker)がいます。終了してしまわないように、コマンドに手を入れています。(不要かもです)

「webコンテナの使用リソース設定」
デフォルトで各コンテナはCPU 256ms/Memory 512MBというlimit設定で起動してきますが、これだとWebコンテナがまともに動作しなかったため、このコンテナだけは多めにリソースを積みました。記法はサンプルの通りです。

その他

環境変数

デフォルトではproxyコンテナは8080番をbindしているんですが、fargateでは?動作しませんでしたので、docker compose up実行時に以下の環境変数を設定して、コンテナと同一ポートを使用するようにしました。

> set -x PORT 80 

コンバート

cloudformationに食わせているファイルは、以下の方法で確認できます。

> docker compose convert

まとめ

オリジナルに対してかなり手をいれてますが環境設定のための編集がほとんどで、基本的には3.x記法をそのまま使えるためecs-cliを使うよりはかなり楽になりました。
以前のデプロイ方法の困ったところまとめはクリア出来てます。
docker-compose.ymlを使ってECSにサービスをデプロイしたい場合はぜひ試してみてください。

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

Code for Japanに飛び込んで、GitHub ActionsでElastic BeanstalkへのCI/CDを構築した流れ

背景

コロナで外出しづらくなったこともあり、以前から興味のあったCode for Japanに参加しました。

今回のプロジェクトは、Ruby on Railsでした。私は、Ruby初心者なので、コンテナやAWSまわりの足回りを固めるために活動してます。

私が、プロジェクトの参加からCI/CD構築までの流れを紹介します。興味がある方の参考になると嬉しいです。

3文まとめ

  • Code for Japanに参加するのは簡単
  • 当然だけど、AWSを触るのはNDAが必要
  • GitHub ActionsでCI/CDを構築するは簡単

Code for Japan プロジェクト参加のきっかけ

東京都のコロナ対策サイトで気になって、ROM専でSlackにいました。

Slack コミュニティ - Code for Japanから、気軽に参加できます。

たまたま、slack上でメンバーの募集を見かけ、市民の政治参加に興味があり参加しますと声を掛けました。
Ruby初心者でしたが、心よく受け入れて頂きました。笑

参加したDIY City プロジェクト(市民参加型合意形成プラットフォーム)

地域で暮らす人たちや、その地域を愛する人たちが主役になり、自分たちでどんなまちにしたいのか、そのためにどんなことが必要なのかを考え、手を動かし、自分たちでつくっていく都市です。できるだけ多様な人がまちづくりに関わり、「要望する」のではなく「つくる」側として参画します。

DIY 都市を作ろう|Hal Seki|note

上記のような構想をもとに、市区町村と協力してサービスを提供するプロジェクトです。市民が積極的に参加することで、より良い町づくりを目指します。

日本では、加古川市で2020/11から本稼働しています。

加古川市 市民参加型合意形成プラットフォーム

OSS decidim

上記のサイトは、Decidim (Free Open-Source participatory democracy for cities and organizations)をベースに構築されています。Ruby on railsで構築されており、これにパッチ修正をあてて稼働しています。翻訳など本家に取り込んでも問題ないものは、本家を修正しています。

このOSSで数年前から、バルセロナヘルシンキなどいくつかの複数の都市で運用されています。都市ごとに、カスタマイズされており、どれも個性的で興味深いです。

バルセロナでは、うまく軌道にのり、下記のような成果が出ているようです。

2016年から2019年の3年間で、すでに市民の70%が登録しており、9000以上の市民からの新たな政策提案が集まっている

「シティOS」で市民に還元。バルセロナが本当にスマートな理由

NDA締結

今回、CI/CD構築のため、AWSを触るので、NDA締結が必要でした。
一般的な内容で、クラウドサインで締結しました。

※私が勤めている弁護士ドットコムのサービスを使ってくれていました。

CI/CD概要

GitHub Actions aws eb deploy.png

既にソースコードをGitHubで管理していたので、GitHub上で完結するGitHub Actionsを採用しました。

ユーザーがGitHubにコードをcommit pushすると、GitHub ActionsでイメージをBuildして、ECRにpush。その後、AWS ECRを使用してElastic Beanstalkにデプロイする非常にシンプルなパイプラインです。

AWS ECR作成

ECRは、Cloud Formationで作成しました。

AWSTemplateFormatVersion: "2010-09-09"
Description: Create ECR

Resources:
  TestEcrPoc:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryName: hoge
      ImageScanningConfiguration:
        scanOnPush: "true"
      ImageTagMutability: "MUTABLE"
      LifecyclePolicy:
        LifecyclePolicyText: |
          {
            "rules": [
              {
                "rulePriority": 1,
                "description": "Delete image without tag after 7 days",
                "selection": {
                  "tagStatus": "untagged",
                  "countType": "sinceImagePushed",
                  "countUnit": "days",
                  "countNumber": 7
                },
                "action": {
                  "type": "expire"
                }
              }
            ]
          }

イメージスキャン

イメージスキャン - Amazon ECRを有効化しています。Pushするたびに、スキャンされます。

イメージスキャンは、オープンソースのClairプロジェクトからCommon Vulnerabilities and Exposures(CVE)データベースを使用してスキャンし、GUI上から結果を確認できる機能です。

ライフサイクルポリシー

タグなしのイメージだけ、7日経過後に削除するライフサイクルポリシーを設定しています。
ライフサイクルポリシーだけJSONで記述する必要があります。yamlの中なので、補完が効かず書きづらいですが、仕方がありません。

AWS IAMユーザーの作成

Elastic Beanstalkのアクセス権だけでなく、上記で作成したECRへのReadWriteアクセスも必要です。

GitHub Actionsで使うSecretsの設定

GitHubでは、レポジトリごとにSecretsが設定できます。

それを使用して、下記のキーで、上記で作成したIAMのアクセス情報とECRのレポジトリ名を保存します。
レポジトリ名は場合によっては、Secretsでなくてもいいと思います。

AWS_ACCESS_KEY_ID: *********************
AWS_SECRET_ACCESS_KEY: *********************
AWS_ECR_REPO_NAME: hoge

AWS ECRへのイメージのpush

github/workflows/deploy.yml
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build, tag, and push image to Amazon ECR
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }}
          IMAGE_TAG: staging
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

AWS ECRへのログイン & Push

公式で、下記のActionが提供されているので、非常に簡単にpushできます。

aws-actions/amazon-ecr-login: Logs into Amazon ECR with the local Docker client.

Dockerrun.aws.jsonの作成

/deployments/Dockerrun.aws.json
{
    "AWSEBDockerrunVersion": "1",
    "Logging": "/app/log",
    "Image": {
        "Name": "{RepositoryName}",
        "Update": "true"
    },
    "Ports": [
        {
            "ContainerPort": "3000"
        }
    ]
}

${RepositoryName}はデプロイ時に、タグ付きのレポジトリ名にリプレイスします。

あえてdeploymentsディレクトリを掘って、その下に置いています。同じ階層にDockerfileがあると、そちらが優先されてしまうためです。また、デプロイ時にDockerrun.aws.jsonだけをzipすることで転送量を減らすのが狙いです。

Loggingセクションに コンテナ内のディレクトリを指定することで、ebの管理下にあるLogディレクトリにログを出力できます。
またGUI上のコンソールからLogの閲覧も可能になります。

AWS Elastic Beanstalkへのデプロイ

github/workflows/deploy.yml
      - uses: actions/setup-python@master
        with:
          python-version: "3.7"

      - name: Install awsebcli
        run: pip install -U awsebcli

      - name: Deploy to Elastic Beanstalk
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }}
          IMAGE_TAG: staging
          EB_ENVIRONMENT_NAME: staging
        run: |
          cd deployments
          sed -i -e "s|{RepositoryName}|$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG|g" Dockerrun.aws.json
          eb deploy ${EB_ENVIRONMENT_NAME}

今回は、極力公式のActionだけにしたかったので、有志のBeanstalk Deploy · Actions · GitHub Marketplaceを使用しませんでした。要件次第では、使った方が楽だと思います。

eb コマンドを使用しているので、python環境の構築後にコマンドのインストールを行っています。

まとめ

GitHub Actionsを使用することで、比較的簡単にパイプラインが構築できました。

デジタル庁の民間登用やCode for Japanの東京都コロナ対策サイト、COCOAなどを契機に、一般市民がテクノロジーを活用して、行政サービスの問題や社会課題を解決するCivitechはこれから盛り上がっていくと思います。

コードの全体は、codeforjapan/decidim-cfj: Code for Japan Decidimにあります。

ぜひあなたのコントリビュートをお待ちしております。

参考

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

【Rails6】Active Job + Sidekiqを動かしてみた

Railsの非同期処理をActive Job + Sidekiqで実装したのでメモを残します。

※RailsアプリケーションはDocker環境で構築済みの前提です。環境構築はこちら

※Active Jobとバックエンドの比較はこちら

環境

  • Ruby 2.7.2
  • Rails 6.0.3.4
  • MySQL 8.0.20
  • Redis 6.0.9
  • Sidekiq 6.1.2
  • Docker version 19.03.13

1. Redisの導入

まずredisコンテナを用意します。
ポート番号はdocker-compose.override.ymlで指定していますが、下記で設定して問題ないと思います。

docker-compose.yml
version: '3.7'

services:
  db:
    image: mysql:8.0.20
    volumes:
      - mysql:/var/lib/mysql:delegated
    command: --default-authentication-plugin=mysql_native_password
    env_file: .env

  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    tty: true
    stdin_open: true
    env_file: .env
    depends_on:
      - db
      - chrome
      - redis
    volumes:
      - .:/app:cached
      - bundle:/usr/local/bundle:delegated
      - node_modules:/app/node_modules

  chrome:
    image: selenium/standalone-chrome:3.141.59
    volumes:
      - /dev/shm:/dev/shm

  redis:
    image: redis:6.0.9
    env_file: .env
    command: redis-server --appendonly yes
    volumes:
      - redis:/data

volumes:
  mysql:
  bundle:
  node_modules:
  redis:
docker-compose.override.yml
version: '3.7'

services:
  db:
    ports:
      - 3306:3306
  web:
    ports:
      - 3000:3000
  chrome:
    ports:
      - 4444:4444
  redis:
    ports:
      - 6379:6379

Redisの設定ファイルを追加します。
host名に注意してください。

config/redis.yml
default: &default
  db:
    sidekiq: 0
    # cache:   1
    # session: 2

development:
  <<: *default
  host: redis

test:
  <<: *default
  host: redis

2. Sidekiqの設定

まずはGemを追加します。
ruby:Gemfile
gem 'sidekiq'

bundle installを実行し、設定ファイルを追加します。
詳しくは、こちらを参照してください。

config/sidekiq.yml
:verbose: false
:max_retries: 1
:concurrency: 10
:pidfile: ./tmp/pids/sidekiq.pid
:logfile: ./log/sidekiq.log
:queues:
  - development_default

続いてSidekiqとRedisの接続情報も追加します。

config/initializers/sidekiq.rb
redis_config = YAML.load_file('config/redis.yml')[Rails.env]
redis_config['db'] = redis_config['db']['sidekiq']

Sidekiq.configure_server do |config|
  config.redis = {
    url: "redis://#{redis_config['host']}/#{redis_config['db']}"
  }
end

Sidekiq.configure_client do |config|
  config.redis = {
    url: "redis://#{redis_config['host']}/#{redis_config['db']}"
  }
end

ダッシュボードのルーティングも設定します。

config/routes.rb
require 'sidekiq/web'

Rails.application.routes.draw do
  mount Sidekiq::Web, at: '/admin/sidekiq', as: :sidekiq
end

3. Active Jobの設定

Active Jobで非同期処理を実装していきます。

config/application.rb
require "active_job/railtie"

module App
  class Application < Rails::Application
    config.active_job.queue_adapter = :sidekiq
    config.active_job.queue_name_prefix = Rails.env # これは任意
  end
end

4. ジョブの作成と動作確認

ようやくジョブを作成します。

rails g job sample
app/jobs/sample_job.rb
class SampleJob < ApplicationJob
  queue_as :default

  def perform
    puts '--------------------------------'
    puts '------------  Test  ------------'
    puts '--------------------------------'
  end
end

続いて動作確認を行います。
dockerコンテナを起動し、RailsとRedisが動いていることを確認します。
コンテナ内でsidekiqを起動します。

$ bundle exec sidekiq -C config/sidekiq.yml

2020-11-23T07:06:57.513Z pid=74 tid=9om INFO: Booting Sidekiq 6.1.2 with redis options {:url=>"redis://redis/0"}


               m,
               `$b
          .ss,  $$:         .,d$
          `$$P,d$P'    .,md$P"'
           ,$$$$$b/md$$$P^'
         .d$$$$$$/$$$P'
         $$^' `"/$$$'       ____  _     _      _    _
         $:     ,$$:       / ___|(_) __| | ___| | _(_) __ _
         `b     :$$        \___ \| |/ _` |/ _ \ |/ / |/ _` |
                $$:         ___) | | (_| |  __/   <| | (_| |
                $$         |____/|_|\__,_|\___|_|\_\_|\__, |
              .d$$                                       |_|


2020-11-23T07:06:57.938Z pid=74 tid=9om INFO: Booted Rails 6.0.3.4 application in development environment
2020-11-23T07:06:57.939Z pid=74 tid=9om INFO: Running in ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
2020-11-23T07:06:57.939Z pid=74 tid=9om INFO: See LICENSE and the LGPL-3.0 for licensing details.
2020-11-23T07:06:57.939Z pid=74 tid=9om INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org
2020-11-23T07:06:57.946Z pid=74 tid=9om INFO: Starting processing, hit Ctrl-C to stop

別タブのターミナルでRailsコンソールからSampleJobをキューイングしてみます。

$ rails c
Loading development environment (Rails 6.0.3.4)
> SampleJob.set(wait: 5.second).perform_later

Enqueued SampleJob (Job ID: fdcf5c60-3542-4b26-bfd2-9662ffafada9) to Sidekiq(development_default) at 2020-11-23 07:08:49 UTC
=> #<SampleJob:0x00005567e535e4c0
 @arguments=[],
 @exception_executions={},
 @executions=0,
 @job_id="fdcf5c60-3542-4b26-bfd2-9662ffafada9",
 @priority=nil,
 @provider_job_id="7c42f602bd499e75efecad26",
 @queue_name="development_default",
 @scheduled_at=1606115329.3860393>
>

キューイングすると先ほど起動したSidekiq側でジョブが実行されたことが確認できました。

2020-11-23T07:08:52.800Z pid=74 tid=b6y class=SampleJob jid=7c42f602bd499e75efecad26 INFO: start
--------------------------------
------------  Test  ------------
--------------------------------
2020-11-23T07:08:53.067Z pid=74 tid=b6y class=SampleJob jid=7c42f602bd499e75efecad26 elapsed=0.267 INFO: done
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker環境でlsb_releaseがエラーになる時にコマンドラインからlsb_releaseをインストールする

docker環境でlsb_releaseがエラーになる時

# lsb_release -sc
bash: lsb_release: command not found

以下の通り、コマンドラインからlsb_releaseをインストールする

apt-get update -y;apt-get install -y lsb-release;
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GO環境でimport Cエラー

エラー発生

Goのgraphqlライブラリのgqlgenでスキーマを更新しようとしたら謎のエラー

/go/src # go run github.com/99designs/gqlgen
validation failed: packages.Load: /usr/local/go/src/net/cgo_linux.go:12:8: could not import C (no metadata for C)
exit status 1

解決

どうやらgccがdockerイメージ上に入ってない模様。

apk updateしてapkをアップデートした後、alpine-sdkというビルドパッケージ?を入れたらうまく行きました。
apkについては、この記事が分かりやすかったです。

/go/src # apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz

fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
v3.12.1-44-g754f23ac8f [http://dl-cdn.alpinelinux.org/alpine/v3.12/main]
v3.12.1-41-g42f619918d [http://dl-cdn.alpinelinux.org/alpine/v3.12/community]
OK: 12746 distinct packages available
/go/src # apk add alpine-sdk
(1/37) Upgrading musl (1.1.24-r9 -> 1.1.24-r10)
  0%                                                                                                                                                                                                                   
(2/37) Installing fakeroot (1.24-r0)
(3/37) Installing openssl (1.1.1g-r0)
(4/37) Installing libattr (2.4.48-r0)
(5/37) Installing attr (2.4.48-r0)
(6/37) Installing libacl (2.2.53-r0)
(7/37) Installing tar (1.32-r1)
(8/37) Installing pkgconf (1.7.2-r0)
(9/37) Installing patch (2.7.6-r6)
(10/37) Installing libgcc (9.3.0-r2)
(11/37) Installing libstdc++ (9.3.0-r2)
(12/37) Installing lzip (1.21-r0)
(13/37) Installing nghttp2-libs (1.41.0-r0)
(14/37) Installing libcurl (7.69.1-r1)
(15/37) Installing curl (7.69.1-r1)
(16/37) Installing abuild (3.6.0-r1)
Executing abuild-3.6.0-r1.pre-install
(17/37) Installing binutils (2.34-r1)
(18/37) Installing libmagic (5.38-r0)
(19/37) Installing file (5.38-r0)
(20/37) Installing gmp (6.2.0-r0)
(21/37) Installing isl (0.18-r0)
(22/37) Installing libgomp (9.3.0-r2)
(23/37) Installing libatomic (9.3.0-r2)
(24/37) Installing libgphobos (9.3.0-r2)
(25/37) Installing mpfr4 (4.0.2-r4)
(26/37) Installing mpc1 (1.1.0-r1)
(27/37) Installing gcc (9.3.0-r2)
(28/37) Installing musl-dev (1.1.24-r10)
(29/37) Installing libc-dev (0.7.2-r3)
(30/37) Installing g++ (9.3.0-r2)
(31/37) Installing make (4.3-r0)
(32/37) Installing fortify-headers (1.1-r0)
(33/37) Installing build-base (0.5-r2)
(34/37) Installing expat (2.2.9-r1)
(35/37) Installing pcre2 (10.35-r0)
(36/37) Installing git (2.26.2-r0)
(37/37) Installing alpine-sdk (1.0-r0)
Executing busybox-1.31.1-r19.trigger
OK: 224 MiB in 51 packages

ひとりごと

使っているdockerイメージgolang:1.15.5-alpine3.12がいけなかったのか。。
詳しい方教えてください>_<

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

GO環境でcould not import Cエラー

エラー発生

Goのgraphqlライブラリのgqlgenでスキーマを更新しようとしたら謎のエラー

/go/src # go run github.com/99designs/gqlgen
validation failed: packages.Load: /usr/local/go/src/net/cgo_linux.go:12:8: could not import C (no metadata for C)
exit status 1

解決

どうやらgccがdockerイメージ上に入ってない模様。
たぶんきっとこれ? https://github.com/golangci/golangci-lint/issues/602

apk updateしてapkをアップデートした後、alpine-sdkというビルドパッケージ?を入れたらうまく行きました。
apkについては、この記事が分かりやすかったです。

/go/src # apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz

fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
v3.12.1-44-g754f23ac8f [http://dl-cdn.alpinelinux.org/alpine/v3.12/main]
v3.12.1-41-g42f619918d [http://dl-cdn.alpinelinux.org/alpine/v3.12/community]
OK: 12746 distinct packages available
/go/src # apk add alpine-sdk
(1/37) Upgrading musl (1.1.24-r9 -> 1.1.24-r10)
  0%                                                                                                                                                                                                                   
(2/37) Installing fakeroot (1.24-r0)
(3/37) Installing openssl (1.1.1g-r0)
(4/37) Installing libattr (2.4.48-r0)
(5/37) Installing attr (2.4.48-r0)
(6/37) Installing libacl (2.2.53-r0)
(7/37) Installing tar (1.32-r1)
(8/37) Installing pkgconf (1.7.2-r0)
(9/37) Installing patch (2.7.6-r6)
(10/37) Installing libgcc (9.3.0-r2)
(11/37) Installing libstdc++ (9.3.0-r2)
(12/37) Installing lzip (1.21-r0)
(13/37) Installing nghttp2-libs (1.41.0-r0)
(14/37) Installing libcurl (7.69.1-r1)
(15/37) Installing curl (7.69.1-r1)
(16/37) Installing abuild (3.6.0-r1)
Executing abuild-3.6.0-r1.pre-install
(17/37) Installing binutils (2.34-r1)
(18/37) Installing libmagic (5.38-r0)
(19/37) Installing file (5.38-r0)
(20/37) Installing gmp (6.2.0-r0)
(21/37) Installing isl (0.18-r0)
(22/37) Installing libgomp (9.3.0-r2)
(23/37) Installing libatomic (9.3.0-r2)
(24/37) Installing libgphobos (9.3.0-r2)
(25/37) Installing mpfr4 (4.0.2-r4)
(26/37) Installing mpc1 (1.1.0-r1)
(27/37) Installing gcc (9.3.0-r2)
(28/37) Installing musl-dev (1.1.24-r10)
(29/37) Installing libc-dev (0.7.2-r3)
(30/37) Installing g++ (9.3.0-r2)
(31/37) Installing make (4.3-r0)
(32/37) Installing fortify-headers (1.1-r0)
(33/37) Installing build-base (0.5-r2)
(34/37) Installing expat (2.2.9-r1)
(35/37) Installing pcre2 (10.35-r0)
(36/37) Installing git (2.26.2-r0)
(37/37) Installing alpine-sdk (1.0-r0)
Executing busybox-1.31.1-r19.trigger
OK: 224 MiB in 51 packages

ひとりごと

使っているdockerイメージgolang:1.15.5-alpine3.12がいけなかったのか。。
詳しい方教えてください>_<

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

Rails + Docker でhello worldを表示するまでを簡単に

アプリ作成時に毎回調べている気がするので、備忘録的にまとめてみました。
下記のapp名の箇所には適宜アプリ名を入力して下さい。

※間違いがありましたら変更しますのでコメント頂けると嬉しいです^^

新規ディレクトリ作成 〜 hello world!!まで

まず、アプリの土台となるディレクトリを作ります。
さらに、touchコマンドで、2つの空ファイルを作成します。

$ mkdir app名 && cd app名
$ touch Gemfile Gemfile.lock

私は、VScodeを使用して開発しているので
code コマンドを使用して起動しています。
ちなみに、code コマンドは起動と作成をしてくれます。

Gemfileを編集します。

$ code Gemfile
Gemfile
source 'https://rubygems.org'
gem 'rails', '~>5.2'

Dockerfileを作成して編集します。

$ code Dockerfile
Dockerfile
FROM ruby:2.5
RUN apt-get update
RUN apt-get install -y \ 
    build-essential \
    libpq-dev \
    nodejs \
    postgresql-client \
    yarn \
    vim

WORKDIR /app名
COPY Gemfile Gemfile.lock /app名/
RUN bundle install

docker-compose.ymlファイルを作成して編集します。

$ code docker-compose.yml
docker-compose.yml
version: "3"

volumes:
  db-data:

services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - ".:/app名"
    environment:
      - "DATABASE_PASSWORD=postgres"
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  db:
    image: postgres
    volumes:
      - "db-data:/var/lib/postgresql/data"
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=postgres"

コンテナの起動を行い、webコンテナに入って、rails new します。

$ docker-compose up --build -d
$ docker-compose exec web bash
$ rails new . --force --database=postgresql

rails new で作成された database.yml ファイルに追記します。

database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db  #追記
  user: postgres  #追記
  port: 5432  #追記
  password: <%= ENV.fetch("DATABASE_PASSWORD") %>  #追記
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
$ rails db:migrate
$ rails s -b 0.0.0.0

Chromeの検索バーに、localhost:3000 と入力してアクセスするとhello worldが表示されているかと思います!

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

ubuntu:20.04 dockerコンテナ内でホスト側にGUIを出力(xeyesを出力)する検討メモ

xhostの設定、ubuntu:20.04 dockerコンテナ起動

xhost local:
docker run -it -e DISPLAY="$DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix ubuntu:20.04

xeyesをインストールして実行

apt-get update -y; apt-get install -y x11-apps;

ホスト側にxeyesを出力できた

Screenshot from 2020-11-23 11-37-10.png

追記、以下のnvidiaコンテナでもできた(nvidia/cuda:10.1-cudnn7-devel-ubuntu18.04)

例1 nvidiaコンテナに変更

xhost local:
docker run -it -e DISPLAY="$DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix nvidia/cuda:10.1-cudnn7-devel-ubuntu18.04

例2 例1+オプション追加

xhost local:
docker run -it -e DISPLAY="$DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix --gpus 1 nvidia/cuda:10.1-cudnn7-devel-ubuntu18.04

以下は、nvidiaコンテナ利用手順

参考
Docker(Ubuntu18.04+CUDA10.1+cudnn7)でOpenCV4.1.1インストールするメモ
Installation (Native GPU Support)

sudo apt install curl
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey |   sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list |   sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt update
sudo apt-get install -y nvidia-container-toolkit

以下は、runして内部のコマンドを実行する場合の参考(nvidia-smiを実行)

docker run --gpus 1 nvidia/cuda:10.1-cudnn7-devel-ubuntu18.04 nvidia-smi

参考

Dockerコンテナの中でGUIアプリケーションを起動させる
Ubuntu on Docker on UbuntuでGUIを表示する方法

DockerコンテナのホストでGUIを起動する
Dockerを導入してGUI操作可能なLinux(Ubuntu)コンテナを作成する
dockerでGUIアプリ起動可能な環境構築 [クライアント <--> リモートサーバ <--> dockerコンテナ]
dockerでデスクトップ環境(GUI)を構築してみる。
DockerコンテナのホストでGUIを起動する

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

Docker×Rails6(メモ)

事前準備

環境構築

Docker 関連ファイルを用意

FROM ruby:2.6.3-alpine

ENV LANG=ja_JP.UTF-8
ENV TZ=Asia/Tokyo
ENV ROOT=/myapp \
    GEM_HOME=/bundle \
    BUNDLE_PATH=$GEM_HOME
ENV BUNDLE_BIN=$BUNDLE_PATH/bin
ENV PATH /app/bin:$BUNDLE_BIN:$PATH


WORKDIR $ROOT

RUN apk update && \
    apk upgrade && \
    apk add --no-cache \
        gcc \
        g++ \
        libc-dev \
        libxml2-dev \
        linux-headers \
        make \
        nodejs \
        postgresql \
        postgresql-dev \
        tzdata \
        imagemagick \
        yarn && \
    apk add --virtual build-packs --no-cache \
        build-base \
        curl-dev

COPY Gemfile $ROOT
COPY Gemfile.lock $ROOT

RUN bundle install -j4
# 不要ファイル削除
RUN rm -rf /usr/local/bundle/cache/* /usr/local/share/.cache/* /var/cache/* /tmp/* && \
apk del build-packs

COPY . $ROOT

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["sh", "/usr/bin/entrypoint.sh"]
EXPOSE 3000
docker-compose.yml
version: "3.8"

services:
  db:
    image: postgres:11.0-alpine
    volumes:
      - postgres:/var/lib/postgresql/data:cached
    ports:
      - "5432:5432"
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=ja_JP.UTF-8"
      TZ: Asia/Tokyo
  app:
    build: .
    command: ash -c "rm -f tmp/pids/server.pid && ./bin/rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp:cached
      - rails_cache:/myapp/tmp/cache
      - node_modules:/myapp/node_modules:cached
      - bundle:/bundle:cached
    tmpfs:
      - /tmp
    tty: true
    stdin_open: true
    ports:
      - "3000:3000"
    environment:
      RAILS_ENV: development
      NODE_ENV: development
      DATABASE_HOST: db
      DATABASE_PORT: 5432
      DATABASE_USER: postgres
      DATABASE_PASSWORD: password
      WEBPACKER_DEV_SERVER_HOST: webpacker
    depends_on:
      - db
      - webpacker

  webpacker:
    build: .
    command: ./bin/webpack-dev-server
    volumes:
      - .:/myapp:cached
      - node_modules:/myapp/node_modules:cached
    environment:
      RAILS_ENV: development
      NODE_ENV: development
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    tty: false
    stdin_open: false
    ports:
      - "3035:3035"

volumes:
  rails_cache:
  node_modules:
  postgres:
  bundle:
source 'https://rubygems.org'
gem 'rails',      '6.0.3'
gem 'devise'

# to upload images
gem 'carrierwave', '~> 2.0'
gem "mini_magick"
Gemfile.lock(empry)
```entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

cmd

docker-compose run app rails new . --force --no-deps --database=postgresql --skip-bundle

Gemfile を編集する

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.3'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.4'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'

gem 'devise'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '~> 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

# to upload images
gem 'carrierwave', '~> 2.0'

gem "mini_magick"

その後のコマンド

docker-compose run app bundle update
docker-compose run app rails webpacker:install

database.yml を修正

config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
...

Troubleshooting

up 時に check_yarn_integrity関連 というエラーが出たら webpacker.yml を修正

config/webpacker.yml
...
development:
  <<: *default
  compile: true 

  # Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
  check_yarn_integrity: false # true -> falseに変更
...
docker-compose build
docker-compose up -d
docker-compose run app rake db:create

また up 時に "webpack-dev-server" not found が出たら

docker-compose run app yarn add webpack-dev-server
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS, Docker, CircleCI, Laravelでポートフォリオを作成してみた【参考リンク付き】

初めに

今回はDocker, CircleCI, AWS等、人気の高まっているインフラ技術を一から学んで、Webアプリを作成してみました。
バックエンドはLaravel、フロントエンドにVue.js等といった構成です。

この記事では、アプリ開発にあたって苦労した点や、
各機能実装の際に参考にした記事や教材についてもご紹介していければと思います。

アプリの概要

朝活をテーマをしたSNSアプリです。

  • 朝活仲間を作り、「コツコツ」継続できる
  • 朝活習慣の「コツ」を共有して、朝活の挫折を防ぐ

ことをコンセプトに、「朝活」を文字って「AsaKotsu」というサービスを開発しました。
URLはこちら↓です。よければ、ご自由に動かしてみてください^^

アプリのURL:https://pf.asakotsu.com/
(※まだスマホ対応が完了していないので、PCでの閲覧推奨です^^;)

GitHubのURL:https://github.com/ngsw877/asakotsu

使用画面のイメージ

トップページ(投稿一覧とランキング等)
スクリーンショット 2020-11-16 8.00.00.png

タグ毎の投稿一覧
スクリーンショット 2020-11-22 20.10.06.png

投稿詳細と、コメント一覧
スクリーンショット 2020-11-22 20.05.41.png

Zoomミーティング一覧
スクリーンショット 2020-11-16 22.44.58 2.png

ユーザー詳細画面
スクリーンショット 2020-11-16 23.06.16.png

早起き達成時
スクリーンショット 2020-11-22 20.03.34.png

無限スクロール
infinitscroll.gif

このアプリの特徴

基本的にはtwitterのような投稿、コメント、いいね、フォロー機能のあるSNSですが、
その他に以下のような特徴のあるアプリです。

  • アプリから、朝活Zoomミーティングを作成、編集、削除できる(ZoomAPI連携)
  • 目標起床時間を設定して、早起き達成日数を記録することができる
  • 早起き達成日数のランキング機能(1ヶ月ごとに集計)
  • 投稿にタグ付けし(カテゴリ)、「朝コツ」タグ等で朝活のコツを共有することができる

使用技術

  • フロントエンド

    • Vue.js 2.6.11
    • jQuery 3.4.1
    • HTML / CSS / Sass / MDBootstrap
  • バックエンド

    • PHP 7.4.9
    • Laravel 6.18.36
    • PHPUnit 8.5.8
    • ZoomAPI (guzzlehttp/guzzle 7.0.1)
  • インフラ

    • CircleCi
    • Docker 19.03.12 / docker-compose 1.26.2
    • nginx 1.18
    • mysql 5.7.31 / PHPMyAdmin
    • AWS ( EC2, ALB, ACM, S3, RDS, CodeDeploy, SNS, Chatbot, CloudFormation, Route53, VPC, EIP, IAM )

サーバーサイドのロジックはPHP/Laravelでプログラミングし、
フロントエンドの細かいデザインはSassで整え、動きを付けたい時はVue.jsやjQueryで実装しました。
開発環境にDocker/docker-composeを使用し、
CI/CDパイプラインに関しては、CircleCIで自動テスト・ビルドを行い、
AWSのCodeDeployで自動デプロイを実現するようにしています。

インフラ構成図

AWS_Diagram.png

開発環境、本番環境について

開発環境にDocker / docker-composeを使用しており、以下の4つの用途のコンテナを使用しています。

  1. Webサーバーのコンテナ: Nginx
  2. アプリケーションのコンテナ: PHP / Laravel / Vue.js
  3. DBのコンテナ: MySQL
  4. DB管理用のコンテナ: PHPMyAdmin

参考リンク:

本番環境のAWS上ではECSでデプロイしたかったのですが、
難易度が高く断念・・
ひとまずEC2でのデプロイ経験にも慣れるため、今回はEC2上で環境構築していく形で進めていきました。

SSL証明書の発行

SSL証明書を発行してHTTPS化も実現したかったため、ACM(AWS Certificate Manager)を使用しています。

ACMを使用するためには、EC2に加えて、ALB(ELB)CloudFrontも必要になってくるため、今回はALBを導入することにしました。
なお、ALBを使用しているものの、節約のため現状では負荷分散やスケールアウトする程のアクセスが見込まれないため、EC2インスタンスは1つのみ用意しています。
なお、アドレスバーに鍵マークがついても、Laravel側のプロキシ設定をしないとcssやjsファイルが読み込まれなかったり、ルーティングがhttps化されなくなるので要注意な印象。。

参考リンク:
- AWS:無料でSSL証明書を取得する方法
- 信用するプロキシの設定

S3バケットへのアップロード

S3は、以下の2つの用途別に用意しています。

  1. CircleCIでビルドしたソースを格納

  2. EC2上のアプリでアップロードした画像データを格納

2に関しては、S3のバケットポリシーの設定や、Laravel側でS3用パッケージのインストールが必要だったりと意外にやるべきことがありました。

参考リンク:

Slackへの通知設定

CodeDeploySNSChatbotを連携して、自動デプロイの開始と終了のタイミングでSlackアカウントに通知が飛んでくるようにしています。なかなか便利。

機能一覧

  • ユーザー登録関連

    • 新規登録、プロフィール編集機能
    • ログイン、ログアウト機能
    • かんたんログイン機能(ゲストユーザーログイン)
  • ZoomAPI連携

    • 朝活Zoomミーティング機能(CRUD)
      • ミーティングの新規作成、一覧表示、編集、削除機能
  • 早起き達成の判定機能

    • ユーザー毎に目標起床時刻を設定可能(4:00〜10:00まで)
    • 目標起床時間より前に投稿をすることができれば、早起き達成記録が1日分増えます。
    • ※深夜過ぎ等に投稿した場合も早起き成功とならぬよう、
        目標起床時間より3時間前に投稿しても無効になるよう対処しています。
      (例)目標起床時間を07:00に設定した場合、04:00~07:00に投稿できたら早起き達成
  • ユーザーの早起き達成日数のランキング機能(1ヶ月毎)

  • 無限スクロール機能 (jQuery / inview.js / ajax)

  • ユーザー投稿関連(CRUD)

  • コメント機能

  • タグ機能 (Vue.js / Vue Tags Input)

  • いいね機能 (Vue.js / ajax)

  • フォロー機能

    • フォロー中/フォロワー一覧(ページネーション)
  • フラッシュメッセージ表示機能 (jQuery/ Toastr)

    • 投稿、編集、削除、ログイン、ログアウト時にフラッシュメッセージを表示
  • 画像アップロード機能 (AWS S3バケット)

  • PHPUnitテスト

DB設計

ER図

AsaKotsu_ERD.png

各テーブルについて

テーブル名 説明
users 登録ユーザー情報
follows フォロー中/フォロワーのユーザー情報
achievement_days ユーザーが早起き達成した日付を、履歴として管理
meetings ユーザーが作成したZoomミーティング情報
articles ユーザー投稿の情報
tags ユーザー投稿のタグ情報
article_tags articleとtagsの中間テーブル
likes 投稿への、いいねの情報
comments ユーザー投稿への、コメントの情報

早起き達成機能 関連のポイント

usersテーブルwake_up_timeはユーザーの目標起床時間を意味しています。
この時間よりも早い時間にユーザーが投稿をできれば、その日の早起きが達成となります。
なお、
「目標起床時間が07:00で、深夜1:00に投稿した」
というように、早過ぎる時間にユーザーが投稿した
場合にも早起き達成とならないように設定しています。
その仕組みとして、usersテーブルrange_of_successの値が利用されています。
これは、
「目標起床時間より何時間前までに投稿すれば早起き達成となるのか、その範囲を表す整数値」
です。
デフォルトは3で、例えば目標起床時間を07:00に設定している場合は、その3時間前の
04:00 〜 07:00 の間に投稿できれば早起き達成となります。

こうして早起き達成をすることができたら、achievement_daysテーブルdateに達成日の日付が履歴として記録されていきます。
例) 2020-11-22
この日付データを利用して、以下の機能を実現しています。

①  1ヶ月毎の早起き達成日数を算出
② ①の日数を利用したランキング機能

当初は、早起き継続日数のランキングにしようかとも考えていましたが、
ユーザーのモチベーション維持等の観点から1ヶ月毎の早起き達成日数を採用することにしました。

苦労したこと

開発からデプロイまで、どの工程でももれなくエラーで苦戦しましたがw、
ここでは特に印象に残っている点をまとめます。

CircleCIで苦労したこと

  • CircleCIの設定ファイルである、config.ymlの設定
  • 自動ビルド、自動テストの流れの理解

config.ymlの設定においては、だいぶエラーに悩まされました。。
特に、コマンドやパスを指定する時は、パスのルートはどこが起点になっているのかを理解することが重要な印象。
テスト失敗時の対策としては、ビルドされたコンテナにSSHログインしてエラーログを確認し、原因を解消していくようにしていました。

参考リンク: SSH を使用したデバッグ

AWSデプロイで苦労したこと

  • ACMでのSSL証明書発行
  • Laravelで画像をS3にアップロードする設定
  • CodeDeployでの、自動デプロイ設定(特にappspec.yml)
  • EC2インスタンスのセットアップ

上述した、
SSL証明書の発行
S3バケットへのアップロード
周りでエラーにハマりがちでした。
また、今回はECSでなくEC2でデプロイすることとしましたが、EC2にSSHログインしてから
インストールしたり設定するファイルが多く、その辺りの作業も大変でした。
この工程を考えると、ますますECSを扱えるようになりたく思いましたね^^;

フロントエンドで苦労したこと

  • UI/UXの調整(Sass)
  • Ajax全般

バックエンドでの苦労

  • DB設計
  • DBリレーション関連の処理
  • PHPUnitでのテスト全般

リレーション周りについては当初かなり苦戦しました。
どのテーブルとどのテーブルを関連付けるのか、また関連付けた情報をどうやって取得すれば良いのか?
また、

  • $article->user()
  • $article->user

例えばこの2つの違いについても重要なポイントと感じました。

PHPUnitのテストコードについては、体系的に学べる情報がなかなか見つからなかったので、情報収集に苦労しました。

ZoomAPI連携で苦労したこと

  • Guzzleの理解
  • ZoomAPIの理解

アプリ上からZoomミーティングを作成したり編集できる機能をつけることにしましたが、
これまで外部APIを利用したことがなかったこともあり、文法的なものや、API通信の仕組みについて理解するまでが難しく感じました。

実装にあたり、まずLaravelでZoomAPIと通信を行うために、PHPのHTTPクライアントである
Guzzleをインストールしました。

参考リンク:

次に、Zoomアプリマーケットプレイスでアプリを登録し、公式ドキュメントを読んでみるも、英語な上初めはどこのページの何を見れば良いのかわからず苦戦しました。。^^;

Laravelで、ZoomAPIと通信を行う処理のサンプルコードを紹介している
海外の記事を参考にしたりしているうちに、次第に公式ドキュメントから必要な情報を探せるようにもなってきました。

参考リンク:

ただ、今回Laravel6系でアプリを開発していたため、通常Laravel7系で使用できるGuzzleラッパーが使えず、ややコードを書き換えないといけない点にも苦労しました。

参考にした学習教材等

基本的には、UdemyTechpitで学習してきました。
この2つはとてもわかりやすいです。
個人的には、Udemyで基礎を学んでから、応用編としてTechpitで手を動かしながら学ぶのが良いと感じました。

Docker / docker-compose

PHPUnit / CircleCI / AWS

AWS

Laravel

Laravel / Vue.js

Sass

今後の課題

  • レスポンシブWebデザイン(スマホ対応)
  • デザイン面の改善
  • 無限スクロールの不具合修正(読み込まれた投稿のいいねボタンが消える)
  • ALBにAuto Scalingを追加し、EC2を冗長化
  • ECS(EKS)でのデプロイ
  • RDSの冗長化
  • インフラのコード化
  • 検索機能の追加
  • テストコードの充実
  • 投稿時に別画面へ遷移するのではなく、入力フォームをモーダルで表示させるようにする
  • 開始前のZoomミーティング、終了ミーティングのソート機能

まだ課題も多いですが、一つずつ改善してよりブラッシュアップしていきたく思います。

だいぶ長い記事になってしまいましたが、ここまで読んでくださりありがとうございました!^^

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

Redmine(Docker)構築手順メモ

  • ローカル環境に、プロジェクト管理ソフトウェアRedmineをDockerで立ち上げる手順についてまとめる。
    • Redmine用DBにはMySQL5.7を利用する。

構築手順

  • フォルダ構成
  redmine/
        ├ data/           #マウント場所
        |    └ db       
        |    └ plugins  
        |    └ themes        
        └ docker-compose.yml  

1.docker-compose.ymlを作成する。

   version: "3"

   services:
     redmine:
       container_name: redmine
       image: redmine
       restart: always
       ports:
         - 8081:3000
       environment:
         REDMINE_DB_MYSQL: redmine-db
         REDMINE_DB_PASSWORD: redminepass
       volumes:
         - ./data/plugins:/usr/src/redmine/plugins
         - ./data/themes:/usr/src/redmine/public/themes

     redmine-db:
       image: mysql:5.7
       container_name: redmine-db
       restart: always
       environment:
         MYSQL_ROOT_PASSWORD: redminepass
         MYSQL_DATABASE: redmine
       volumes:
         - ./data/db:/var/lib/mysql
       command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci   

※マウント場所やポートなどは自環境に合わせて適宜設定する。
2. コンテナを起動する。
上記redmineフォルダに移動し、以下のdocker-composeコマンドを実行する。

   docker-compose up -d

3.ブラウザからhttp://localhost:8081にアクセスする。
※以下の画面が表示される。
redmine_top.png
4.初期ユーザー情報(ログインID:admin/パスワード:admin)を入力して、ログインする。※ログイン後、パスワード変更を要求される。

参考情報

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

Redmine(Docker)環境構築メモ

  • ローカル環境に、プロジェクト管理ソフトウェアRedmineをDockerで立ち上げる手順についてまとめる。
    • Redmine用DBにはMySQL5.7を利用する。

構築手順

  • フォルダ構成
  redmine/
        ├ data/           #マウント場所
        |    └ db       
        |    └ plugins  
        |    └ themes        
        └ docker-compose.yml  

1.docker-compose.ymlを作成する。

   version: "3"

   services:
     redmine:
       container_name: redmine
       image: redmine
       restart: always
       ports:
         - 8081:3000
       environment:
         REDMINE_DB_MYSQL: redmine-db
         REDMINE_DB_PASSWORD: redminepass
       volumes:
         - ./data/plugins:/usr/src/redmine/plugins
         - ./data/themes:/usr/src/redmine/public/themes

     redmine-db:
       image: mysql:5.7
       container_name: redmine-db
       restart: always
       environment:
         MYSQL_ROOT_PASSWORD: redminepass
         MYSQL_DATABASE: redmine
       volumes:
         - ./data/db:/var/lib/mysql
       command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci   

※マウント場所やポートなどは自環境に合わせて適宜設定する。
2. コンテナを起動する。
上記redmineフォルダに移動し、以下のdocker-composeコマンドを実行する。

   docker-compose up -d

3.ブラウザからhttp://localhost:8081にアクセスする。
※以下の画面が表示される。
redmine_top.png
4.初期ユーザー情報(ログインID:admin/パスワード:admin)を入力して、ログインする。※ログイン後、パスワード変更を要求される。

参考情報

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

【Docker入門】〜jupyter lab起動までの最短解説〜

はじめに

この記事では、docker初心者がjupyter labの起動まで最速で到達することを目的としております。
containerやimageなど、dockerの専門用語の深い話は飛ばされているので、気になる部分は適宜ググってみてください。

記事を読んで参考になったと思った方は、LGTM押していただけると幸いです!

前提

・mac環境で実施しております

目次

  1. 環境構築の作業全体像
  2. dockerインストール
  3. Dockerfile作成
  4. image作成
  5. container作成
  6. 環境の削除

1. 環境構築の作業全体像

Dockerでの環境構築の基本的な流れは、以下の通り
1. Dockerfileの作成
2. imageの作成
3. containerの作成&起動

それぞれ一言で解説すると

用語 一言解説 参考URL
Dockerfile 構築する環境の設計書
(このファイルを見ればどんな環境なのか一目でわかります)
-
image 環境情報を持つ複製可能な環境ファイル
(1つのimageでたくさんの環境を作ることができます)
Dockerイメージの理解を目指すチュートリアル
container imageから生成された環境インスタンス
(トライアンドエラーで環境を立てたり潰したりできます)
-

image.png
概略図(https://docs.docker.jp/engine/understanding-docker.html)
※クライアントが「Dockerfile」を持っており、それを用いて「image」を「build」します。

2. dockerインストール

docker hubに登録して、トップページの「Get start with Docker Desktop」からdesktopバージョンをダウンロードする
https://hub.docker.com/
スクリーンショット 2020-11-22 21.09.33.png

3. Dockerfileの作成

Desktopにdockerディレクトリを作成し、その中に以下のDockerfileを作成します

Desktop/docker/Dockerfile
#anaconda3のimageをdockerhubからpullする(https://hub.docker.com/r/continuumio/anaconda3)
#このimageは、ubuntuOSにanaconda3をセットアップした環境
FROM continuumio/anaconda3:2020.07

#jupyterの設定ファイルに変更を加える(この設定を加えないとjupyter-labが起動しません)
RUN jupyter notebook --generate-config
WORKDIR /root/.jupyter
RUN echo 'c.NotebookApp.allow_root = True' >> jupyter_notebook_config.py && \
    echo 'c.NotebookApp.ip = "0.0.0.0"' >> jupyter_notebook_config.py && \
    echo 'c.NotebookApp.token = "xxxx"' >> jupyter_notebook_config.py && \
    echo 'c.NotebookApp.port = 8888' >> jupyter_notebook_config.py && \
    echo 'c.NotebookApp.open_browser = False' >> jupyter_notebook_config.py
#セキュリティー設定については以下のURL参照
#https://jupyter-notebook.readthedocs.io/en/latest/security.html#server-security
#https://qiita.com/SaitoTsutomu/items/aee41edf1a990cad5be6

#作業用ディレクトリを作成する
RUN mkdir -p /home/work
WORKDIR /home/work

#デフォルトコマンドを設定する(containerが起動した時に実行されるコマンド)
CMD [ "jupyter", "lab"]

 
Dockerfile 命令一覧

命令 一言解説
FROM docker hubからimageをpullする
(localに該当のイメージがある場合はpullは行われない)
RUN linuxコマンドを実行する
(pullしたimageの環境内でコマンドを実行し、環境のカスタマイズを行う)
WORKDIR カレントディレクトリを変更する
(linuxのcdコマンドでは、移動は一時的なため注意)
CMD デフォルトコマンドを設定する
(containerが起動した時に実行されるコマンド)

そんなにコマンドの数は多くないので、気になる方はその他も調べてみてください
http://docs.docker.jp/v17.06/engine/reference/builder.html)

4. image作成

以下の通りコマンドを実行して、imageの作成&確認を行う

imageの作成

#Dockerfileのあるディレクトリに移動
cd desktop/docker/Dockerfile
#カレントディレクトリを指定して、imageをbuildする(-tのオプションでimageの名前を指定する)
docker build . -t anaconda-env

作成したimageの確認

docker images
REPOSITORY      TAG       IMAGE ID            CREATED             SIZE
anaconda-env    latest    8aacbb4fe3dc        10 hours ago        2.76GB

以上のように表示されていれば、imageの作成完了

5. container作成

最後に、container作成を行うことでjupyter-labの実行環境の作成完了です!
以下のコマンドを順に入力してください

#ローカルホスト側に保存する用のディレクトリを作成する
mkdir volume
#コンテナを作成する
docker run -v $(pwd)/volume:/home/work -p 1111:8888 --name anaconda-container  -it anaconda-env

オプション解説

オプション 解説
-v ・container内部の一部ディレクトリの保存先をローカルに指定する
・上記コマンドでは、コンテナ:/home/workへの保存は、ホスト:volumeに保存されます
・コンテナを削除しても、データが消えないため、ソースコードや学習データをこのディレクトリで管理します
・絶対パスで指定する必要があるため、$(pwd)によってカレントディレクトリを代入しています
-p localhostとcontainer内のポートの繋ぎ込みを表します
(上記指定の場合、localhostの1111ポートに接続した時に、container内の8888ポートに接続する)
--name 生成するcontainerの名前を決めます
-it おまじない
(-i:コマンドラインからの入力を受け付ける、-t:コマンドラインの表示を綺麗にする、これらの組み合わせ)

上記コマンドを実行すると、jupyter-labが起動するので、以下URLにアクセスしてください
http://localhost:1111

今回パスワードはDockerfileで、'xxxx’を指定しています(パスワードの設定方法の詳細を知りたい方は以下URLを参照ください)
https://jupyter-notebook.readthedocs.io/en/latest/security.html#server-security

ログイン画面
image.png

jupyter-lab画面
image.png

ここまでで、dockerによるjupyter-labの起動は完了です!お疲れ様でした!


この章の最後に、作成したコンテナの状態を確認します
linux画面に戻って、下図のjupyter-labを起動している状態から、「ctrl+p+q」でコンテナから一時的に抜け出します。(コンテナは停止されません)
image.png
下記コマンドでコンテナが起動されていることがわかります

#containerの状態を確認する
docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
22093b0f68f1        anaconda-env        "jupyter lab"       25 minutes ago      Up 25 minutes       0.0.0.0:1111->8888/tcp   anaconda-container

ちなみにコンテナの停止と実行は、以下コマンドで実行可能です

docker stop anaconda-container

#containerの停止(Exited)を確認(-aで停止中のコンテナも確認できる)
docker ps -a
CONTAINER ID        IMAGE           COMMAND          CREATED             STATUS                      PORTS         NAMES
22093b0f68f1        anaconda-env    "jupyter lab"    37 minutes ago      Exited (0) 26 seconds ago                 anaconda-container

再度起動したい場合は、以下のコマンドを実行してください

docker start anaconda-container
#juypter-labを起動する場合
docker exec -it anaconda-container jupyter lab
#環境のCUIに接続する場合(conda install等をしたい場合)
docker exec -it anaconda-container bash

6. 環境の削除

以下の手順でcontainerとimageを削除します

#停止しなければ、コンテナは削除できない
docker stop anaconda-container
#containerの削除
docker rm anaconda-container
#imageの削除
docker rmi anaconda-env

 
Dockerfileでimageを作成する時に、セーブポイントとしてchasheが残されています(DockerfileのRUNの命令ごとにchashが生成されます)
chasheは、Dockerfile生成時にミスがあってもセーブポイントまではchashを再利用できるように保存されています
知らぬ間に、chasheが容量を圧迫するケースがあるのでこちらの削除もお忘れなく

#キャッシュの削除
docker builder prune

さいごに

ここまで一通り流しましたが、意外とすんなり環境構築ができたのではないでしょうか??
dockerになれてしまえば、煩わしい環境構築はDockerfileで自動化できますし、他PC・サーバーへの移行も容易です。
データ分析・AI開発やweb開発の環境構築のスタンダードとなっているようなので、押さえておいて損はないはずです。
細部の解説をかなり飛ばしているので、網羅的に勉強したい方はぜひ参考資料で学んでみてください!(特にudemyの講座はオススメです!)

記事を読んで参考になったと思った方は、LGTM押していただけると幸いです!

参考

・Docker超入門
https://datawokagaku.com/whatisdocker/
・udemy講座(網羅的に勉強したい方はこちらおすすめです)
https://www.udemy.com/course/aidocker/

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

Windows10 homeにDocker Hubをインストールしたけど起動しなかった時に調べた内容

自宅のPC検証環境を作りたくDocker Hubをインストール
その時に、docker run hello-worldが実行出来なかったので色々試した内容をまとめておく

結論
・Dockerが起動してるか確認する

環境
・Windows10 home

まずこの記事を参考にインストール
Windows 10 Home 対応の Docker Desktop for Windows を一足早く試してみました

Docker Hubのインストールまでは完了してhello-worldをしてみるも起動しない

C:\Users\name>docker run hello-world
docker: error during connect: This error may indicate that the docker daemon is not running.: Post http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/containers/create: open //./pipe/docker_engine: The system cannot find the file specified.
See 'docker run --help'.

こんな感じのエラーが出る
エラーを調べてみると環境変数が正しく設定出来ていないので繋がらないっぽい

調べてみると下記のページにたどり着く
Docker for Windowsでのエラー
dockerでネットワークエラー
windows: docker: command not found( docker not added to path)

コマンドから環境変数を設定していたが、設定から環境変数を検索してそこからPATHにDockerをインストールしたフォルダを設定した

環境変数を設定し再度hello-worldを実行するも上のエラーが出て実行できない
一度、再インストールし直して実行してみるも同じ状態

さらに検索してみると下記ページがヒット
Windows10の環境で docker コマンドを実行するとエラーが発生する

このスタックオーバーフローの回答に「Docker Desktopが起動していないのでは?」とありツールバーのDockerマークを見ると赤い状態で起動していませんでした…

Dockerを起動してあげるとhello-world出来ました。

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

Windows10 home環境でDocker Hubをインストールしたけど起動しなかった時に調べた内容

自宅のPC検証環境を作りたくDocker Hubをインストール
その時に、docker run hello-worldが実行出来なかったので色々試した内容をまとめておく

結論
・Dockerが起動してるか確認する

環境
・Windows10 home

まずこの記事を参考にインストール
Windows 10 Home 対応の Docker Desktop for Windows を一足早く試してみました

Docker Hubのインストールまでは完了してhello-worldをしてみるも起動しない

C:\Users\name>docker run hello-world
docker: error during connect: This error may indicate that the docker daemon is not running.: Post http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/containers/create: open //./pipe/docker_engine: The system cannot find the file specified.
See 'docker run --help'.

こんな感じのエラーが出る
エラーを調べてみると環境変数が正しく設定出来ていないので繋がらないっぽい

調べてみると下記のページにたどり着く
Docker for Windowsでのエラー
dockerでネットワークエラー
windows: docker: command not found( docker not added to path)

コマンドから環境変数を設定していたが、設定から環境変数を検索してそこからPATHにDockerをインストールしたフォルダを設定した

環境変数を設定し再度hello-worldを実行するも上のエラーが出て実行できない
一度、再インストールし直して実行してみるも同じ状態

さらに検索してみると下記ページがヒット
Windows10の環境で docker コマンドを実行するとエラーが発生する

このスタックオーバーフローの回答に「Docker Desktopが起動していないのでは?」とありタスクバーのDockerマークを見ると赤い状態で起動していませんでした…

Dockerを起動してあげるとhello-world出来ました。

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