20190301のdockerに関する記事は11件です。

Golang(Echo) x docker-composeでホットリロード用いた開発

About

Golang(Echo)でDockerfileを開発と本番で同じものを使いつつ、docker-composeを使う。
なおかつホットリロードもする。

前提

  • Golang
    • 1.12
  • docker
    • 18.09.2
  • docker-compose
    • 1.23.2
  • realize
    • 2.0.2

Docker環境を用意する

とりあえず最低限のEchoサーバーを動かすこと前提

main.go

main.go を記述

main.go
package main

import (
    "net/http"

    "github.com/labstack/echo"
)

func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, World!")
    })
    e.Logger.Fatal(e.Start(":1323"))
}

modulesの初期設定

go.mod を手に入れる

$ docker run -v `pwd`:/go/app -w /go/app golang:1.12-alpine go mod init app
go: creating new go.mod: module app
$ ls
go.mod  main.go

ここで go.sum が欲しい人はよしなに。

Dockerfile

DockerのMulti-Stage Buildを使ってレイヤーを2つ用意します。
1つ目のレイヤーはdocker-composeで使用するため、
2つ目のレイヤーは本番で使用するために使います。

Dockerfile
FROM golang:1.12-alpine as build

WORKDIR /go/app

COPY . .

RUN apk add --no-cache git \
 && go build -o app

FROM alpine

WORKDIR /app

COPY --from=build /go/app/app .

RUN addgroup go \
  && adduser -D -G go go \
  && chown -R go:go /app/app

CMD ["./app"]

動作確認をしておきましょう。

$ docker build -t myapp .
$ docker run -p 1323:1323 -d --name myapp myapp
$ curl localhost:1323
Hello, World!

動いたのを確認できたらコンテナを落とします。

$ docker stop down myapp
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
$

docker-compose

docker-composeを動かすために docker-compose.yml を記述します。

この時に指定する target: build がポイントです。
Multi-Stage Buildのレイヤーを使用することができます。

docker-compose.yml
version: '3.5'

services:
  app:
    build:
      context: .
      target: build
    volumes:
      - ./:/go/app
    command: go run main.go
    ports:
      - 1323:1323

さて、動作確認です。

$ docker-compose up
Recreating echo_app_1 ... done
Attaching to echo_app_1
app_1  | go: finding github.com/labstack/gommon/color latest
app_1  | go: finding github.com/labstack/gommon/log latest
app_1  | go: finding golang.org/x/crypto/acme/autocert latest
app_1  | go: finding golang.org/x/crypto/acme latest
app_1  | go: finding golang.org/x/crypto latest
app_1  | go: finding github.com/valyala/fasttemplate latest
app_1  |
app_1  |    ____    __
app_1  |   / __/___/ /  ___
app_1  |  / _// __/ _ \/ _ \
app_1  | /___/\__/_//_/\___/ v3.3.10-dev
app_1  | High performance, minimalist Go web framework
app_1  | https://echo.labstack.com
app_1  | ____________________________________O/_______
app_1  |                                     O\
app_1  | ? http server started on [::]:1323

別のターミナルを起動してcurlを打ってみましょう

$ curl localhost:1323
Hello, World!

動いてますね。

ホットリロードを導入する

oxequa/realize を使用して実現します

Dockerfileの編集

realizeのインストール

Dockerfile
FROM golang:1.12-alpine as build

WORKDIR /go/app

COPY . .

RUN apk add --no-cache git \
-  && go build -o app
+  && go build -o app \
+  && go get github.com/oxequa/realize

FROM alpine

WORKDIR /app

COPY --from=build /go/app/app .

RUN addgroup go \
  && adduser -D -G go go \
  && chown -R go:go /app/app

CMD ["./app"]

docker-composeの編集

realizeを使用して起動するようにする

docker-compose.yml
version: '3.5'

services:
  app:
    build:
      context: .
      target: build
    volumes:
      - ./:/go/app
-    command: go run main.go
+    command: realize start --run --no-config
    ports:
      - 1323:1323

動作確認

