20191001のdockerに関する記事は13件です。

今日のdocker error: tar, wget

tar

docker/ubuntu
# tar zxvf NP_distr.Z 
tar: This does not look like a tar archive
tar: Skipping to next header
tar: Exiting with failure status due to previous errors
macOS
$ docker run -v /Users/administrator/work:/home/work -it gcc /bin/bash
macOS
$ tar zxvf NP_distr.Z 

ファイル共有してmac側で解答すればエラーにならなかった。

wget

docker/ubuntu
# wget http://www.itl.nist.gov/div897/ctg/suites/ITG.ps
URL transformed to HTTPS due to an HSTS policy
--2019-10-01 12:30:46--  https://www.itl.nist.gov/div897/ctg/suites/ITG.ps
Resolving www.itl.nist.gov (www.itl.nist.gov)... 132.163.4.36, 2610:20:6005:13::51, 2610:20:6b01:4::36
Connecting to www.itl.nist.gov (www.itl.nist.gov)|132.163.4.36|:443... connected.
GnuTLS: The TLS connection was non-properly terminated.
Unable to establish SSL connection.

# wget http://www.itl.nist.gov/div897/ctg/suites/ITG.ps
URL transformed to HTTPS due to an HSTS policy
--2019-10-01 12:34:19--  https://www.itl.nist.gov/div897/ctg/suites/ITG.ps
Resolving www.itl.nist.gov (www.itl.nist.gov)... 132.163.4.36, 2610:20:6005:13::51, 2610:20:6b01:4::36
Connecting to www.itl.nist.gov (www.itl.nist.gov)|132.163.4.36|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 181136 (177K) [application/postscript]
Saving to: 'ITG.ps'

ITG.ps                     100%[======================================>] 176.89K   217KB/s    in 0.8s    

2019-10-01 12:34:21 (217 KB/s) - 'ITG.ps' saved [181136/181136]

全く同じコマンドで、1度目はエラー、2度目はOK。

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

Posix Test Suite docker downloads

PCTS:151-2, POSIX Test Suite
https://www.itl.nist.gov/div897/ctg/posix_form.htm

macOS
$ docker run -v /Users/administrator/work:/home/work -it gcc /bin/bash
ubuntu
# apt update; apt -y upgrade ; apt install -y wget vim sudo apt-utils 
# wget http://www.itl.nist.gov/div897/ctg/suites/NP_distr.Z.exe
# wget http://www.itl.nist.gov/div897/ctg/suites/CVR.ps
# wget http://www.itl.nist.gov/div897/ctg/suites/ITG.ps

Guide

NIST-PCTS:151-2 Installation and Testing Guide October 1, 1995

Utilities - NIST-PCTS:151-2 requires the following utilities: • ar or a compatible library archiver;
• grep or a compatible pattern retriever,
• cc -E or a compatible macro preprocessor,
• extended cpio creating and reading utility to read the NIST-PCTS:151-2 distribution and create an extended cpio archive;
• extended tar format creating and reading utility to read and create an extended tar archive; • mkdir or a compatible directory maker;
• mknod or a compatible special file builder;
• mv or a compatible file mover;
• ranlib, or the System V ar/ld combination;
• rm or a compatible file remover;
• rm -r -f or a compatible directory tree remover;

docker/ubuntu
# mv NP_distr.Z.exe NP_distr.Z   
# tar zxvf NP_distr.Z 

tarがうまくいかなかった記録はこちら。

今日のdocker error: tar, wget
https://qiita.com/kaizen_nagoya/items/e49231092a4419368241

powershellで解凍がうまくいかなかった記録はこちら。

Posix Test Suite 解凍方法(Windows power shell版)
https://qiita.com/kaizen_nagoya/items/57ee061892bc9afcf860

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

Posix Test Suite docker downloads, tar, install

PCTS:151-2, POSIX Test Suite
https://www.itl.nist.gov/div897/ctg/posix_form.htm

macOS
$ docker run -v /Users/administrator/work:/home/work -it gcc /bin/bash
ubuntu
# apt update; apt -y upgrade ; apt install -y wget vim sudo apt-utils 
# wget http://www.itl.nist.gov/div897/ctg/suites/NP_distr.Z.exe
# wget http://www.itl.nist.gov/div897/ctg/suites/CVR.ps
# wget http://www.itl.nist.gov/div897/ctg/suites/ITG.ps

Guide

NIST-PCTS:151-2 Installation and Testing Guide October 1, 1995

Utilities - NIST-PCTS:151-2 requires the following utilities: • ar or a compatible library archiver;
• grep or a compatible pattern retriever,
• cc -E or a compatible macro preprocessor,
• extended cpio creating and reading utility to read the NIST-PCTS:151-2 distribution and create an extended cpio archive;
• extended tar format creating and reading utility to read and create an extended tar archive; • mkdir or a compatible directory maker;
• mknod or a compatible special file builder;
• mv or a compatible file mover;
• ranlib, or the System V ar/ld combination;
• rm or a compatible file remover;
• rm -r -f or a compatible directory tree remover;

