DockerのECSプラグインを使う

ECS PluginはDockerの拡張機能
ECSのFargate上にデプロイすることができる

$ git clone https://github.com/docker/ecs-plugin.git
$ cd ecs-plugin/example/
$ docker build app -t example
$ docker images –filter reference=example
REPOSITORY TAG IMAGE ID CREATED SIZE
example latest 31ac32e7e8dd 18 seconds ago 52.9MB

$ docker run -t -i -p 5000:5000 example

OK(※redisが起動していない為)

### AWS ECS
DockerHubの様なもの
作成したDockerイメージをECRにpushし、docker-compose使用時にpull
$ docker context use default
$ docker context ls

### ECS用のIAM作成
こちらを参考にECSのユーザを作成する
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/get-set-up-for-amazon-ecr.html
accound_id, access_key_id, secret_access_keyをメモ

### AWS CLI install
$ dnf install python3-pip
$ pip3 install awscli –upgrade –user
$ aws –version
aws-cli/1.19.28 Python/3.6.8 Linux/4.18.0-193.19.1.el8_2.x86_64 botocore/1.20.2
$ aws configure
-> Administratorのaccess_key_id, secret_access_keyと ap-northeast-1を入力

$ timedatectl set-timezone Asia/Tokyo

$ aws ecr get-login-password –region ap-northeast-1 | docker login –username AWS –password-stdin hoge.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded

// レポジトリ作成
$ aws ecr create-repository \
–repository-name example \
–image-scanning-configuration scanOnPush=true \
–region ap-northeast-1
// タグ付け
$ docker tag example:latest hoge.dkr.ecr.ap-northeast-1.amazonaws.com/example:latest
// imageをpush
$ docker push hoge.dkr.ecr.ap-northeast-1.amazonaws.com/example:latest
$ aws ecr list-images –repository-name example
{
“imageIds”: [
{
“imageDigest”: “sha256:75260261d397dd588f43bd4fc16118cb2763c55c46caa313a9a2caf0202636f9”,
“imageTag”: “latest”
}
]
}

AWS console

イマイチよくわってないが、なんか出来とるな。。。

[CentOS8] docker-compose

$ sudo curl -L “https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)” -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose –version
docker-compose version 1.28.5, build c4eb3a1f

Dockerfile

FROM alpine
RUN apk add bash procps curl
CMD sh -c "(while :; do date; sleep 1; done) >&2"

docker-compose.yml

version: "3"

services:
  myalpine:
    build: "."
    tty: true

$ docker images
$ docker-compose up -d
$ docker ps
$ docker-compose stop

version: '3.7'

services:
  nginx:
    image: nginx
    ports:
      - 8080:80

$ docker-compose up -d

複数のコンテナ起動に威力を発揮する

[CentOS8] Docker環境構築

公式ガイドに沿って作っていきます。
1. リポジトリセットアップ
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
$ sudo yum-config-manager \
–add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum install docker-ce
$ sudo systemctl start docker
$ docker –version
Docker version 20.10.5, build 55c4c88
$ sudo docker run hello-world
Unable to find image ‘hello-world:latest’ locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24
Status: Downloaded newer image for hello-world:latest

Hello from Docker!

$ sudo docker pull centos
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 9 days ago 13.3kB
centos latest 300e315adb2f 3 months ago 209MB
$ sudo docker inspect 300
$ sudo docker run 300 echo “hello world”
hello world
$ sudo docker ps -a -n=5
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
79f86705caf2 300 “echo ‘hello world'” 42 seconds ago Exited (0) 40 seconds ago exciting_newton
3a66b7697532 hello-world “/hello” 16 minutes ago Exited (0) 16 minutes ago laughing_wu

// ハイフンdでバックグラウンドで走らせる
$ sudo docker run -d centos free -s 3

// コンテナの中に入って操作する -iはインタラクティブモード、-tはターミナル
$ sudo docker run -i -t centos /bin/bash

// image作成 username/${name}
$ sudo docker commit 646 hpscript/hello
$ sudo docker run -i -t hpscript/hello /bin/bash

// image -> container -> image はdocker build

vi Dockerfile