$ docker-compose up
Recreating echo_app_1 ... done
Attaching to echo_app_1
app_1  | len [0/0]0x0
app_1  | [10:25:29][APP] : Watching 1 file/s 1 folder/s
app_1  | [10:25:29][APP] : Install started
app_1  | [10:25:30][APP] : Install completed in 0.805 s
app_1  | [10:25:30][APP] : Running..
app_1  | [10:25:30][APP] :    ____    __
app_1  | [10:25:30][APP] :   / __/___/ /  ___
app_1  | [10:25:30][APP] :  / _// __/ _ \/ _ \
app_1  | [10:25:30][APP] : /___/\__/_//_/\___/ v3.3.10-dev
app_1  | [10:25:30][APP] : High performance, minimalist Go web framework
app_1  | [10:25:30][APP] : https://echo.labstack.com
app_1  | [10:25:30][APP] : ____________________________________O/_______
app_1  | [10:25:30][APP] :                                     O\
app_1  | [10:25:30][APP] : ? http server started on [::]:1323

動いてますね。
curlをして動作確認してみましょう。

$ curl localhost:1323
Hello, World!

最後に main.go を編集してホットリロードされるかの確認です

main.go
package main

import (
    "net/http"

    "github.com/labstack/echo"
)

func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
-        return c.String(http.StatusOK, "Hello, World!")
+        return c.String(http.StatusOK, "Good Bye.")
    })
    e.Logger.Fatal(e.Start(":1323"))
}
$ curl localhost:1323
Good Bye.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Golang(Echo)でdocker-composeを用いた開発

About

Golang(Echo)でDockerfileを開発と本番で同じものを使いつつ、docker-composeを使う。
なおかつホットリロードもする。

前提

  • Golang
    • 1.12
  • docker
    • 18.09.2
  • docker-compose
    • 1.23.2
  • realize
    • 2.0.2

Docker環境を用意する

とりあえず最低限のEchoサーバーを動かすこと前提

main.go

main.go を記述

main.go
package main

import (
    "net/http"

    "github.com/labstack/echo"
)

func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, World!")
    })
    e.Logger.Fatal(e.Start(":1323"))
}

modulesの初期設定

go.mod を手に入れる

$ docker run -v `pwd`:/go/app -w /go/app golang:1.12-alpine go mod init app
go: creating new go.mod: module app
$ ls
go.mod  main.go

ここで go.sum が欲しい人はよしなに。

Dockerfile

DockerのMulti-Stage Buildを使ってレイヤーを2つ用意します。
1つ目のレイヤーはdocker-composeで使用するため、
2つ目のレイヤーは本番で使用するために使います。

Dockerfile
FROM golang:1.12-alpine as build

WORKDIR /go/app

COPY . .

RUN apk add --no-cache git \
 && go build -o app

FROM alpine

WORKDIR /app

COPY --from=build /go/app/app .

RUN addgroup go \
  && adduser -D -G go go \
  && chown -R go:go /app/app

CMD ["./app"]

動作確認をしておきましょう。

$ docker build -t myapp .
$ docker run -p 1323:1323 -d --name myapp myapp
$ curl localhost:1323
Hello, World!

動いたのを確認できたらコンテナを落とします。

$ docker stop down myapp
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
$

docker-compose

docker-composeを動かすために docker-compose.yml を記述します。

この時に指定する target: build がポイントです。
Multi-Stage Buildのレイヤーを使用することができます。

docker-compose.yml
version: '3.5'

services:
  app:
    build:
      context: .
      target: build
    volumes:
      - ./:/go/app
    command: go run main.go
    ports:
      - 1323:1323

さて、動作確認です。

$ docker-compose up
Recreating echo_app_1 ... done
Attaching to echo_app_1
app_1  | go: finding github.com/labstack/gommon/color latest
app_1  | go: finding github.com/labstack/gommon/log latest
app_1  | go: finding golang.org/x/crypto/acme/autocert latest
app_1  | go: finding golang.org/x/crypto/acme latest
app_1  | go: finding golang.org/x/crypto latest
app_1  | go: finding github.com/valyala/fasttemplate latest
app_1  |
app_1  |    ____    __
app_1  |   / __/___/ /  ___
app_1  |  / _// __/ _ \/ _ \
app_1  | /___/\__/_//_/\___/ v3.3.10-dev
app_1  | High performance, minimalist Go web framework
app_1  | https://echo.labstack.com
app_1  | ____________________________________O/_______
app_1  |                                     O\
app_1  | ? http server started on [::]:1323