docker/ubuntu
# mv NP_distr.Z.exe NP_distr.Z   
# tar zxvf NP_distr.Z 
# cd NIST-PCTS/
# cd ./src/install
# ./s_install 
# cd ../..
# ./bin/install ./scripts/utilities 
        NIST-PCTS:151-2, Version 1.8, 10/1/95


src/tools       Oct  1 12:54:25 2019
  ./sv_cmd
    c89 -c -I/home/work/NIST-PCTS/include sv_cmdcom.c

...

sv_expect.c:46:24: warning: 'char' is promoted to 'int' when passed through '...'
   46 |   c_saved = va_arg(ap, char);
      |                        ^
...
    z_gets.c: In function 'Zgets':
z_gets.c:59:2: warning: 'gets' is deprecated [-Wdeprecated-declarations]
   59 |  ret_val = gets(s);
      |  ^~~~~~~

# mv journal util_inst_rep
# ./bin/install ./scripts/NIST-PCTS 

        NIST-PCTS:151-2, Version 1.8, 10/1/95

STD/DEF     Oct  1 12:55:52 2019
  ./src/gen_terms
    c89 -c -I/home/work/NIST-PCTS/include gen_terms.c

...

    /usr/bin/ld: errno: TLS definition in //lib/x86_64-linux-gnu/libc.so.6 section .tbss mismatches non-TLS reference in 2.4_01.o
/usr/bin/ld: //lib/x86_64-linux-gnu/libc.so.6: error adding symbols: bad value
collect2: error: ld returned 1 exit status

    ERROR
    Command exited with an error.

...

    MESSAGE
    3.1.2_05x.c: In function 'main':
3.1.2_05x.c:136:18: warning: comparison between pointer and zero character constant [-Wpointer-compare]
  136 |    if(environ[2] != '\000')
      |                  ^~
3.1.2_05x.c:136:7: note: did you mean to dereference the pointer?
  136 |    if(environ[2] != '\000')
      |       ^

...

    MESSAGE
    3.1.2_38.c: In function 'main':
3.1.2_38.c:38:26: error: dereferencing pointer to incomplete type 'DIR' {aka 'struct __dirstream'}
   38 |      Zwrite(fd, (DIR *)&(*dirp), sizeof(DIR));
      |                          ^~~~~
3.1.2_38.c:38:41: error: invalid application of 'sizeof' to incomplete type 'DIR' {aka 'struct __dirstream'}
   38 |      Zwrite(fd, (DIR *)&(*dirp), sizeof(DIR));
      |                                         ^~~

    ERROR
    Command exited with an error.
    c89 -o ../../bin/3.1.2_38 3.1.2_38.o  /home/work/NIST-PCTS/lib/sv_tools.a /home/work/NIST-PCTS/lib/sv_base.a /home/work/NIST-PCTS/lib/sv_sys.a /home/work/NIST-PCTS/lib/tssf.a  /home/work/NIST-PCTS/lib/tssf.a 
    MESSAGE
    gcc: error: 3.1.2_38.o: No such file or directory

tarがうまくいかなかった記録はこちら。

今日のdocker error: tar, wget
https://qiita.com/kaizen_nagoya/items/e49231092a4419368241

powershellで解凍がうまくいかなかった記録はこちら。

Posix Test Suite 解凍方法(Windows power shell版)
https://qiita.com/kaizen_nagoya/items/57ee061892bc9afcf860

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

Dockerコンテナ・イメージの全削除コマンド

ローカルのお掃除するときにたまに使うのでメモ。

Dockerコンテナ全削除

docker ps -aq | xargs docker rm

Dockerイメージ全削除

docker images -aq | xargs docker rmi

参考

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

Golang - Go Modulesで開発環境の用意する

はじめに

今まで以下の流れで開発環境を用意しました。

GoModulesの存在を知り、以下の理由からもう一度開発環境を見直すことにしました。

  • バージョン管理のデファクトスタンダードになる(なってる?)GoModulesを理解したかった
  • GoModulesを使用することで、設定に苦しんだGOPATH関連の制限から解放されそうだった

Go Modules

GoModulesは、Go1.11から導入され始めたGoの新しいバージョン管理システムになります。
詳細については、以下を参照いただくのが良いと思います。
GoModulesの概要から、今までのバージョン管理との違いまで把握できます。

GOPATH mode から module-aware mode

今まで(GOPATH mode)は標準pkg以外を全部 $GOPATH 以下のディレクトリで管理する仕様となっており
プロジェクトも $GOPATH/src 配下に作成する必要がありました。この制約で上記の開発環境を用意する際にかなり苦しみました。

しかし、module-aware mode では標準pkg以外の全てのパッケージをモジュールとして扱い、モジュールの管理やビルドが任意のディレクトリで可能になりました。($GOPATH/src にプロジェクトを配置しちゃダメというわけではなそう)

環境構築

go(1.10以降)とVSCodeはインストール済みの状態から始めたいと思います
私はgo(1.13.1)、VSCode(1.38.1)でやっています

