[Docker] bind

$ sudo docker run -d –rm -p 8080:80 nginx:1.17.6-alpine
$ sudo docker container ls –format=’table {{.ID}}\t{{.Names}}\t{{.Ports}}’
$ sudo docker container port 09ee61149e2d
80/tcp -> 0.0.0.0:8080

Web系サービスを展開する場合、HTTPSの443とHTTP80が外部に公開される

コンテナ間の連携を行う場合は、bridgeではなく、作成したネットワークを利用する
作成したNATのネットワークが、内部のコンテナが他のコンテナを名前解決できる

### コンテナのログを設定
$ sudo docker container run –rm –name nginx -d nginx:1.17.6-alpine
$ sudo docker exec nginx cat /etc/nginx/nginx.conf
error_log /var/log/nginx/error.log warn;
access_log /var/log/nginx/access.log main;
エラー系のログが/var/log/nginx/error.logに書かれ、アクセスログが/var/log/nginx/access.logに書かれている

$ sudo docker exec nginx ls -l /var/log/nginx/error.log
lrwxrwxrwx 1 root root 11 Nov 20 2019 /var/log/nginx/error.log -> /dev/stderr
$ sudo docker exec nginx ls -l /var/log/nginx/access.log
lrwxrwxrwx 1 root root 11 Nov 20 2019 /var/log/nginx/access.log -> /dev/stdout

stderr, stdoutに出力されているのがわかります。

### bind
$ echo “hello bind” > hello1.txt
$ sudo docker run –rm -d –name bct \
–mount type=bind,source=/home/vagrant/dev/docker/book,target=/bindcont \
alpine:3.10.3 tail -f /dev/null
$ sudo docker exec bct ls /bindcont

$ sudo docker container exec bct touch /bindcont/hello2.txt
$ sudo docker stop bct
$ ls

readonlyにすることが多い

なるほど、標準出力、標準エラー出力はエイリアスが設定されてるんか…
標準出力は少し理解してきた

[Docker] 環境変数

nginxをリバースプロキシとして使用する
リバースプロキシーはロードバランサの一種で、クライアントからのアクセスを別のサーバに転送する

### 環境変数を使ったイメージのパラメーター
環境変数はシステムやアプリのパラメータを設定するもので、「キーとバリュー」の形式で管理されている。

アプリサーバー: 表示するメッセージ、ポート番号
リバースプロキシー: アプリサーバーのアドレス、待ち受けポート

pythonではosモジュールのenviron変数を使うことが一般的

server.py

import os, flask
MESSAGE = os.environ['MESSAGE']
PORT = int(os.environ['PORT'])

app = flask.Flask('c2env1_app')
@app.route('/')
def index():
	return MESSAGE

app.run(debug=True, host='0.0.0.0', port=PORT)

$ sudo docker run –name c2env1_app_base -d python:3.7.5-slim tail -f /dev/null
$ sudo docker exec c2env1_app_base pip install flask==1.1.1
$ sudo docker cp server.py c2env1_app_base:/
$ sudo docker stop c2env1_app_base
$ sudo docker commit c2env1_app_base c2env1_app
$ sudo docker run –name c2env1_app -p 8081:80 -d \
-e MESSAGE=”Hello Docker Env” -e PORT=80 \
c2env1_app python -u /server.py

nginx.tpl

events {
	worker_connections
}
http {
	server {
		server_name localhost:
		listen {{PORT}};
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr
		proxy_set_header X-Forwarded-Host $host
		proxy_set_header X-Forwarded-Server $host
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		location / {
			proxy_pass {{APP_SERVER}};
		}
	}
}

start.sh

#!/bin/sh
sed -e "s/{{PORT}}/$PORT/g" /etc/nginx/nginx.tpl > /etc/nginx/nginx.conf
sed -i -e "s^{{APP_SERVER}}^$APP_SERVER^g" /etc/nginx/nginx.conf
exec nginx -g "daemon off;"

$ sudo docker run –name c2env1_web_base -d nginx:1.17.6-alpine tail -f /dev/null
$ sudo docker cp start.sh c2env1_web_base:/
$ sudo docker exec c2env1_web_base chmod +x /start.sh
$ sudo docker cp nginx.tpl c2env1_web_base:/etc/nginx/
$ sudo docker stop c2env1_web_base
$ sudo docker commit c2env1_web_base c2env1_web