別のターミナルを起動してcurlを打ってみましょう

$ curl localhost:1323
Hello, World!

動いてますね。

ホットリロードを導入する

oxequa/realize を使用して実現します

Dockerfileの編集

realizeのインストール

Dockerfile
FROM golang:1.12-alpine as build

WORKDIR /go/app

COPY . .

RUN apk add --no-cache git \
-  && go build -o app
+  && go build -o app \
+  && go get github.com/oxequa/realize

FROM alpine

WORKDIR /app

COPY --from=build /go/app/app .

RUN addgroup go \
  && adduser -D -G go go \
  && chown -R go:go /app/app

CMD ["./app"]

docker-composeの編集

realizeを使用して起動するようにする

docker-compose.yml
version: '3.5'

services:
  app:
    build:
      context: .
      target: build
    volumes:
      - ./:/go/app
-    command: go run main.go
+    command: realize start --run --no-config
    ports:
      - 1323:1323

動作確認

$ docker-compose up
Recreating echo_app_1 ... done
Attaching to echo_app_1
app_1  | len [0/0]0x0
app_1  | [10:25:29][APP] : Watching 1 file/s 1 folder/s
app_1  | [10:25:29][APP] : Install started
app_1  | [10:25:30][APP] : Install completed in 0.805 s
app_1  | [10:25:30][APP] : Running..
app_1  | [10:25:30][APP] :    ____    __
app_1  | [10:25:30][APP] :   / __/___/ /  ___
app_1  | [10:25:30][APP] :  / _// __/ _ \/ _ \
app_1  | [10:25:30][APP] : /___/\__/_//_/\___/ v3.3.10-dev
app_1  | [10:25:30][APP] : High performance, minimalist Go web framework
app_1  | [10:25:30][APP] : https://echo.labstack.com
app_1  | [10:25:30][APP] : ____________________________________O/_______
app_1  | [10:25:30][APP] :                                     O\
app_1  | [10:25:30][APP] : ? http server started on [::]:1323

動いてますね。
curlをして動作確認してみましょう。

$ curl localhost:1323
Hello, World!

最後に main.go を編集してホットリロードされるかの確認です

main.go
package main

import (
    "net/http"

    "github.com/labstack/echo"
)

func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
-        return c.String(http.StatusOK, "Hello, World!")
+        return c.String(http.StatusOK, "Good Bye.")
    })
    e.Logger.Fatal(e.Start(":1323"))
}
$ curl localhost:1323
Good Bye.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerのボリューム先が分かると環境のエラーに少し強くなれると思いたい話

ボリューム位置を知りたくなった経緯

Growiのバージョンアップをしたらdocker-compose upできない
原因はバージョンをあげる前のelasticsearchコンテナが作ったnodeの0番。恐らく以前のnodeが残っていてかつ、Dockerfileの設定では1つのnodeしか作られないようになっているにも関わらず、バージョンアップしたGrowiをdocker-compose upする時に新たなnodeを立てようとしていたからだと思われる。

解決策

それなら、ボリュームされたこいつを削除してやればいいじゃん!!

どこだァ!!ボリューム!!

docker-compose.yml
volumes:
      - es_data:/usr/share/elasticsearch/data

これではホストのどこにボリュームされてるか分からねぇぞぉ!!

$ docker volume ls

こうしてあげると、

local               growi_es_data
local               growi_es_plugins
local               growi_growi_data
local               growi_mongo_configdb
local               growi_mongo_db

こんな感じで、ボリュームされているボリューム名がリストされます。今回はelasticsearchに用があるので、growi_es_dataちゃんにご同行願いましょう。ふへへへへへ・・・

$ docker volume inspect growi_es_data

こうしてあげると、