環境変数

.zshrc(Shellによる)
export PATH=$GOPATH/bin:$PATH
export GOPATH=$HOME/go
export GO111MODULE=on

※GOPATHはプロジェクトと違うディレクトリで試したかったので $HOME/go にしています

GO111MODULE はGOPATH modeとmodule-aware modeを切り替えるための環境変数です。
Go 1.13からデフォルトが on になる予定だったようですが、どうやら auto がデフォルトになっているそうです。
そのため環境変数に上記を設定します。

  • on :Go modules を使う (module-aware mode)
  • off :$GOPATH を使う (GOPATH mode)
  • auto :$GOPATH/src の外に対象のリポジトリがあり、 go.mod が存在する場合は module-aware mode、そうでない場合は GOPATH mode

ディレクトリの作成

以下の構成でディレクトリを作成します

参考:Modules#quick-start

$  tree -F GolangProjects
GolangProjects
└── github.com/
    └── so-heee/
        └── modules_example/

モジュールの初期化

以下のコマンドでモジュールを初期化します
初期化すると go.mod ファイル(モジュールを管理するファイル)が出来ます

$ go mod init github.com/so-hee/modules_example
go: creating new go.mod: module github.com/so-hee/modules_example
└── modules_example
    └── go.mod

サンプルプログラムの作成

hello.go
package main

import (
    "fmt"
    "rsc.io/quote"
)

func main() {
    fmt.Println(quote.Hello())
}

ビルドと実行

作成したファイルをビルドすると、依存パッケージである rsc.io/quote がダウンロードされます

$ go build -o hello
go: finding rsc.io/quote v1.5.2
go: downloading rsc.io/quote v1.5.2
go: extracting rsc.io/quote v1.5.2
go: downloading rsc.io/sampler v1.3.0
go: extracting rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: extracting golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: finding rsc.io/sampler v1.3.0
go: finding golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c

GOPATHに設定したディレクトリにパッケージがダウンロードされています

$ tree -F go -L 3 -d
go
└── pkg
    └── mod
        ├── cache
        ├── golang.org
        └── rsc.io

また go.sum ファイル(依存モジュールのチェックサムの管理をしてるファイル)が作成されています
ビルドしたファイルを実行してみます

$ ./hello
Hello, world.

VSCodeでの環境設定

上記のフォルダをVSCodeで開きます

拡張機能インストール

Cmd + Shif + x でExtensionMarketplaceを開いてGoをインストール

スクリーンショット 2019-09-22 20.03.18.png

先ほど作成したhello.goのファイルを開くとツールのパッケージをインストールするか聞かれるのでインストールしましょう

スクリーンショット 2019-10-01 16.15.05.png

聞かれない場合がもしあった場合は、Cmd + Shift + P でコマンドパレットを表示
GO: Install/Update Tools で全て選択してインストールしましょう

独自パッケージの作成

新規でパッケージを作成し、mainでimportしてみます

modules_example/calc/calc.go
package calc

// Sum は引数a, bを合算して返却します
func Sum(a, b int) int {
    return a + b
}
hello.go
package main

import (
    "fmt"

    "github.com/so-heee/modules_example/calc"
    "rsc.io/quote"
)

func main() {
    fmt.Println(quote.Hello())
    fmt.Println(calc.Sum(1, 2))
}

問題なくimportできたので、実行してみます。F5でデバッグしてみます

Hello, world.
3

Dockerを使った開発環境の設定

dockerのインストール

Homebrewでdockerをインストールします(Homebrewの使い方は省略します)

$ brew cask install docker
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> Updated Formulae
dbmate                kops                  mosquitto            rabbitmq

==> Satisfying dependencies
==> Downloading https://download.docker.com/mac/stable/38240/Docker.dmg
######################################################################## 100.0%
==> Verifying SHA-256 checksum for Cask 'docker'.
==> Installing Cask docker
==> Moving App 'Docker.app' to '/Applications/Docker.app'.
?  docker was successfully installed!

$ docker --version
Docker version 19.03.2, build 6a30dfc

VSCodeにRemote-Containersのインストール

Cmd + Shif + x でExtensionMarketplaceを開いて Remote-Containers を検索してインストールします

スクリーンショット 2019-09-26 12.36.38.png

設定ファイルの作成

左下の矢印アイコンを選択します

スクリーンショット 2019-09-26 12.33.32.png

今度は Remote-Containers: Add Development Container Configuration Files を選択します
何の開発環境を作るか聞かれるためGoを選択します

スクリーンショット 2019-09-26 17.33.21.png

選択すると先ほどのサンプルであった.devcontainerディレクトリが作成され
その下にdevcontainer.jsonDockerfileが入っています

スクリーンショット 2019-10-01 17.03.23.png

Dockerコンテナの作成

左下の矢印アイコンを選択します

Remote-Containers: Open Folder in Container を選択し、フォルダを選択します
スクリーンショット 2019-09-26 12.33.09.png

ビルドが開始されます

スクリーンショット 2019-09-26 13.56.13.png