FROM centos
MAINTAINER hpscript <hoge@gmail.com>
# RUN build execute
RUN echo "now building..."
CMD ["echo", "now running..."]

// dockerfileによるbuild
$ sudo docker build -t hpscript/echo .
$ sudo docker run hpscript/echo
now running…

$ sudo docker build -t hpscript/httpd .
http://192.168.34.10:8000/
$ sudo docker login
// imageをpushする
$ sudo docker push ddddocker/test

ok
これをecsでec2にデプロイしたい

EC2(amazon linux2)上でDockerを使う

テスト用ですぐにterminateするため、EC2のスペックは最小限にします

### Launch instance
– Amazon Linux 2 AMI (HVM), SSD Volume Type
– type: t2.nano
– subnet: public
– Auto-assign Public IP: enable
– volume: GP2 8Gib
– Security Group: HTTP 0.0.0.0/0, SSH 0.0.0.0/0

### 前準備
$ ssh ec2-user@${public ip} -i ~/.ssh/${秘密鍵}.pem

// git install
$ sudo yum update
$ sudo yum -y install gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker autoconf
// 省略

### EC2にDocker.ceインストール
// Extras Libraryを見てみる
$ amazon-linux-extras
20 docker=latest enabled \
[ =17.12.1 =18.03.1 =18.06.1 =18.09.9 =stable ]
$ amazon-linux-extras info docker
docker recommends docker # yum install docker

ありますね、extrasからインストールします。
$ sudo amazon-linux-extras install docker
$ docker –version
Docker version 18.09.9-ce, build 039a7df

### Docker-compose install
$ sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose –version
docker-compose version 1.21.2, build a133471

## docker構築
### docker-compose.yml & Dockerfile
-docker-composeの構成やimageはlocal環境(ubuntu)と同じにする
-> nginx:1.13.5-alpine, node:12.13.0-alpine&php:7.3-fpm-alpine, FROM mysql:5.7.19

$ docker-compose build
ERROR: Couldn’t connect to Docker daemon at http+docker://localhost – is it running?
あれ?
$ sudo docker-compose build
sudo: docker-compose: command not found
ん?

権限をec2-userに付与する
$ sudo usermod -a -G docker ec2-user
$ cat /etc/group |grep docker
docker:x:993:ec2-user

$ docker info
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
あれ?

$ sudo service docker start
$ sudo docker info

### build & up -d
$ docker-compose build
$ docker-compose up -d
$ docker-compose ps
Name Command State Ports
———————————————————————-
app-1 docker-php-entrypoint php-fpm Up 9000/tcp
db-1 docker-entrypoint.sh mysql … Exit 1
nginx-1 nginx -g daemon off; Up 0.0.0.0:80->80/tcp
ん?
$ docker logs db-1

EC2でもswapメモリを増設する
$ sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
$ sudo /sbin/mkswap /var/swap.1
$ sudo /sbin/swapon /var/swap.1

$ docker-compose ps
Name Command State Ports
————————————————————————-
app-1 docker-php-entrypoint php-fpm Up 9000/tcp
db-1 docker-entrypoint.sh mysql … Up 0.0.0.0:3306->3306/tcp
nginx-1 nginx -g daemon off; Up 0.0.0.0:80->80/tcp

### 動作確認
$ docker exec -it app-1 sh
/var/www/html # ls
index.html index.php
$ docker exec -it nginx-1 sh
/ # cd /var/www/html
/var/www/html
$ docker exec -it db-1 bash
root@3e44157ee4fc:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.19 MySQL Community Server (GPL)

publicIPを叩く
http://**.***.***.***/
-> OK

なるほど、ローカルと全く一緒なので割と直ぐに環境構築ができます。
any application, anywhereが実感できる。
EC2の場合は冗長化が前提なので、mysqlのコンテナは必要なしでRDSに繋げるところが異なるか。vagrantが長かったせいか、商用環境にコンテナを使うのは違和感があったが、実際動かしてみると、Dockerでも別に差し支えないように見える。