[
    {
        "CreatedAt": "2019-02-28T09:37:54Z",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "growi",
            "com.docker.compose.volume": "es_data"
        },
        "Mountpoint": "/var/lib/docker/volumes/growi_es_data/_data",
        "Name": "growi_es_data",
        "Options": null,
        "Scope": "local"
    }
]

詳しいボリュームの内容が分かります。見えちゃってるゼェ〜、君の全部がヨォ〜・・・ヘッヘッヘ・・・

ディレクトリを削除・・・と思いきや・・・

当初は、これで分かったボリューム先まで行ってそのパスの先にある_dataを丸ごと削除してあげれば問題ないと思っていたんですが、

$ docker volume rm growi_es_data

上記のように、volume名を指定してそこを吹っ飛ばすことができるコマンドをvolume lsなどを調べていた時に見つけたので、これで削除しました。

解決!

この作業の後に、docker-compose upしたら、ちゃんと動いてくれました。

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

dockerfileを作る時にエディタとかの環境を整える

dockerfileを作る時にエディタとかの環境を整える

docker run -it ubuntu:18.04 sh でdockerfileを作る時にエディタとかの環境を整える

apt update && apt install -y nano vim net-tools dnsutils iputils-ping iproute2 curl wget 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Cloud9からAzure PowerShellに接続する

AWS Cloud9からAzure PowerShellに接続する手順を確立させたのでそのメモです。

具体的には、Cloud9上でUbuntuのDockerコンテナを起動して、その上にPowerShell CoreとAzモジュールをインストールし、AzureにPowerShellで接続可能にしました。

手順

すること

Cloud9のターミナルにてコマンドを以下の順に実行していきます。

Cloud9上のbash

  • docker run -it -d ubuntu:18.04
  • docker exec -it $(docker ps -l -q) /bin/bash

Dockerコンテナ上のUbuntu

  • apt update
  • apt install -y wget
  • wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
  • dpkg -i packages-microsoft-prod.deb
  • apt update
  • apt install -y powershell
  • mkdir $HOME/.config/powershell
  • pwsh

Ubuntu上のPowerShell Core

  • Install-Module Az
  • Import-Module Az
  • Enable-AzureRmAlias -Scope CurrentUser
  • Connect-AzureRmAccount

実際にやってみる

#DockerのUbuntu18.04イメージからコンテナを起動
ec2-user:~/environment $ docker run -it -d ubuntu:18.04
Unable to find image 'ubuntu:18.04' locally
18.10: Pulling from library/ubuntu
a13xxxxxxxxx: Pull complete 
e03xxxxxxxxx: Pull complete 
c57xxxxxxxxx: Pull complete 
d21xxxxxxxxx: Pull complete 
Digest: sha256:f4dc4a22fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Status: Downloaded newer image for ubuntu:18.04
af658cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

#先程起動したコンテナにログイン
ec2-user:~/environment $ docker exec -it $(docker ps -l -q) /bin/bash

#ここでupdateをしないと次のwgetインストールがエラーになる
root@af658cxxxxxx:/# apt update
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
(中略)
Building dependency tree       
Reading state information... Done
3 packages can be upgraded. Run 'apt list --upgradable' to see them.

#wgetのインストール
root@af658cxxxxxx:/# apt install -y wget
Reading package lists... Done
Building dependency tree       
Reading state information... Done
(中略)
Running hooks in /etc/ca-certificates/update.d...
done.

#.NET Coreのリポジトリをaptコマンドの管理対象に登録
root@af658cxxxxxx:/# wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
root@af658cxxxxxx:/# dpkg -i packages-microsoft-prod.deb
Selecting previously unselected package packages-microsoft-prod.
(Reading database ... 4379 files and directories currently installed.)
Preparing to unpack packages-microsoft-prod.deb ...
Unpacking packages-microsoft-prod (1.0-ubuntu18.04.2) ...
Setting up packages-microsoft-prod (1.0-ubuntu18.04.2) ...

#ここでupdateをしないと次のPowerShellインストールがエラーになる
root@af658cxxxxxx:/# apt update
Get:1 https://packages.microsoft.com/ubuntu/18.04/prod bionic InRelease [3226 B]
(中略)
Building dependency tree       
Reading state information... Done
3 packages can be upgraded. Run 'apt list --upgradable' to see them.