スクリーンショット 2019-09-26 17.41.31.png

ビルド中にdetailsを押すと、ターミナルにビルドの状況が表示されます

完了するとエクスプローラーに表示されます

スクリーンショット 2019-10-01 17.13.00.png

コンテナ上でGOのプログラムを実行

ターミナルタブを開いて、右側のプルダウンを 1:bash にします
hello.goを実行してみます

するとコンテナ上のGOPATH(devcontainer.jsonのgo:gopath)に依存パッケージがダウンロードされます
ローカルの時と同じですね。

root@4f93101644d1:/workspaces/GolangProjects/github.com/so-heee/modules_example# go run ./hello.go 
go: downloading rsc.io/quote v1.5.2
go: extracting rsc.io/quote v1.5.2
go: downloading rsc.io/sampler v1.3.0
go: extracting rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: extracting golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: finding rsc.io/quote v1.5.2
go: finding rsc.io/sampler v1.3.0
go: finding golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
こんにちは世界。
3

※こんにちは世界になるのは別の問題だと思うので今回は無視します(F5実行は問題ありません)

課題(依存先モジュールの編集する時)

githubで公開すると、基本的にそちらを参照してしまうため、ローカルで修正しても動作が変わりませんでした。。。
対応策としてgo.modを一時的に書き換えてreplaceディレクティブを使う方法や、go mod vendor でvendorを書き出してしまってそれを編集するなどがあるようですが、そもそも開発スタイルが正しいのか不安が残ります。
こちら解決策ご存知の方、もしくは別の方法をとってる方などいましたら是非ご教示ください!!

参考:最近のGo Modulesプラクティス ~ ghqユーザーの場合も添えて

参考

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

Dockerコンテナから、同一ホストマシンのPostgresqlに接続する(CentOS7)

Dockerコンテナから、(コンテナを起動している)ホストで起動しているPostgresqlに接続できなかった時に試行錯誤した備忘録的なやつ。

前提

  • Dockerネットワークはデフォルト(bridge)で起動する
  • Postgresqlの接続設定をやったけど動かなかった

環境

  • CentOS 7.7
  • Postgres Server 9.2.24
  • Docker 1.13.1

結論

firewalldにPostgresqlを追加する。

# firewall-cmd --zone=public --add-service=postgresql
# firewall-cmd --reload

1個目のfirewall-cmdコマンドに--permanentオプションをつけるとOSを再起動しても設定が継続する。

参考

http://www.madeinclinic.jp/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/20150118/

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

Dockerコンテナから、同一ホストマシンのPostgresqlに接続できるようにする(CentOS7)

Dockerコンテナから、(コンテナを起動している)ホストで起動しているPostgresqlに接続できなかった時に試行錯誤した備忘録的なやつ。

前提

  • Dockerネットワークはデフォルト(bridge)で起動する
  • Postgresqlの接続設定をやったけど動かなかった

環境

  • CentOS 7.6
  • Postgres Server 9.2.24
  • Docker 1.13.1

結論

firewalldにPostgresqlを追加する。

# firewall-cmd --zone=public --add-service=postgresql
# firewall-cmd --reload

1個目のfirewall-cmdコマンドに--permanentオプションをつけるとOSを再起動しても設定が継続する。

参考

http://www.madeinclinic.jp/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/20150118/

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

Puppeteerでメモリリーク対策

初めに

Dockerコンテナ上でPuppeteerを使ってスクレイピングをしていたらPossible EventEmitter memory leak detected.なるエラーが発生。

emitter.setMaxListeners()を使ってもエラーが解消されず困っていたのですが、この問題に関するissueを参照したら解消したので、備忘録として残しておきます。

今回のサンプルをGithubにあげましたので、適度確認下さい。

環境情報

環境としてWindows 10 ProDocker(Docker Desktop)上のNode.jsTypeScript + Puppeteerのプログラムを実行しています。

$ docker.exe --version
Docker version 19.03.2, build 6a30dfc

$ docker-compose.exe --version
docker-compose version 1.24.1, build 4667896b

$ docker-compose.exe run scraping cat //etc/issue
Debian GNU/Linux 9 \n \l

$ docker-compose.exe run scraping node --version
v10.15.3
package.json
{
  "dependencies": {
    "@types/node": "^12.7.8",
    "@types/puppeteer": "^1.19.1",
    "puppeteer": "^1.20.0",
    "ts-node": "^8.4.1",
    "tsc": "^1.20150623.0",
    "typescript": "^3.6.3"
  }
}

問題があったコード

index.ts
import puppeteer from 'puppeteer';