インフラに変更を加えなければ、デプロイはCodeDeployで対応できそうだが、パッケージ等を入れるにしても、Dockerfileを更新するだけってのは確かに良いかも。
そして、デプロイやロードバランサまわり、オートスケーリングなどをkubernetesで管理するのね。

Docker + Laravel7.2 + CircleCIで継続的インテグレーション

### Docker環境の構築
CircleCIを使うにあたって、Dockerで環境を構築する
– nginx:1.13.5-alpine、node:12.13.0-alpine + FROM php:7.3-fpm-alpin、mysql:5.7.19で作成
※docker-compose.yml, Dockerfileの記載は省略

$ sudo docker-compose build
$ sudo docker-compose up -d
$ sudo docker ps
$ sudo docker exec -it app-1 sh

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar create-project –prefer-dist laravel/laravel app
$ php artisan –version
Laravel Framework 7.2.0

$ /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
$ /sbin/mkswap /var/swap.1
$ /sbin/swapon /var/swap.1
$ vi composer.json

"require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.3",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0",
        "laravel/ui" : "^2.0"
   },

$ php composer.phar update
$ php artisan ui vue –auth
$ php artisan migrate
$ npm install
$ npm run dev

$ sudo docker exec -it db-1 bash
$ mysql -u root -p
mysql> use mydb
mysql> show tables;
+—————–+
| Tables_in_mydb |
+—————–+
| failed_jobs |
| migrations |
| password_resets |
| users |
+—————–+
4 rows in set (0.07 sec)

// 動作確認、日本語のレコードが問題なく入るか
http://192.168.33.10/login
http://192.168.33.10/register
mysql> select * from users;

### Circle CI
– CircleCIでLaravelのMySQLを使ったテストを実行する
Experimental CircleCI images for MySQL
> The following is the customizations CircleCI applies in a Dockerfile:

FROM mysql:latest
ENV MYSQL_ALLOW_EMPTY_PASSWORD=true \
    MYSQL_DATABASE=circle_test \
    MYSQL_HOST=127.0.0.1 \
    MYSQL_ROOT_HOST=% \
    MYSQL_USER=root

config/database.php

'connections' => [

        'circle_test' => [
            'driver' => 'mysql',
            'host' => '127.0.0.1',
            'port' => '3306',
            'database' => 'circle_test',
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ], 

docker imageを選択する
-> laravelの環境に合わせてcircleci/php:7.3.9-apache-node-browsersにする
https://circleci.com/docs/ja/2.0/docker-image-tags.json

.circleci/config.yml

version: 2
jobs:
  build:
    docker:
      - image: circleci/php:7.3.9-apache-node-browsers
      - image: circleci/mysql:5.7

    environment:
      - APP_DEBUG: true
      - APP_ENV: testing
      - APP_KEY: base64:62bhVUIMcTWoVIzZm**************
      - DB_CONNECTION: circle_test
      - MYSQL_ALLOW_EMPTY_PASSWORD: true

    working_directory: ~/repo

    steps:
      - checkout

      - run: sudo docker-php-ext-install pdo_mysql

      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "composer.json" }}
          - v1-dependencies-

      - run: composer install -n --prefer-dist

      - save_cache:
          paths:
            - ./vendor
          key: v1-dependencies-{{ checksum "composer.json" }}

      - run: php artisan migrate
      - run: php artisan db:seed

      - run: php ./vendor/bin/phpunit

$ git add .
$ git config –global core.autoCRLF false
$ git commit -m “circleci”
$ git remote add origin https://github.com/hoge/circleci.git
$ git push -u origin master

repositoryをprivateにして再度 git push。
-> success
private repoでもできるのね。

というか、CircleCI自体がDockerのimageを使っているだけで、別にプロジェクト自体はDocker環境だけでなく、Vagrantでも行けそうですね。

Docker+laravel7.xでrequire laravel/uiでInstallation failed, reverting ./composer.json to its original content.

Dockerのphp:7.3-fpm-alpineで、composer require laravel/uiを入れようとすると「Installation failed, reverting ./composer.json to its original content.」のエラーになる。

$ php composer.phar require laravel/ui:^2.0
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing laravel/ui (v2.0.1): Downloading (100%)

Installation failed, reverting ./composer.json to its original content.