#PowerShellのインストール
root@af658cxxxxxx:/# apt install -y powershell
Reading package lists... Done
Building dependency tree       
Reading state information... Done
(中略)
Setting up powershell (6.1.3-1.ubuntu.18.04) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...

#PowerShellプロファイルの格納パス作成
root@af658cxxxxxx:/# mkdir $HOME/.config/powershell

#PowerShell起動
root@af658cxxxxxx:/# pwsh
PowerShell 6.1.3
Copyright (c) Microsoft Corporation. All rights reserved.
(略)

#Azモジュールをインストール
PS /> Install-Module Az
Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from 'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): Y

#AzモジュールをPowerShellにインポート
PS /> Import-Module Az

#AzureRMのコマンド名でAzコマンドを実行できるようにする
PS /> Enable-AzureRmAlias -Scope CurrentUser

#Azureアカウントで認証してAzureRmのPowerShellセッション開始
PS /> Connect-AzureRmAccount                                                                                                                                   
WARNING: To sign in, use a web browser to open the page
https://microsoft.com/devicelogin and enter the code H4WXXXXXX to authenticate.

ブラウザでhttps://microsoft.com/deviceloginを開いてターミナル上に表示されている認証コードH4WXXXXXXを入力します。
スクリーンショット 2019-03-03 13.51.18.png
ログインを求められたらAzureアカウントでログインします。
このログイン方法であれば多要素認証が有効なアカウントであっても認証が可能となります。
ブラウザでのログインが完了したらターミナルに戻り、以下のようにログイン情報が表示されて認証が成功していることを確認します。

#認証が成功していることを確認。
PS /> Connect-AzureRmAccount
WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code H4WXXXXXX to authenticate.                        

Account         SubscriptionName TenantId                             Environment                                                                                 
-------         ---------------- --------                             -----------
XXX@contoso.com YYYY             xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx AzureCloud

AzコマンドとAzureRMコマンド(実際はAzコマンド)が利用可能になりました。

PS /> Get-AzResourceGroup
ResourceGroupName : hogehoge
Location          : japaneast
ProvisioningState : Succeeded
Tags              : 
ResourceId        : /subscriptions/XXXXXXX・・・

PS /> Get-AzureRMResourceGroup
ResourceGroupName : hogehoge
Location          : japaneast
ProvisioningState : Succeeded
Tags              : 
ResourceId        : /subscriptions/XXXXXXX・・・

備考

  • ただブラウザからAzure PowerShellを利用したいということであれば、Azure Cloud Shellを利用された方がいいと思います。(わたしの場合はCloud9上にAzureほか各クラウドの設定Configを集約してGithubにpushする運用をしたいがため、このようなことをしています)

  • UbuntuでのPowerShell Coreの利用は、18.04が安定版のようです。18.10で実際に試してみましたがエラーとなり利用できませんでした。

https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-6

  • Cloud9のターミナルでPowerShellを利用しているとターミナルの動作がすごく不安定になるときがあります。(スクロールが効かなくなる、コマンドが打てなくなる、等)。もしそうなった場合は新規ターミナルを開き直してください。

  • Linux上でOffice365 や Exchange PowerShell も使いたいのですが、 .Net Core 対応はまだ先のようです。(追記:なんとこちらで無理やり使ってらっしゃる方がいました。そのうちわたしも検証してみます。)

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

nginx + djangoで adminページのsvgが表示されないやつを直す

初心者です

nginxとかに関しては全くの初心者で、そんな中引っかかった問題を書く。

環境

Docker: 2.0.0.3
django: 2.1.7
nginx: 1.15.9

問題

  • なんとかDockerでdjango + nginx + postgreの環境を整えて、デフォルトページが表示できた。
  • cssとかは動いているのにsvgだけ読み込まんのはなんで????

わかったこと

  • nginx側で静的ファイルをいい感じに振り分けていた。(djangoで/static/...のURIだったときはnginxの方にリクエストを流す)
  • どうやらmime.typesというファイルに、レスポンスするファイルのMIMEをすべて書き連ねないといかんらしい。
  • そうしないとnginx.confで設定されている application/octet-stream でヘッダが組まれてしまいいい感じにやってくれない