$ sudo docker run –name c2env1_web -p 8080:80 -d \
-e APP_SERVER=”http://172.17.0.2:80″ -e PORT=80 \
c2env1_web /start.sh

この様にも書ける
.env

APP_SERVER="http://172.17.0.2:80"
PORT=80

$ sudo docker run –name c2env1_web -p 8080:80 -d \
–env-file .env c2env1_web /start.sh

.envに変数入れて、–env-file .envでコマンド打てば、環境変数として扱えるのね。
これ凄いわ… ガチでビビるレベルや…

[Docker] flaskのアプリを作る

$ sudo docker container run –name base -it -p 8080:80 python:3.7.5-slim bash
# pip install flask==1.1.1

server.py

import flask
app = flask.Flask('app server')

@app.route('/')
def index():
	return 'Hello docker'

app.run(debug=True, host='0.0.0.0', port=80)

$ sudo docker container cp server.py base:/
# python server.py
Traceback (most recent call last):
File “server.py”, line 1, in
import os, flask
File “/usr/local/lib/python3.7/site-packages/flask/__init__.py”, line 14, in
from jinja2 import escape
ImportError: cannot import name ‘escape’ from ‘jinja2’ (/usr/local/lib/python3.7/site-packages/jinja2/__init__.py)

### コンテナからファイルを転送
$ sudo docker container cp base:/etc/hosts ./
$ cat hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 300da009fa4e

### コンテナのイメージ化
$ sudo docker commit base c2img1_app
$ sudo docker images;
REPOSITORY TAG IMAGE ID CREATED SIZE
c2img1_app latest 37a4ea8b1a13 5 seconds ago 189MB
$ sudo docker run –rm -p 8080:80 c2img1_app python -u /server.py
$ sudo docker image history c2img1_app

### imageをpush
$ sudo docker image tag c2img1_app ddddocker/c2img1_app:v1.0
$ sudo docker login
$ sudo docker push ddddocker/c2img1_app:v1.0

なんかやべえな…

[Docker] イメージの検索

### docker imageの検索
$ sudo docker serach python
$ sudo docker search -f “is-official=true” -f “stars=50” python
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
python Python is an interpreted, interactive, objec… 7220 [OK]
pypy PyPy is a fast, compliant alternative implem… 314 [OK]

### curlによるタグ一覧を取得
$ sudo apt install jq
$ curl -s https://registry.hub.docker.com/v1/repositories/python/tags | jq ‘.[].name’
latestは最新版とは限らないので、タグを指定した方が良い

### pull
$ sudo docker pull python:3.7.5-slim
$ sudo docker image inspect python:3.7.5-slim
$ sudo docker rmi mysql:5.7

凄いな、レベルが高いのは一瞬でわかるな…
参ったぜ…

CloudTrailとは

「いつ」「誰が」「何を」したのか記録するサービス
セキュリティグループの設定やデバイスの登録など管理イベント
S3バケットの操作などアクティビティ
90日間は無料

Event Historyで確認できる

なるほど、90日無料だけど、きちんとした運用にするなら保存した方が良さそうだな…

[Docker] コンテナのログを出力する

1. まずコンテナを起動
$ sudo docker run -dit –name myphp -p 8080:80 myphpimage
http://192.168.56.10:8080/

2. コンテナIDを確認
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
090665612e7b myphpimage “/bin/sh -c ‘/usr/sb…” 5 minutes ago Up 5 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp myphp

3. ログを確認
$ sudo docker logs -f 090665612e7b
AH00558: apache2: Could not reliably determine the server’s fully qualified domain name, using 172.17.0.2. Set the ‘ServerName’ directive globally to suppress this message

あれ…??? 違うimageでやってみます。
$ sudo docker build . -t myhttpd
$ sudo docker images;
$ sudo docker run -dit –name myhttpd -p 8080:80 myhttpd
$ sudo docker ps
$ sudo docker logs -f 6e69ac1678b5
AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using 172.17.0.2. Set the ‘ServerName’ directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using 172.17.0.2. Set the ‘ServerName’ directive globally to suppress this message
[Sun Mar 27 06:02:28.200386 2022] [mpm_event:notice] [pid 1:tid 139803119992128] AH00489: Apache/2.4.53 (Unix) configured — resuming normal operations
[Sun Mar 27 06:02:28.201876 2022] [core:notice] [pid 1:tid 139803119992128] AH00094: Command line: ‘httpd -D FOREGROUND’
192.168.56.1 – – [27/Mar/2022:06:02:31 +0000] “GET / HTTP/1.1” 200 213
192.168.56.1 – – [27/Mar/2022:06:03:01 +0000] “GET / HTTP/1.1” 304 –
192.168.56.1 – – [27/Mar/2022:06:03:53 +0000] “-” 408 –