(async () => {
    const urlList = [
        "https://qiita.com/nobodytolove123/items/5fbb35d3a036989acc04",
        "https://qiita.com/nobodytolove123/items/895463907df00aba912f",
        "https://qiita.com/nobodytolove123/items/112562699f8ac8d36937"
    ];

    let browser: puppeteer.Browser;

    try {
        browser = await puppeteer.launch({
            args: [
                '--no-sandbox',
                '--disable-setuid-sandbox'
            ]
        }).catch(e => { throw(e) });

        const page: puppeteer.Page = await browser.newPage();

        urlList.forEach(async (url) => {
            await page.goto(url, { waitUntil: "domcontentloaded" }).catch(e => {
                throw (e.message);
            });

            console.log(await page.title());
        });
    } catch(e) {
        throw (e.message);
    } finally {
        if (browser) {
            browser.close();
        }
    }
})();

エラー

$ docker-compose run scraping
(node:1) UnhandledPromiseRejectionWarning: Navigation failed because browser has disconnected!
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:1) UnhandledPromiseRejectionWarning: Navigation failed because browser has disconnected!
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:1) UnhandledPromiseRejectionWarning: Navigation failed because browser has disconnected!
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)

対応策

上記のエラーを解消するため、issueを参照した所、複数回に渡って連続でpage.gotoする場合、毎回browser.close()をするとよいとの回答がありました。

なので、workというgoto毎にbrowser.close()を行うジョブ関数を定義し、work関数が再起という形で自身を呼び出す実装を行います。

index.ts
import puppeteer from 'puppeteer';

(async () => {
    const urlList = [
        "https://qiita.com/nobodytolove123/items/5fbb35d3a036989acc04",
        "https://qiita.com/nobodytolove123/items/895463907df00aba912f",
        "https://qiita.com/nobodytolove123/items/112562699f8ac8d36937",
    ];

    const work = async (url) => {
        let browser: puppeteer.Browser;

        try {
            browser = await puppeteer.launch({
                args: [
                    '--no-sandbox',
                    '--disable-setuid-sandbox'
                ]
            }).catch(e => { throw (e) });

            const page: puppeteer.Page = await browser.newPage();

            await page.goto(url, { waitUntil: "domcontentloaded" });

            console.log(await page.title());
        } catch (e) {
            throw (e);
        } finally {
            if (browser) {
                browser.close();
            }

            if (urlList.length) {
                work(urlList.shift());
            }
        }
    }

    try {
        work(urlList.shift());
    } catch(e) {
        console.log(e);
        process.exit(-1);
    }
})();
$ docker-compose.exe run scraping
最近傍点の抽出 - Qiita
Babelでnamespace、moduleをトランスパイルする - Qiita
Docker + Laravel 学習メモ - Qiita

クラス分割

以降はおまけです、ソースをスッキリするためにクラスに分割してみます。

main.ts
import CrewlWorker from './crewl_worker';

(new CrewlWorker()).run();
crewl_worker.ts
import Puppeteer from './puppeteer'

export default class CrewlWorker {
    urls: string[];

    public async run() {
        this.urls = await this.getWorkUrls();
        this.crawlPage(this.urls.shift());
    }

    public async getWorkUrls(): Promise<string[]> {
        return new Promise((resolve) => {
            resolve([
                "https://qiita.com/nobodytolove123/items/5fbb35d3a036989acc04",
                "https://qiita.com/nobodytolove123/items/895463907df00aba912f",
                "https://qiita.com/nobodytolove123/items/112562699f8ac8d36937",
            ]);
        });
    }

    async crawlPage(url: string) {
        let pup: Puppeteer;

        try {
            pup = await new Puppeteer().initialize();

            await pup.page.goto(url, { waitUntil: "domcontentloaded" });

            console.log(await pup.page.title());
        } catch (e) {
            throw (e);
        } finally {
            if (pup) {
                pup.browser.close();
            }

            if (this.urls.length) {
                this.crawlPage(this.urls.shift());
            } else {
                process.exit(0);
            }
        }
    }
}
puppeteer.ts
import puppeteer from 'puppeteer';

export default class Puppeteer {
    public browser: puppeteer.Browser;
    public page: puppeteer.Page;

    private launchArg: any = {
        args: [
            '--no-sandbox',
            '--disable-setuid-sandbox'
        ]
    };

    public async initialize() {
        return new Promise<this>(async (resolve, reject) => {
            try {
                this.browser = await puppeteer.launch(this.launchArg);
                this.page = await this.browser.newPage();
            } catch (e) {
                reject(e);
            }

            resolve(this);
        });
    }
}
$ docker-compose.exe run scraping ./node_modules/.bin/ts-node main.ts
最近傍点の抽出 - Qiita
Babelでnamespace、moduleをトランスパイルする - Qiita
Docker + Laravel 学習メモ - Qiita

最後に

今回はエラーを回避しつつ、Puppeteerを使ったスクレイピングを行いました。

しかし私はPuppeteerTypeScriptは初心者ですので、何か突っ込みがあればコメントにてお待ちしております。

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

ローカル開発環境をmampからdockerに移した話

やりたかった事、背景

・元々の開発環境はmampだった
・新しくプロジェクトを追加する時、スクリプト動かしてvhost記述して、みたいな感じでめんどかった
・port番号が8888のせいでめんどい時があった(設定次第で別にmampでもできる)
・上司にdocker環境を進められて、興味があった
・社内で使っていたdocker開発環境だと自分の環境ではxdebugが動かなかった。また、その環境はコンテナがプロジェクトファイルのhtdocsフォルダに紐つけられていて、プロジェクトを再配置するのがだるかった