Warning: proc_open(): fork failed - Out of memory in phar:///var/www/html/composer.phar/vendor/symfony/console/Application.php on line 952

  [ErrorException]
  proc_open(): fork failed - Out of memory

最初、fork failed – Out of memoryのエラーが出ているので、swapメモリを増やしたが、結果は同じ。
$ /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
$ /sbin/mkswap /var/swap.1
$ /sbin/swapon /var/swap.1

色々調べたがLaravel7.x系は記事が少なく、原因はわからず。とりあえずcomposer.jsonに直接書いてupdateしてみることに。
$ vi composer.json

"require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.3",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0",
        "laravel/ui" : "^2.0"
   },
$ php composer.phar update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing laravel/ui (v2.0.1): Downloading (100%)
Writing lock file
Generating optimized autoload files
// 省略

上手くいきました。何故だろう???
Docker上でcomposer requireするときはcomposer.jsonに書かないと駄目なのか?理由が良く解らない。

Dockerでlaravel6.xのローカル環境構築(nginx, node, php, mysql)

Vagrantよりも軽量で、「any Application Anywhere」と言う通り、どのHardwareでも構築できるDockerでLaravel環境を構築したいと思います
※本当の動機は、Web系エンジニアであればDockerは使えて常識という空気感がある為。。

## 前準備
// OSはdockerが開発されているubuntu
$ uname -a
Linux vagrant-ubuntu-trusty-64 4.4.0-148-generic #174~14.04.1-Ubuntu SMP Thu May 9 08:17:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
// docker ceインストール済み
$ docker version
Version: 18.06.3-ce
// docker-compose インストール済み
$ docker-compose version
docker-compose version 1.21.2, build a133471
// git インストール済

▽UbuntuへのDockerインストール手順 ※trustyの場合、kernelを4.4に上げる必要あり
https://docs.docker.com/install/linux/docker-ce/ubuntu/
▽docker composeのインストール
$ sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

### 全体構成
構成は、currentに(1)docker-compose.ymlがあり、その下に、各コンテナ(2)web(nginx:1.13.5-alpine)、(3)app(node:12.13.0-alpine + FROM php:7.3-fpm-alpine)、(4)db(mysql:5.7.19)のフォルダと、(5)laravelのソースコードがある。

なぜapacheではなく、nginxを使っているかというと、php:*-fpm-alpineにbashでログインしてyum install httpd後に、systemctl start httpdしようとするとエラーになるため、enginxの方が都合がいい為。

また、Laravelはnode.jsは必須の為、nodeとphpのマルチビルドにしている。phpのコンテナを立ち上げて、nodeをインストールすればいいじゃないかと思うかもしれないが、基本的にコンテナ内での操作は最小限にする。

$ tree -L 3
.
├── app
│   └── Dockerfile ・・・(3)
├── data
│   └── ${appName} ・・・(5)
│       ├── app
│       ├── appspec.yml
│       ├── artisan
│       ├── bootstrap
│       ├── composer.json
│       ├── composer.lock
│       ├── composer.phar
│       ├── config
│       ├── database
│       ├── package.json
│       ├── package-lock.json
│       ├── phpunit.xml
│       ├── public
│       ├── README.md
│       ├── resources
│       ├── routes
│       ├── scripts
│       ├── server.php
│       ├── storage
│       ├── tests
│       ├── vendor
│       └── webpack.mix.js
├── db ・・・(4)
│   ├── Dockerfile
│   ├── initial.sql
│   └── my.cnf
├── docker-compose.yml ・・・(1)
└── web
    └── default.conf ・・・(2)

### (1)docker-compose.yml
laravelでのルーティングはpublicフォルダなので、[web](nginx)では、publicフォルダを同期させ、[app](php-alpine)では、アプリディレクトリを同期させる。

version: '3'
services:
  web:
    image: nginx:1.13.5-alpine
    ports:
      - "80:80"
    depends_on:
      - app
    volumes:
      - ./web/default.conf:/etc/nginx/conf.d/default.conf
      - ./data/${appName}/public:/var/www/html

  app:
    build: ./app
    env_file: .env
    environment:
      DATABASE_HOST: db
    depends_on:
      - db
    volumes:
      - ./data/${appName}:/var/www/html/nomad

  db:
    build: ./db
    env_file: .env
    ports:
      - "3306:3306"
    volumes:
      - db-data:/var/lib/mysql
      - ./db/initial.sql:/docker-entrypoint-initdb.d/initial.sql
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