↓どっからかコピペしたnginx.conf

nginx.conf
...略
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /tmp/nginx.access.log combined;
    sendfile on;
    ...全略
}

どうやらmime.typesに書かれていないMIMEが要求された時、ここのdefault_typeとやらに勝手になってしまって、正常にMIMEを認識してくれない -> svgとして読み取らんからレスポンスが無い。

というわけでまたまたどっかからコピペしたmime.typesにsvgのMIMEを調べて追加

mime.types
types {
    text/html                             html htm shtml;
    text/css                              css;
    text/xml                              xml rss;
    image/gif                             gif;
    image/jpeg                            jpeg jpg;
    image/svg+xml                         svg;    # <-ココ
    application/x-javascript              js;
    text/plain                            txt;
}

無事にsvgが表示されるようになったとさ

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

dockerをサンドボックスにする(ubuntu16.04にapacheの環境構築をする例)

※ サンドボックスとして環境構築や動作検証をしたいケースには役立ちますが、実運用時は別の記事を参考にしてください。

ホストOSと同様の操作で環境構築を何度でも試せて、フレームワーク同士の競合を回避できるサンドボックスとして Docker を利用する方法を紹介します。

ベースイメージからコンテナを作成

--privileged をつけて /sbin/init を起動コマンドにすることで、systemctlが利用可能になります。

sudo docker run --privileged -d --name con -p 8080:80 ubuntu:16.04 /sbin/init

コンテナに入る

sudo docker exec -it con bash

必要なものをインストールする

コンテナの中で実行します。

apt update
apt upgrade -y
apt install -y vim git curl apache2 mariadb-server mariadb-client  

apacheを起動する

systemctl start apache2

コミットしてコンテナをイメージ化する

念の為、環境が壊れたときにコンテナを即座に作り直すためのイメージを作っておきます。

※ run 時の起動コマンドに /sbin/init を指定しているため、exitしてもコンテナは起動したままです。

exit

ホストOSで

sudo docker commit con con

コンテナを作り直す

環境構築に失敗してコンテナを作り直す場合は、下記のコマンドを実行します。

sudo docker rm -f con
sudo docker run --privileged -d --name cake -p 8080:80 con /sbin/init 

起動したら、再度apacheを起動してから環境構築に挑みます。

疎通確認

ホストOSのブラウザで http://localhost:8080/ にアクセスして、ページが表示されれば成功です。

記事を書いた理由

Googleで apache の構築手順を調べると、「httpd イメージを使ってみよう!」「docker-composeを使って〜」みたいな記事が多いです。

既存のイメージを使えばすぐに構築できますし、運用上は docker compose などを使って1プロセス1コンテナにすることで個別に最新バージョンにアップデートできるなどの利点はありますが、求めているものがそうでないことも多々あります。

例えば、自分はこのフレームワークってどんなものだろう?という単純な疑問が出たときに、その都度ホストOSを汚していたらキリがありません。だから仮想環境を使います。
とはいえ、そのフレームワーク以外の知識が求められるのが不便でならないという思いを何度もしてきました。

それを少しでも解消できればなぁと思いながら書きました。
少しでも気楽に環境構築ができる人が増えることを願っています。

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

[MailhogとLaravel]Expected response code 220 but got code "500"のエラー解決方法

Expected response code 220 but got code "500"

上記のようなエラーが発生する場合の解決方法

環境

  • docker
  • laravel
  • mailhog
  • 開発環境(ENV=development)

問題点:確実に環境変数

  • 500エラーが帰ってきているのでメールサーバにはアクセスできている
  • 環境変数自体がおかしいか、読み込めていない

実際に通る.env

MAIL_USERNAMEMAIL_PASSWORDMAIL_ENCRYPTIONはNULLを設定しておきましょう。

MAIL_DRIVER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

解決方法

上記の環境変数さえ読み込めれば、実行はできる。
もしこれを設定してできない場合は環境変数がうまく読み込めていない。
以下の手順で確認してください。

0.環境変数が読み込めているか確認するコマンド

\Config::get('mail')