じゃあもうdockerで自分で環境作っちゃえ!!!

実際にやった事

・ローカル環境のhttps化(オレオレ)
・VirtualDocumentRootを使ってvhostをワイルドカード化した(超楽になった)
・xdebug動くようにした
・php5とphp7切り替えられるようにした
・mailhogつけた
importがめんどかったのでdbのデータもディレクトリ写すだけでできるようにした

dbのデータだけはなぜかできなかったので誰かプルリク投げてください。。。

いろんなサイト参考にしていいとこ取りしまくりました。。すみません。。。

レポジトリはgithubに公開してます。

docker-compose up -d で動きます。是非とも使用して、ガシガシ開発しましょう!!!

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

ローカル開発環境をmampからdockerに移した話(Docker-sync対応)

やりたかった事、背景

・元々の開発環境はmampだった
・新しくプロジェクトを追加する時、スクリプト動かしてvhost記述して、みたいな感じでめんどかった
・port番号が8888のせいでめんどい時があった(設定次第で別にmampでもできる)
・上司にdocker環境を進められて、興味があった
・社内で使っていたdocker開発環境だと自分の環境ではxdebugが動かなかった。また、その環境はコンテナがプロジェクトファイルのhtdocsフォルダに紐つけられていて、プロジェクトを再配置するのがだるかった

じゃあもうdockerで自分で環境作っちゃえ!!!

実際にやった事

ローカル環境のhttps化(オレオレ) どうやらdockerだとオレオレダメみたい。。。。今度対応します
・VirtualDocumentRootを使ってvhostをワイルドカード化した(超楽になった)
・xdebug動くようにした
・php5とphp7切り替えられるようにした
・mailhogつけた
importがめんどかったのでdbのデータもディレクトリ写すだけでできるようにした

dbのデータだけはなぜかできなかったので誰かプルリク投げてください。。。

いろんなサイト参考にしていいとこ取りしまくりました。。すみません。。。

レポジトリはgithubに公開してます。

docker-compose up -d で動きます。是非とも使用して、ガシガシ開発しましょう!!!

2019/10/02追記 Docker-sync対応

使っていただいている方からDocker for Mac環境で使用しているとファイルioがとても遅いとの情報をいただき、調べたところioを早くするためにdocker-syncなるものがあるようで、調べてきました

docker-sync とは?

通常、dockerコンテナとホストos間でvolumeをマウントしているとDockerとmacのファイルシステムの相性が悪くioがとても遅いという欠点があるそうです。
それはホストosにあるsrcに対してioを行なっているため遅いそうで、docker-syncはマウントする用のコンテナを立ち上げ、そことioを行うため爆速になるそうです。

試した結果。。。。

まじで爆速になりました。docker-syncしゅごい。

やったこと

https://qiita.com/pocari/items/0340049742927f3a94b7
を参考にさせてもらいました。

上から実行すればオーケーです。

$ gem install docker-sync
$ brew install fswatch
$ brew install unison

unisonはホスト<->dockerのミドルウェアです。ホスト->dockerのミドルウェアもあります。詳しくは調べてみてください。

次にoverride用のdocker-compose-dev.ymlと実際にsyncするvolumeの設定をするdocker-sync.ymlを追加しました

docker-compose-dev.yml
version: '2'

volumes:
  sync-volume:
    external: true

services:
  web:
    volumes:
      - sync-volume:/var/www/html:nocopy

ここで重要なのはvolumesのコンテナ側にnocopyオプションを使うことです。作者が言うんだから間違いないです。w

docker-sync.yml
version: '2'

syncs:
  sync-volume:
    src: '/Path/to/your/Projects'

srcにはあなたのプロジェクトフォルダを指定してください。

ここまで終わったらいよいよdocker-syncの出番です。docker-sync startで行っちゃってください!

docker-sync start中にrubyのヘッダファイルがないよーとか言われた方

最初はなんかこんなの出ると思います

mkmf.rb can't find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/include/ruby.h

これはrubyがinstallされてないから起こるようで、installしましょう。w

//xcode commandlinetoolはinstallされているものとします
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg

後は明日の朝ごはんでも考えながらdocker-syncが動くのをゆっくり待ちましょう。

Projectフォルダにいっぱいあると相当時間かかりました。(自分の環境だと20分くらい)
ここで待てば今後待つことはないと考えて待ちましょう

UNISON 2.51.2 (OCAML 4.06.1) finished propagating changes at 23:47:09.99 on 02 Oct 2019
Saving synchronizer state
Synchronization complete at 23:47:10  (51 items transferred, 0 skipped, 0 failed)
real    37m 53.47s
user    3m 13.34s
sys 6m 10.06s
chown ing file to uid 0
39642ca3c32d338b0abaeb1bb654d44f20056bbaf89069dc58062d4f1b0c729a
     success  Sync container started
     success  Starting Docker-Sync in the background