$ docker logs -f ${コンテナID} で出力するのか

### アクセスログのみ表示したい時
$ sudo docker logs 6e69ac1678b5 -f 2>/dev/null
-> 2はエラーログで、/dev/nullは非表示

### エラーログのみ表示したい時
$ sudo docker logs 6e69ac1678b5 -f 1>/dev/null

Dockerのログはコンテナの標準出力(1), 標準エラー出力(2)に書き込まれた内容を表示する

phpのエラーログ
php.iniを以下の様に変更する

error_log = /dev/stderr
[/php]

なるほどー すげー 少しずつ理解できてきた^^

[GitLab] branchごとにjobを実行する

stages:
  - build
  - test

build_job1:
  stage: build
  script:
    - echo "this is develop"
  only:
    refs:
      - develop

build_job2:
  stage: build
  script:
    - echo "this is master"
  only:
    refs:
      - master

test_job:
  stage: test
  script:
    - echo "test"

$ git push -u origin develop

なるほどー

GitLab CI/CDでawsでデプロイする

Project の setting -> CI/CD -> variableでAWSのcredentialを設定する

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION

.gitlab-ci.yml

stages:
  - dev
  - deploy

# GitLab Container Repositoryにpush
build-job:
  stage: dev
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
  script:
    - docker build --pull -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

# GitLab Container RepositoryのimageをECRにpush
deploy-job:
  stage: deploy
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $ECR_REPOSITORY_NAME:$CI_COMMIT_SHA
    - docker logout
    - apk add --update py-pip
    - pip install awscli
    - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
    - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
    - aws configure set region $AWS_DEFAULT_REGION
    - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin $ECR_REPOSITORY
  script:
    - docker push $ECR_REPOSITORY_NAME:$CI_COMMIT_SHA

なるほどー
中々面白い

GitLab variables