上記コマンドを実行して、意図した環境変数になっているか確認。
image.png

なっていない場合は以下の手順を試すべし

1.キャッシュクリア

bash
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

2.環境変数ロード

bash
. .env
# もしくは環境変数を環境ごとに分けてる場合は読み込みたいファイルを指定
. .env.development

3.環境変数直接設定する

bash
MAIL_DRIVER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

4.最終手段、mail.phpを書き換える

環境変数を実際に読み込んでいるのはconfig/mail.phpというファイルだ。
ここの環境変数を読み込む部分を削除し、直接値を書き込んでしまえば良い。

bash
'encryption' => env('MAIL_ENCRYPTION', 'ssl'),

# こうなっているのをこうじゃ!

'encryption' => env(''),
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECSのバックエンドをEC2からFargateに変更

概要

ECS+EC2で動作しているアプリケーションをFargateに変更にします。
ECS+EC2での環境構築は、LaravelアプリケーションをAWS上のDockerで動かすを参考にしてください。

全てマネジメントコンソール上で行います。

前提条件

Farageteについて

メリット

  • コンテナのためのEC2の管理が不要
    • コンテナのスケールに合わせてインスタンスタイプの変更、あるいはスケールアウトさせる必要がない
    • インスタンスタイプの選択が不要
  • AutoScaleのタイミング設定が不要

デメリット

  • コンテナホストにssh接続できない
    • Dockerコマンドが実行できないため、コンテナの状況を確認するといったことができない
  • ログドライバがawslogsのみ

料金

EC2単位ではなく、コンテナ単位で料金が発生します。
下記の記事に最新の料金が記載されていましたので、参考にしてみてください。
2019年1月にAWS Fargateが大幅値下げしたのでEC2との価格比を確認してみた | DevelopersIO

nginxの設定ファイルを修正

Fargateでは、コンテナ間通信の宛先は127.0.0.1になります。
nginxの設定ファイルの一部を下記の通り変更します。

default.conf
# 変更前
fastcgi_pass php-fpm:9000;
# 変更後
fastcgi_pass 127.0.0.1:9000;

IAMロールを作成

ECSタスク実行ロールを作成します。
手順は、下記のecsTaskExecutionRole IAM ロールを作成するにはに従って作成してください。
Amazon ECS タスク実行 IAM ロール - Amazon Elastic Container Service

なお、タスク定義のリビジョンの作成前にECSタスク実行ロールが作成されている必要があります。新しいリビジョンの作成の途中でロールを作成した場合、ECSタスク実行ロールを選択することができず、エラーとなります。

ALBのターゲットグループを作成

ALBのターゲットグループのターゲットの種類はipである必要があります。
既存のEC2のALBのターゲットグループがターゲットの種類がinstanceとなっている場合、新規で作成する必要があります。

タスクの定義のリビジョンを作成する

Amazon ECS > タスク定義 から作成済みのタスクを選択し、新しいリビジョンの作成を選択します。

以下の項目を変更します。

項目
ネットワークモード awsvpc
互換性が必要 FARGATE

Fargateの場合、ネットワークモードはawsvpcを設定する必要があります。
nginxの設定ファイルを修正で、コンテナ間通信の宛先を127.0.0.1に変更した理由もここにあります。

タスクサイズ

項目
タスクメモリ (GB) 0.5GB
タスクメモリ (GB) 0.25vCPU

EC2の場合、設定はオプション項目となっていますが、FARGATEを選択した場合は必須となります。

コンテナの定義
コンテナのネットワーク設定でリンクを設定している場合、awsvpcではサポートされていないため変更する必要があります。今回は、EC2で動作している際に、nginxコンテナのネットワーク設定のリンクの設定を削除します。

また、ここではログの設定も行います。
コンテナでの運用の場合、コンテナを落とした際にログが消えてしまうため、ログを外部に出力する必要があります。
今回は、awslogsログドライバーを利用して、標準出力に出力されたログをCloudWatchに送信します。

ストレージとログのログ設定でログの出力先を設定します。
Auto-configure CloudWatch Logsにチェックを入れると、自動でロググループが作成されます。以上でログの設定は完了です。CloudWatchからログを確認することが可能となりました。