みたいなのが出たら成功です。ようこそ快適docker環境へ。hello docker。

cakephp系を使用していて、tmp/cacheがnot writableと言われた方へ

docker exec -it web-php* chmod -R 777 /var/www/html/{Projects}/app/tmp/

ってコマンドを実行してみてください

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

Docker-Composeで実行中のアプリケーションをホスト側OSのwebサーバーで待受けリバースプロキシでフォワードする

アプリケーションサーバをDocker(docker-compose)で構築して
ホスト側のWebサーバーからリバースプロキシでDockerアプリケーションにフォワードする方法

1. Dockerで構築した10080ポートで実行しているWebアプリケーション

ホストOSの中で http://localhost:10080 で動作するWebアプリケーションが
実行中だとします。

それをホストOS側のnginxでリバースプロキシでフォワードしたい場合のnginx.confの設定

nginx.conf
http  {

    ...

    server {
        # 待受ポート
        listen 80;
        listen [::]:80;
        # 独自ドメイン
        server_name your-domain.com

        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-For $proxy_add_x_forwarded_for;
        proxy_set_header "special-header";
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        # 当該設定のドキュメントルートを設定
        root /var/www/html/public_html_fuku;
        # 以下の記述でプロキシ設定を実行する
        location / {
            proxy_pass http://localhost:10080 ;
            # 非公開アプリケーションのため nginxでbasic認証を実装する
            # .htpasswdは任意の方法で生成する
            auth_basic "basic  authentication";
            auth_basic_user_file /etc/nginx/.htpasswd;
        }
        # リバースプロキシは行うものの、特定のパターンのURLのみ特定ページへリダイレクトさせたい場合
        # apacheのmod_rewrite機能と同等機能
        rewrite /special_pattern/(.*)  /replace/ last;
    }

    ...

}


以上が、 80ポートで待ち受けるアプリケーションの設定
次に 443ポート(SSL)で待ち受けるアプリケーションの設定

2. Dockerで構築した3000ポートかつhttp2で実行しているWebアプリケーション

nginx.conf
http {

    ...

    server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  your-domain.com;
        root         /var/www/html/your-domain.com;

        # フォワードさせるアプリケーションが利用している ssl接続の証明書のパスを
        # 以下のディレクトリで指定する
        ssl_certificate "/var/www/your-domain.com/server.crt";
        ssl_certificate_key "/var/www/your-domain.com/server.key";
        # 以下のディテクティブはなくても動作するが、未調査のため各値がどう作用するか不明
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
            proxy_pass https://localhost:3000;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";

            # 非公開アプリケーションのため nginxでbasic認証を実装する
            # .htpasswdは任意の方法で生成する
            auth_basic "basic  authentication";
            auth_basic_user_file /etc/nginx/.htpasswd;
        }
    }

    ...

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

docker入門

windows10 homeでdocker環境を構築(chocolatery)

  1. chocolateryが使えるように設定
    ※1
    参考 : https://chocolatey.org/

  2. 以下コマンドを実行※1

cmd
 choco install docker ``` <br>``` choco install docker-machine 
  1. windows homeの場合そのまま使えないためvirtualboxをインストール
cmd
 choco install virtualbox 
  1. ホストがあるか確認
cmd
 docker-machine ls
  1. ホストがないなら作成する。
    例)docker-machine create -d virtualbox default

  2. docker-machine lsを実行しステータスがrunningになっていることを確認
    もしstopになっていたらvirtualboxの仮想マシンを起動できていない

  3. docker-machine.exe env --shell cmd default

  4. 以下のコマンドを実行(上記のコマンドを実行したときにこれ実行してください的なのが出てくるのでそれをコピペ)
    @FOR /f "tokens=*" %i IN ('"C:\ProgramData\chocolatey\lib\docker-machine\bin\docker-machine.exe" env --shell cmd default') DO @%i

  5. ipアドレスの確認 docker-machine ip

dockerコマンドを使ってみる

  1. コンテナの情報を確認
    docker ps -a

  2. イメージの確認
    docker images

  3. コンテナを立ち上げる (-i -tではなく-dにするとバックグラウンドで立ち上がる)
    docker run -i -t -p 8080:80 --name 識別するための好きな名前 イメージの名前

  4. コンテナの停止
    docker stop コンテナID又は--nameで指定した名前

  5. コンテナ再起動
    docker start コンテナID又は--nameで指定した名前

  6. コンテナをシェルで立ち上げる(docker start後)
    docker attach コンテナID又は--nameで指定した名前

  7. コンテナ削除
    docker rm コンテナID又は--nameで指定した名前

  8. イメージ削除
    docker rmi イメージID 例:docker pull amazonlinux

  9. プル
    docker pull プルしたいイメージ

  10. docker fileを使う

    - Dockerfileという名前でファイルを作成(拡張子なし)中身は以下のような感じ

    From amazonlinux

    RUN yum update -y

    RUN yum install httpd -y

    • Dockerfileという名前でファイルを作成(拡張子なし)
    • Dockerfileが置かれている場所で以下を実行するとnewawsってimageが作成される(newawsは好きな名前でok)
    • コンテナ作成
    • docker build -t newaws .
    • docker imagesでできたことを確認
    • イメージと同じように使える
    • docker run -it --privileged --name aws newaws