ARTIFACT_DOWNLOAD_ATTEMPTS 8.15 1.9 実行ジョブのアーティファクトのダウンロード試行回数
CI all 0.4 CI環境で実行されていることを示します
CI_COMMIT_REF_NAME 9.0 all そのプロジェクトがビルドされているブランチ名かタグ名
CI_COMMIT_REF_SLUG 9.0 all $CI_COMMIT_REF_NAME を小文字化して 63バイトに短縮化 0-9 と a-z 以外は – に置換されます。先頭と末尾には – を使いません。URL、ホスト名、ドメイン名で使用できます。
CI_COMMIT_SHA 9.0 all ビルド中のプロジェクトのコミットリビジョン
CI_COMMIT_BEFORE_SHA 11.2 all プッシュリクエスト直前の最新コミットID
CI_COMMIT_TAG 9.0 0.5 コミットタグ名。ビルド中のタグのみ表示されます。
CI_COMMIT_MESSAGE 10.8 all コミットメッセージ全文
CI_COMMIT_TITLE 10.8 all コミットタイトル – コミットメッセージの最初の一行
CI_COMMIT_DESCRIPTION 10.8 all コミット詳細: タイトル行が100文字よりも短い場合の最初の一行を除いたメッセージです;それ以外の場合は全文です。
CI_CONFIG_PATH 9.4 0.5 CI設定ファイルのパス。デフォルトは .gitlab-ci.yml
CI_DEBUG_TRACE all 1.7 debug tracing が有効かどうか
CI_DEPLOY_USER 10.8 all GitLab Deploy Token の認証ユーザー名、プロジェクトが1つだけ関連付けられている場合にのみ出力
CI_DEPLOY_PASSWORD 10.8 all GitLab Deploy Tokenの認証パスワード、プロジェクトが一つだけ関連付けられている場合にのみ出力
CI_DISPOSABLE_ENVIRONMENT all 10.1 このジョブが使い捨てな環境で実行される場合にのみフラグを示します。 (この環境は、このジョブでのみ生成されるもので、実行後に削除もしくは破壊されるものです – shell と ssh を除く全てです ). この環境が使い捨ての場合、trueにセットされます。それ以外の場合は未定義です。
CI_ENVIRONMENT_NAME 8.15 all このジョブの環境名
CI_ENVIRONMENT_SLUG 8.15 all 環境名の簡易バージョン、DNS名やURL、Kubernetesのラベルなどに適しています。
CI_ENVIRONMENT_URL 9.3 all このジョブ環境のURL
CI_JOB_ID 9.0 all GitLab CI が内部的に利用する現在のジョブのユニークID
CI_JOB_MANUAL 8.12 all ジョブが手動実行されているかどうかを示すフラグ
CI_JOB_NAME 9.0 0.5 .gitlab-ci.yml で定義されているジョブ名
CI_JOB_STAGE 9.0 0.5 .gitlab-ci.yml で定義されているステージ名
CI_JOB_TOKEN 9.0 1.2 GitLab コンテナーレジストリで使える認証用トークン
CI_MERGE_REQUEST_ID 11.6 all pipelines for merge requests の場合のマージリクエストのID
CI_MERGE_REQUEST_IID 11.6 all pipelines for merge requests の場合のマージリクエストのIID
CI_MERGE_REQUEST_REF_PATH 11.6 all pipelines for merge requests の場合のマージリクエストのrefパス. (e.g. refs/merge-requests/1/head)
CI_MERGE_REQUEST_PROJECT_ID 11.6 all pipelines for merge requests の場合のマージリクエストのプロジェクトID
CI_MERGE_REQUEST_PROJECT_PATH 11.6 all pipelines for merge requests の場合のマージリクエストのプロジェクトパス (e.g. namespace/awesome-project)
CI_MERGE_REQUEST_PROJECT_URL 11.6 all pipelines for merge requests の場合のマージリクエストのプロジェクトのURL (e.g. http://192.168.10.15:3000/namespace/awesome-project)
CI_MERGE_REQUEST_TARGET_BRANCH_NAME 11.6 all pipelines for merge requests の場合のマージリクエストのターゲットブランチ名
CI_MERGE_REQUEST_SOURCE_PROJECT_ID 11.6 all pipelines for merge requests の場合のマージリクエストの元プロジェクトのID
CI_MERGE_REQUEST_SOURCE_PROJECT_PATH 11.6 all pipelines for merge requests の場合のマージリクエストの元プロジェクトのパス
CI_MERGE_REQUEST_SOURCE_PROJECT_URL 11.6 all pipelines for merge requests の場合のマージリクエストの元プロジェクトのURL
CI_MERGE_REQUEST_SOURCE_BRANCH_NAME 11.6 all pipelines for merge requests の場合のマージリクエストのソースブランチ名
CI_NODE_INDEX 11.5 all ジョブセット内のジョブのインデックス。ジョブが並列になっていない場合は、この変数はセットされません。
CI_NODE_TOTAL 11.5 all ジョブが並列実行のトータルインスタンス数。ジョブが並列になっていない場合は、この変数は1にセットされます。
CI_JOB_URL 11.1 0.5 実行ジョブ詳細のURL
CI_REPOSITORY_URL 9.0 all クローンするGitリポジトリのURL
CI_RUNNER_DESCRIPTION 8.10 0.5 GitLabに保存されているRunnerの説明
CI_RUNNER_ID 8.10 0.5 使われているランナーのユニークID
CI_RUNNER_TAGS 8.10 0.5 定義済みランナータグ
CI_RUNNER_VERSION all 10.6 実行中のジョブのGitLab ランナーのバージョン
CI_RUNNER_REVISION all 10.6 実行中のジョブのGitLab ランナーのリビジョン
CI_RUNNER_EXECUTABLE_ARCH all 10.6 GitLab ランナーの実行ファイルのOS/アーキテクチャ (これは実行環境と同じではないことに注意)
CI_PIPELINE_ID 8.10 0.5 GitLab CIが内部的に使用する現在のパイプラインのユニークID
CI_PIPELINE_TRIGGERED all all ジョブがtriggeredであるかを示しているフラグ
CI_PIPELINE_SOURCE 10.0 all このパイプラインのソース: push, web, trigger, schedule, api, external のどれか。9.5より前に作成されたパイプラインは不明です。
CI_PROJECT_DIR all all ジョブが実行されるリポジトリーがクローンされたフルパス
CI_PROJECT_ID all all GitLab CIが内部的に利用する現在のプロジェクトのユニークID
CI_PROJECT_NAME 8.10 0.5 現在ビルド中のプロジェクト名 (実際にはプロジェクトフォルダー名)
CI_PROJECT_NAMESPACE 8.10 0.5 現在ビルド中のプロジェクトネームスペース名 (ユーザー名かグループ名)
CI_PROJECT_PATH 8.10 0.5 ネームスペース付きのプロジェクト名
CI_PROJECT_PATH_SLUG 9.3 all $CI_PROJECT_PATH の 0-9 and a-z 以外を – に変換して、小文字にした。ドメイン名やURLからに利用できる。
CI_PROJECT_URL 8.10 0.5 プロジェクトにアクセスするHTTPアドレス
CI_REGISTRY 8.10 0.5 コンテナーレジストリが有効な場合、GitLab’s Container Registry のURLを返す
CI_REGISTRY_IMAGE 8.10 0.5 このプロジェクトでコンテナーレジストリが有効な場合、プロジェクトに紐付けられたレジストリのアドレスを返す
CI_REGISTRY_PASSWORD 9.0 all GitLab Container Registry にコンテナーをプッシュするときに使うパスワード
CI_REGISTRY_USER 9.0 all GitLab Container Registry にコンテナーをプッシュするときに使うユーザー名
CI_SERVER all all ジョブがCI環境で実行されていることを示す
CI_SERVER_NAME all all ジョブを調整するCIサーバー名
CI_SERVER_REVISION all all ジョブをスケジューリングする GitLab revision
CI_SERVER_VERSION all all ジョブをスケジューリングする GitLab version
CI_SERVER_VERSION_MAJOR 11.4 all GitLab コンポーネントのメジャーバージョン
CI_SERVER_VERSION_MINOR 11.4 all GitLab コンポーネントのマイナーバージョン
CI_SERVER_VERSION_PATCH 11.4 all GitLab コンポーネントのパッチバージョン
CI_SHARED_ENVIRONMENT all 10.1 ジョブが共有環境(shell や ssh のようなCI実行をまたいでいる)で実行されていることを示す。環境が共有されている場合は、trueに設定、そうでない場合設定されません。
GET_SOURCES_ATTEMPTS 8.15 1.9 このジョブ実行中のソース取得試行回数
GITLAB_CI all all GitLab CI環境で実行されていることを示す
GITLAB_USER_ID 8.12 all ジョブを開始した人のID
GITLAB_USER_EMAIL 8.12 all ジョブを開始した人のメールアドレス
GITLAB_USER_LOGIN 10.0 all ジョブを開始した人のログインユーザー名
GITLAB_USER_NAME 10.0 all ジョブを開始した人の実名
RESTORE_CACHE_ATTEMPTS 8.15 1.9 ジョブ実行中のキャッシュのリストア試行回数

https://qiita.com/ynott/items/4c5085b4cd6221bb71c5

なるほど、ここまではわかった。
次は、gitlabからECRへのpush

GitLabのトークン

GitLab Token
– Personal Access tokens
— GitLab API, GitLab repository, GitLab registry
– OAuth2 token
— OAuth2 ProviderとしてOAuth認証
– Impersonation tokens
— Personal access tokensの特殊な形
– Project access tokens
— Project単位のPersonal access tokens
– Deploy tokens
— git clone及びGitLab管理下のpackageとcontainer registryへのpush/pullを可能にする
– Deploy keys
— repositoryのread-onlyまたはread-writeのみ可能とする
  – projectのowner/maintainerが発行可能でcloneしてくるのに有用
– Runner registration token
— GitLabRunnerをGitLab側に登録する際に認証するためのtoken
— CI/CDのjobを実行するRunnerを紐付ける
– Runner authentication token
— GitLabRunnerの認証登録後にRunnerが入ったホストに登録されるtoken
— config.toml内に自動登録される
– CI/CD Job token
— CI/CD job実行時のAPI利用の際に認証に使用される一時的なtoken
— job内でrepositoryをclone, pushなどをする際に、CI_JOB_TOKENとして予め環境変数に定義されているものを即座に利用可能

なるほど
docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
これだと、gitlab-ci-tokenはCI/CD job tokenのことか