volumes:
  db-data:

### (2)default.config
最後に、locationで「storage|js|css|img」へのアクセスを追記している。これをかかないと、css、js、img、storageが効かないので注意が必要

server {
    listen 80;
    server_name _;

    root  /var/www/html/${appName}/public;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(\.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location ~ ^/(storage|js|css|img)/.*$ {
        root /var/www/html;
    }
}

### (3)Dockerfile
g++, libstdc++, libgccをインストールしないと、nodeが動かないので注意が必要

FROM node:12.13.0-alpine as node

FROM php:7.3-fpm-alpine

RUN docker-php-ext-install pdo_mysql mysqli mbstring
RUN apk add --no-cache --virtual g++
RUN apk add --no-cache libstdc++ && apk add --no-cache libgcc

WORKDIR /var/www/html

COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -s /usr/local/bin/node /usr/local/bin/nodejs \
    && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
    && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx

### (4) db
Docker公式のmysqlは日本語対応していない為、my.confを作ってあげる必要がある。

Dockerfile

FROM mysql:5.7.19

ADD ./my.cnf /etc/mysql/my.cnf

RUN chmod 644 /etc/mysql/my.cnf

my.conf

[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin
[client]
default-character-set=utf8mb4

### (5) app
Laravelのプロジェクトをgit clone
.envのDB_HOSTは[db](mysql:5.7.19)のコンテナ名を入力する

### コンテナのbuild
$ sudo docker-compose build
$ sudo docker-compose up -d
$ sudo docker ps

// 立ち上がったら、[app](php-alpine)にログイン
$ sudo docker exec -ti ${containerId} sh
$ cd ${appName}
$ php composer.phar install
$ php composer.phar dump-autoload
$ php artisan key:generate
$ php artisan migrate
$ php artisan storage:link

// tableが作成されたら、[db](mysql:5.7.19)にログイン
$ sudo docker exec -ti ${containerId} bash
$ export LANG=ja_JP.UTF-8
// 省略: mysql の日本語化
$ mysql -u root -p
$ use ${dbName}
$ insert into …

### 動作確認
http://192.168.33.10/login

大体こんな感じか。ansibleでも書けるが、確かにdocker-composeとDockerfileでコード化できるところが面白い。
Vagratで構築するのとは全然異なるので、どちらで開発するかはよく考えた方が良さそう。

Docker MySQLで日本語入力できない時

mysql> show variables like ‘char%’;
+————————–+—————————-+
| Variable_name | Value |
+————————–+—————————-+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+————————–+—————————-+
8 rows in set (0.12 sec)

docker-compose.yml

  db:
    build: ./db
    env_file: .env
    ports:
      - "3306:3306"
    volumes:
      - db-data:/var/lib/mysql
      - ./db/initial.sql:/docker-entrypoint-initdb.d/initial.sql
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

./db/my.cnf

[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin
[client]
default-character-set=utf8mb4

./db/Dockerfile

FROM mysql:5.7.19

ADD ./my.cnf /etc/mysql/my.cnf

RUN chmod 644 /etc/mysql/my.cnf

$ sudo docker-compose build
$ sudo docker-compose up -d
$ sudo docker exec -it 325 bash
# mysql -u root -p
mysql> show variables like ‘char%’;
+————————–+—————————-+
| Variable_name | Value |
+————————–+—————————-+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+————————–+—————————-+

$ sudo apt-get update
$ apt-get install locales locales-all
$ dpkg-reconfigure locales
275. ja_JP.UTF-8 UTF-8 & 3
$ apt-get install vim

$ export LANG=ja_JP.UTF-8
$ vim ~/.bashrc

$ vim ~/.inputrc

set convert-meta off
set meta-flag on
set output-meta on

$ source ~/.inputrc

これで、Docker mysqlの日本語入力が可能となりました。
やばすぎるな、これ。

DockerのPHP + Node.jsマルチビルドでsymbol not found

Dockerで、「nginx:1.13.5-alpine」 + 「php:7.3-fpm-alpine」 + 「mysql:5.7.19」のコンテナ構成で、 laraveを使うため、「node:12.13.0-alpine as node + php:7.3-fpm-alpine」として、Node.jsを入れる。

Dockerfileを以下のようにマルチステージビルドでdocker-composeをbuildしてupすると、エラー出力

Dockerfile

FROM node:12.13.0-alpine as node

FROM php:7.3-fpm-alpine

RUN docker-php-ext-install pdo_mysql mysqli mbstring

WORKDIR /var/www/html

COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -s /usr/local/bin/node /usr/local/bin/nodejs \
    && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
    && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx

Nodeを実行すると No such file or directory | symbol not foundのエラーが大量に出る

$ sudo docker exec -it {containerId} sh
/var/www/html # php -v
PHP 7.3.15 (cli) (built: Feb 20 2020 23:51:19) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.15, Copyright (c) 1998-2018 Zend Technologies
/var/www/html # node --version
Error loading shared library libstdc++.so.6: No such file or directory (needed by /usr/local/bin/node)
Error loading shared library libgcc_s.so.1: No such file or directory (needed by /usr/local/bin/node)
Error relocating /usr/local/bin/node: _ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode: symbol not found
Error relocating /usr/local/bin/node: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9push_backEc: symbol not found
Error relocating /usr/local/bin/node: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEmc: symbol not found
// 省略

共有ライブラリを使っていてエラーになるらしい
Docker fileに以下の2行を追加する

RUN apk add --no-cache --virtual g++
RUN apk add --no-cache libstdc++ && apk add --no-cache libgcc

g++ はc++のコンパイラ
libstdc++は標準 C++ のライブラリ、c++をコンパイル時に使用
libgccはラインタイムライブラリ
Node.jsはc++なんですね。

Dockerfile

FROM node:12.13.0-alpine as node

FROM php:7.3-fpm-alpine

RUN docker-php-ext-install pdo_mysql mysqli mbstring
RUN apk add --no-cache --virtual g++
RUN apk add --no-cache libstdc++ && apk add --no-cache libgcc

WORKDIR /var/www/html

COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -s /usr/local/bin/node /usr/local/bin/nodejs \
    && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
    && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx

$ sudo docker exec -it ${containerId} sh
/var/www/html # php -v
PHP 7.3.15 (cli) (built: Feb 20 2020 23:51:19) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.15, Copyright (c) 1998-2018 Zend Technologies
/var/www/html # node -v
v12.13.0
/var/www/html # npm -v
6.12.0

うーん、結構きついね。

Dockerでnginx + php + mysql5.7

DockerでLaravel6.x環境を作ろうと思ったが、かなり苦戦。

version: '3'
services:
  web:
    image: nginx:1.13.5-alpine
    ports:
      - "80:80"
    depends_on:
      - app
    volumes:
      - ./web/default.conf:/etc/nginx/conf.d/default.conf
      - ./data/html:/var/www/html

  app:
    build: ./app
    env_file: .env
    environment:
      DATABASE_HOST: db
    depends_on:
      - db
    volumes:
      - ./data/html:/var/www/html

  db:
    image: mysql:5.7.19
    env_file: .env
    ports:
      - "3306:3306"
    volumes:
      - db-data:/var/lib/mysql
      - ./db/initial.sql:/docker-entrypoint-initdb.d/initial.sql

volumes:
  db-data:

メモリを増設しないとmysqlが起動しない。
$ sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
$ sudo /sbin/mkswap /var/swap.1
$ sudo /sbin/swapon /var/swap.1

$ sudo docker exec -it 749 bash
root@7491eb45c0f0:/# mysql -u root -p
Enter password:

$ sudo docker exec -it a5fce sh
/var/www/html # php -v
PHP 7.1.9 (cli) (built: Sep 27 2017 21:40:25) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
/var/www/html # node -v
sh: node: not found

phpを7.3にして、nodeを入れる必要がある。