docker上でamazonlinuxを立ち上げapacheで接続

1.amazonlinuxのイメージをダウンロード
docker pull amazonlinux

2.仮想サーバーに接続
docker-machine ssh default

3.mkdir /sys/fs/cgroup/systemd
mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd

4.-vをつけることでサーバーとdockerのディレクトリをリンクさせる(docker-machineは Windows環境であれば、
C:\Users をVirtualBox共有フォルダとしてdockerホストの /c/Users に自動マウントしてくれます)
--privilegedと/sbin/initはsystemctlを有効にするためにつける
-pでdockerの80番ポートを仮想サーバーの8080ポートで使用するという意味
docker run -v /c/Users/yoy_n/docker:/var/www --privileged -d -p 8080:80 --name aws amazonlinux /sbin/init

もしdockerfileを使用するなら
docker build -t newaws .
docker run -v /var/www:/var/www --privileged -d -p 8080:80 --name aws newaws /sbin/init

5.docker exec -it aws /bin/bash

6.webルート確認
httpd -S -D SSL

7.var/www/htmlになっていたら以下実行
mkdir var/www/html

8.systemctl start httpd

9.systemctl status httpd

番外編

1.virtualboxとローカルPCのファイル共有

2.環境変数の設定
- PC->プロパティ->システムの詳細設定->環境変数->システム環境変数
- 変数名 VBoxManage
- 変数値 C:\Program Files\Oracle\VirtualBox

3.設定後cmd再起動
VirtualBox VMs/VM-Share

4.virtualboxでローカルPCの共有したいpathを指定
参考:https://pc-karuma.net/virtualbox-folder-share/

5.仮想環境(virtualbox)で下記コマンド実行(sample2はvirtualboxで指定した名前)
sudo mount -t vboxsf sample2 /var/www/html

※1 管理者権限でインストール必要

mysqlの設定

cmd
#mariadbがインストールされているか確認
$ yum list installed | grep mariadb
mariadb-libs.x86_64                   1:5.5.56-2.amzn2                 installed

#mysqlがインストールされているか確認
$ yum list installed | grep mysql

#mysqlがインストールできるか確認
$ yum info mysql
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
エラー: 表示するパッケージはありません

#mysql8.0リポジトリの追加(このリポジトリに5.7も含まれています)
$ sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm -y

#mysql8.0リポジトリの無効化
$ sudo yum-config-manager --disable mysql80-community

#mysql5.7リポジトリの有効化
$ sudo yum-config-manager --enable mysql57-community

#mysql5.7がインストールできるか確認
$ yum info mysql-community-server

#mysqlインストール
$ sudo yum install mysql-community-server -y
$ mysqld --version
mysqld  Ver 5.7.22 for Linux on x86_64 (MySQL Community Server (GPL))

#自動起動設定
$ sudo systemctl start mysqld.service
$ sudo systemctl enable mysqld.service
$ systemctl status mysqld.service
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

APIキーはハードコーディングせず.envファイルを活用しよう

対象の方

  • プログラミング初心者
  • .envを使用した事がない方

ハードコーディングって何?

ハードコーディングとは、本来プログラム中に記述すべきでないリソースを、直接ソースコード中に埋め込むことである。これらは本来、外部ソースから取得するか、実行時に生成するべきものであり、これをソフトコーディングという。
ウィキペディア

# このようなコードの事
api_key = "xxxxxxxxxxxx" 

実際プログラミング初めて間もない頃は環境変数の言葉すら知らず、この様に直書きしてました笑
今考えると、Githubにpublicで上げるのに論外ですよね…

ハードコーディングのここがダメ

  • 特定のkeyが存在する場合はそれに関連する情報がコードの漏洩と共に盗まれる可能性がある。
  • 複数箇所で使用する場合、毎回書くのは面倒く際
  • などなど…

結果.envファイルを作成して、変数として管理しよう!!

使い方

  1. 隠しファイル.envを作業ディレクトリに作成しよう。
  2. 変数名=値の形で宣言しよう api_key="xxxxxxxx" #変数名 = 実際の値

手順としてはこれだけで後はこの値を使用したい箇所で呼び出すだけ!
とっても簡単!!

こうする事で、apiキーだけでなくdockerで構築するdb情報を書いておけば

docker-compose.yml

USER : ${変数名}

の様に使用することが出来る。

また、node.jsなどで使用したい場合はdotenvを利用して.envを読み込み使用する事が出来る。

例
require('dotenv').config({path: ここに.envまでのパス})

process.env.変数名 #呼び出し

後書き

初めてQiitaに記事を書いてみました。
読みづらい箇所が所々あったとは思いますが読んで頂きありがとうございます。
また、間違えがあればご指摘頂けると幸いです

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