スクリーンショット 2019-03-02 15.15.24.png

そのほかの設定の変更がなければ作成を押下して、新しいリビジョンの作成は完了です。

サービスを作成する

Amazon ECS > クラスター から作成済みのクラスタを選択し、サービスタブの作成を押下します。

項目
起動タイプ FARGATE
タスク定義 上記で作成した新しいリビジョンを選択
プラットフォームのバージョン LATEST
クラスタ sample-api-cluster
サービス名 sample-fargate-api
サービスタイプ REPLICA
タスクの数 1

Elastic Load Balancing(オプション)

項目
ELB タイプ Application Load Balancer
サービス用の IAM ロールの選択 自動で生成されるAWSServiceRoleForECSサービスリンクロールが使用される
ELB 名 作成したALBを選択

負荷分散用のコンテナ

nginx:80:80を指定し、ELBへの追加を選択。
ターゲットグループ名に、作成したALBに紐づくターゲットグループを選択を選択。

以上で、ECSの環境構築は完了です。

動作確認

作成したALBのDNS名にアクセスし、動作確認を行います。

余談

Laravelのログを標準出力する際に、以下の余分なメッセージが出力される問題にぶつかりました。

WARNING: [pool www] child 10 said into stdout

原因と対応方法は、https://github.com/docker-library/php/issues/207 に記載されています。
また、PHP7.3ではこの問題が解消しており、 DockerイメージFROM php:7.3.2-fpm-alpineでは余分なメッセージが出力されていないことを確認できています。

参考記事

参考にさせていただきました。ありがとうございます。
AWS FargateでElixirのコンテンツ配信システムを動かしてみた (実装編) - エムスリーテックブログ
AWSにおける本番環境を想定したCI/CD実践 - y-ohgi's blog
AWS Fargate のすヽめ | 開発ブログ | Elastic Infra

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

NVIDIA Docker で HW accelerated な OpenGL(GLX) を動かす(2019 年版)

背景

  • ホストの GPU を使った OpenGL アプリを docker 経由で動かしたい(e.g. ホストが Ubuntu であるが, 動かしたい OpenGL アプリが CentOS しかサポートしていないなど)

nvidia/opengl

5 年近く前(!)に docker + opengl をやったときとから

https://qiita.com/syoyo/items/7a04b9ac457eed67da54

世の中はいろいろ進化しました.

beta レベルですが, NVIDIA が docker イメージを用意してくれています.

https://hub.docker.com/r/nvidia/opengl

そこそこ最新のドライバ(390+)であれば, libgvnd のバージョンを使うのがよさそうです.

設定例

https://hub.docker.com/r/coreyhanson/glxgears-nvidia

が参考になります.

基本的には, 普段の nvidia-docker run の引数に,

-v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY

を加えればいけます.

注意点として, docker コンテナ内で root で glxgears など動かそうとすると DISPLAY エラーになりますので, 実行用のアカウントを docker コンテナに作っておく必要があります
(Dockerfile に useradd あたりを追加し適当につくる)

CUDA と OpenGL もつかいたいよくばりな人向け

nvidia/cudagl があります.

https://hub.docker.com/r/nvidia/cudagl

TODO

  • tmp/.X11-unix をマッピングすることによるセキュリティはどうなのか考えてみる.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

プラグインインストール済のJenkins 構築 Docker編 その2

プラグインインストール済のJenkins 構築 Docker編 その1の続きです。

セットアップウィザードを無効にしましょう

環境変数JAVA_OPSに"-Djenkins.install.runSetupWizard=false"を設定するようにDockerfileを修正。

Dockerfile
FROM jenkins:2.19.4
ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=false"

Dockerfileからdocker imageを作成

# docker build -t myjenkins:3 .

コンテナの起動

# docker run -it -d --name myjenkins-3 -p 8080:8080 myjenkins:3

http://localhost:8080/ にアクセスしたら、セットアップウィザードを起動せず、jenkinsが使えるようになりました。

image.png

ただし、まだPluginが空です。
image.png

次回予告

Plugin Installの自動化
を実施したい。

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