20220322のGoに関する記事は4件です。

Go + MySQL + React のDocker開発環境を作成する

はじめに GoとMySQLとReact(&TypeScript)を使ったポートフォリオ作成をしようと思い、最初に勉強も兼ねてDocker開発環境を作成しました。 そこでQiitaやZennなどで書かれている記事を参考にしていましたが、最終的に他の方とは違う構成になったので自分も記事を執筆しようと思いました。 作成したもの ディレクトリ構成 . ├── README.md ├── db │   ├── data │   └── my.cnf ├── docker-compose.yml ├── go-app │   ├── Dockerfile │   └── main.go ├── react-ts-app │   ├── .dockerignore │   ├── Dockerfile │   ├── README.md │   ├── node_modules │   ├── package-lock.json │   ├── package.json │   ├── public │   ├── src │   └── tsconfig.json └── variables.env Dockerfile(go-app) FROM golang:latest WORKDIR /app/go COPY ./ ./ ENTRYPOINT [ "go", "run", "main.go" ] Dockerfile(react-ts-app) FROM node:17.7.2 WORKDIR /app/react-ts COPY package*.json ./ RUN yarn install COPY . . ENTRYPOINT [ "npm", "start" ] dockerignoreファイル(react-ts-app) node_modules npm-debug.log yarn-error.log docker-compose.yml version: '3' services: react-ts: build: ./react-ts-app ports: - '3000:3000' tty: true stdin_open: true go: build: ./go-app ports: - '8000:8000' tty: true stdin_open: true db: image: mysql:8.0 volumes: - './db/data:/var/lib/mysql' - './db/my.cnf:/etc/mysql/conf.d/my.cnf' # MYSQL_ROOT_PASSWORDのみをenvファイルで設定 env_file: - variables.env ports: - '3306:3306' my.cnf [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci [client] default-character-set=utf8mb4 解説 Dockerfileは、docker-composeを使わなくても単体で動作することが可能だよねっていう状態を意識しました。 また、docker-composeはあくまでコンテナを立ち上げるのを楽にするためのものだと意識しました。 Dockerfile ENTRYPOINTを指定していることで、docker-composeをupした瞬間にdb・go・react-tsの3つのコンテナが起動&サーバーも起動するようになっています。 COPY句によってDockerfile自体もイメージ内にコピーされてしまいますが、イメージサイズへの影響が小さい・dockerignoreファイルを作成してもビルドにかかる時間は変わらないと判断し、許容しています。 dockerignoreファイルによるビルド時間への影響は下記のサイトが参考になります。 dockerignore(React用) node_modules、npm-debug.log、yarn-error.log の3つを指定しています。 これによってローカルモジュール・デバッグログ・エラーログがDockerイメージにコピーされないようにします。 node_modulesはパッケージがインストールされるディレクトリです。必要なパッケージはソースコードによって異なるため、node_modulesをイメージ内にコピーする必要はないと言えます。 また、node_modules内に多くのパッケージをインストールしている場合、イメージをビルドするときに多くの時間を要します。そのため、node_modules は dockerignoreファイルに登録することが基本となっています。 node_modules のコピーはしませんがコンテナ内でもパッケージは必要になります。ReactのDockerfileでは package.json と package-lock.json をコピーし、yarn install を行うことで、コンテナ使用者が必要なパッケージのみをインストールするようにしています。 Go FROM でイメージを取得するときに、golangにするか、ubuntuのようなOSイメージにするか、golang:<version>-alpineにするかで迷いました。 この中で一番設定ミスが起こりづらそうだと感じたgolangにしました。 dockerの知識量的にOSイメージからGoの環境を整えるのはハードルが高そう。また、alpineはGo projectに公式サポートされていないとDockerhubに書いてあるといった理由で、この2つは選択肢から外しました。 ENTRYPOINT によって、コンテナが立ち上がるとともに go run main.go でサーバーも立ち上がるようにしています。 以下、main.goのコードです。 main.go package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/", echoHello) http.ListenAndServe(":8000", nil) } func echoHello(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "<h1>Hello World</h1>") } React nodeイメージのDockerfileを見ると、デフォルトでyarnが入っていることがわかります。 なので、yarnをわざわざインストールする必要はありません。 また、Dockerfileやcomposeにcreat-react-appの記述もされている方がいますが、コンテナを起動するたびに新規のプロジェクト作成するのは時間がかかりそうだと感じたので僕は書きませんでした。 あくまでソースコードはホスト上にあり、コンテナへそれらをコピーすることで正常に動くようにしたいと思いました。 次に最も重要な部分ですが、ReactのDockerfileではビルド時間の短縮のためにCOPY句を2つ使っています。 COPY package*.json ./ RUN yarn install COPY . . dockerにはレイヤー構造とキャッシュという概念があり、これを活用することでイメージのビルド時間を短縮できます。 レイヤーとキャッシュについては解説すると長くなるので、ここでは割愛させていただきます。 Reactの開発では頻繁にソースコードを変えると思います。 もし yarn install の前に COPY . . を行うと、ソースコードが変更されるたびにパッケージをインストールし直すことになります。 パッケージを追加・変更していなくても毎回この処理が行われ、多くの時間が費やされてしまいます。 COPY package*.json ./ と yarn install を先に行なっていればレイヤーキャッシュが使用され、ビルドの時間を大幅に節約できます。 以上の理由から、COPYを2回使うようにしました。 この記述方法は、こちらのサイトを参考にしました。 MySQL MYSQL_ROOT_PASSWORDを設定しなければエラーが出ます。 共有をしないのであればcompose上に直接設定してもいいですが、僕はgithubを通じて共有しようと考えていたのでenvファイルを使いました。 MySQLはローカルホスト上ではmysql.server startを使って起動する必要があるかと思いますが、このコンテナ上ではそれが必要ありません。コンテナが立ち上がるとともにDBサーバーも立ち上がります。 my.cnfファイルを用意していありますが、ここでは文字化けを防ぐための設定しかしていません。 もしかしたら他にももっと設定した方がいいものもあるかもしれませんが、沼にハマりそうなのでやめました。 最後に 人によって書き方が違って正しい情報を入手しづらく、結構時間がかかってしまいました。 もちろん僕が書いたものも正しいとは言い切れないので、これから更に知識をアップデートしていきたいなと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Golang GitHubトレンドデイリーランキング!!【自動更新】

GitHub Trending をキャッチアップする習慣をつけて、強強エンジニアになろう。 この記事では、Golang のGithubのトレンドデイリーランキングを25位まで紹介します。 トレンドデイリーランキング 【1 位】 Dreamacro/clash ? 25,075 star A rule-based tunnel in Go. 【2 位】 trustwallet/assets ? 2,417 star A comprehensive, up-to-date collection of information about several thousands (!) of crypto tokens. 【3 位】 Mrs4s/go-cqhttp ? 4,213 star cqhttp的golang实现,轻量、原生跨平台. 【4 位】 TheAlgorithms/Go ? 9,271 star Algorithms implemented in Go for beginners, following best practices. 【5 位】 sundowndev/phoneinfoga ? 6,466 star Information gathering & OSINT framework for phone numbers 【6 位】 gohugoio/hugo ? 57,785 star The world’s fastest framework for building websites. 【7 位】 coocood/freecache ? 3,890 star A cache library for Go with zero GC overhead. 【8 位】 junegunn/fzf ? 42,921 star ? A command-line fuzzy finder 【9 位】 JanDeDobbeleer/oh-my-posh ? 4,836 star A prompt theme engine for any shell. 【10 位】 osrg/gobgp ? 2,678 star BGP implemented in the Go Programming Language 【11 位】 takshal/freq ? 68 star This is go CLI tool for send fast Multiple get HTTP request. 【12 位】 mikeroyal/Open-Source-Security-Guide ? 154 star Open Source Security Guide 【13 位】 Arriven/db1000n ? 700 star 【14 位】 cloudreve/Cloudreve ? 13,468 star ?支持多家云存储的云盘系统 (Self-hosted file management and sharing system, supports multiple storage providers) 【15 位】 rclone/rclone ? 31,903 star "rsync for cloud storage" - Google Drive, S3, Dropbox, Backblaze B2, One Drive, Swift, Hubic, Wasabi, Google Cloud Storage, Yandex Files 【16 位】 AdguardTeam/AdGuardHome ? 10,854 star Network-wide ads & trackers blocking DNS server 【17 位】 kgretzky/evilginx2 ? 5,219 star Standalone man-in-the-middle attack framework used for phishing login credentials along with session cookies, allowing for the bypass of 2-factor authentication 【18 位】 tendermint/starport ? 673 star Starport is the all-in-one platform to build, launch and maintain any crypto application on a sovereign and secured blockchain 【19 位】 ethereum/go-ethereum ? 36,198 star Official Go implementation of the Ethereum protocol 【20 位】 go-rod/rod ? 2,221 star A Devtools driver for web automation and scraping 【21 位】 Mikaelemmmm/go-zero-looklook ? 933 star ?基于go-zero(go zero) 微服务全技术栈开发最佳实践项目。Develop best practice projects based on the full technology stack of go zero (go zero) microservices. 【22 位】 bnb-chain/bsc ? 1,417 star A Binance Smart Chain client based on the go-ethereum fork 【23 位】 docker/compose ? 25,284 star Define and run multi-container applications with Docker 【24 位】 fatedier/frp ? 54,294 star A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet. 【25 位】 V4NSH4J/discord-mass-DM-GO ? 803 star The most popular Discord selfbot written in GO allowing users to automate their campaigns and launch large low-cost marketing campaigns targetting Discord users! 最後に 最後まで見ていただきありがとうございました。 LGTMをもらえるととても励みになりますので、ぜひお願いします
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GoでGitHubへpushする前にmakeコマンドでprecommitする方法

はじめに こちらはzennの記事の転載となります。 平下CTO@sweeepです。Go言語でGitHubなどへpushする前にmakeコマンドでprecommitをする方法をこちらをサンプルに解説します。→ GoでファイルのValidation方法など 本記事の内容です。 precommitの内容 makeコマンドでprecommit一括実行 実行結果 PR時のprecommit checkリスト precommitの内容 precommit時のそれぞれの整形/linter/チェックについて以下記します。 goimports: Go言語の標準パッケージでパッケージのインポートを整形し、また、gofmtのルールでコードを整形します。 $ find . -print | grep --regex '.*\.go' | xargs goimports -w -local "github.com/hirac1220/go-file/utils" fmt: Go言語の標準パッケージでコードを整形します。 $ go fmt ./... vet: Go言語標準パッケージで静的解析します。 $ go vet ./... errcheck: エラーハンドリングされていないエラーをチェックします。 $ errcheck staticcheck: こちらもGo言語を静的解析します。 $ staticcheck ./... gosec: ソースコードをスキャンして、セキュリティの問題についてチェックします。 $ gosec ./... golangci-lint: Go言語の多くのlinterを搭載しています。こちらで他のlinterまかなうことも。 $ golangci-lint run ./... それぞれインストール それぞれのパッケージのインストールコマンドです。必要に応じてインストール実施してください。 $ go install golang.org/x/tools/cmd/goimports@latest $ go install github.com/kisielk/errcheck@latest $ go install honnef.co/go/tools/cmd/staticcheck@latest $ brew install golangci-lint $ brew upgrade golangci-lint $ curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOPATH)/bin latest makeコマンドにしてあるので、一括インストールも可能です。 $ cd utils/file $ make install makeコマンドでprecommit一括実行 GitHubへpushする前にmakeコマンドで下記precommitを一括実施します。hookして自動でprecommitをかけることも可能ですが、Draft PRなどでとりあえずのpushしたいこともあり、マニュアル運用としています(自動化はGitHub側のreviewdogなど導入予定)。 以下がMakefileの定義となります。 utils/file/Makefile # precommit check precommit: goimports fmt errcheck staticcheck gosec goimports: find . -print | grep --regex '.*\.go' | xargs goimports -w -local "github.com/hirac1220/go-file/utils" fmt: go fmt ./... vet: go vet ./... errcheck: errcheck staticcheck: staticcheck ./... golangci: golangci-lint run ./... gosec: gosec ./... precommit実行結果 以下makeコマンドで実行します。 $ cd utils/file $ make precommit precommit実行結果は以下のようになります。 $ make precommit find . -print | grep --regex '.*\.go' | xargs goimports -w -local "github.com/hirac1220/go-file/utils" go fmt ./... errcheck staticcheck ./... gosec ./... [gosec] 2022/03/21 18:32:15 Including rules: default [gosec] 2022/03/21 18:32:15 Excluding rules: default [gosec] 2022/03/21 18:32:15 Import directory: /Users/kimi/go/src/github.com/hirac1220/go/go-file-validate/utils/file [gosec] 2022/03/21 18:32:16 Checking package: file [gosec] 2022/03/21 18:32:16 Checking file: /Users/kimi/go/src/github.com/hirac1220/go/go-file-validate/utils/file/file.go Results: Summary: Gosec : 2.9.3 Files : 1 Lines : 66 Nosec : 0 Issues : 0 PR時のprecommit checkリスト プルリクエストテンプレートをリポジトリのルートディレクトリで作成し、PR時にprecommit実施したかチェックするようにします。 添付のように、リポジトリのcreate new fileで.github/pull_request_template.mdを作成し、以下を記入します。 ### レビュー前チェック - [ ] make precommit PR実施すると添付のようにprecommitチェックリストが表示されます。 まとめ 今回はGo言語でのGitHubなどへpushする前にmakeコマンドでprecommitをする方法を解説しました。今後はprecommitと同等の設定をしたreviewdogなど導入し、precommitせずにPRすると自動でコメントしてもらうようにしていきたいです。 今回使用したサンプルはこちらのGitHubレポジトリにあります。 弊社ではフロントエンド・バックエンド・CoreAI機能開発のエンジニアを積極的に採用しています。ご興味のある方は下記リンクよりご応募お待ちしております! または、まずはカジュアルにお話してみたい、という方は下記リンクよりお申し込みください!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Distro for OpenTelemetryのCollectorとGo SDK on Traces Instrumentation

AWS Distro for OpenTelemetry OpenTelemetryは、オープンソースのプロジェクトで、 アプリケーション監視用の分散トレースとメトリックを収集するために、 ライブラリ・API・エージェントが提供されています。 AWS Distro for OpenTelemetryはOpenTelemetryをAWSで使うためのディストリビューションです。 OpenTelemetry自体については、freeCodeCamp.orgの動画が参考になるかと思います。 AWS Distro for OpenTelemetry Collector OpenTelemetry Collectorについてはこちらが参考になります。 こちらのdocker版サンプルを実施します。 以下のソースコードをcheckoutし、exampleフォルダへ移動します。 % git clone https://github.com/aws-observability/aws-otel-collector.git % cd aws-otel-collector/examples/docker/ 以下コマンドで実行します。 % docker-compose up すると、X-Rayでトレースが確認できます。 OpenTelemetry Go SDK on Traces Instrumentation 以下を参考に実施します。 Global Tracerの設定 以下のサンプルアプリを使います。 OpenTelemetry Protocol (OTLP) Exporterの作成 OpenTelemetry Goではバックエンドにトレースを送信する場合には、Exporterが必要になるようです。 ここではADOT Collectorへ送信するため、以下のようにExporterを作成します。 sampleapp/main.go // Create and start new OTLP trace exporter traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithEndpoint("0.0.0.0:4317"), otlptracegrpc.WithDialOption(grpc.WithBlock())) if err != nil { log.Fatalf("%s: %v", "failed to create new OTLP trace exporter", err) } Tracer Providerの作成 Traceの生成用に、Tracer Providerを作成します。 上記で作成したExporterと、ID generatorを設定します。 sampleapp/main.go idg := xray.NewIDGenerator() tp := trace.NewTracerProvider( trace.WithSampler(trace.AlwaysSample()), trace.WithBatcher(traceExporter) trace.WithIDGenerator(idg), ) アプリケーションの実装 エンドポイントが2つ用意されています。 /aws-sdk-callと sampleapp/main.go r.HandleFunc("/aws-sdk-call", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") ctx := r.Context() xrayTraceID := getXrayTraceID(trace.SpanFromContext(ctx)) json := simplejson.New() json.Set("traceId", xrayTraceID) payload, _ := json.MarshalJSON() _, _ = w.Write(payload) })) /outgoing-http-call こちらはhttpリクエストのタイミングと、その後のカスタム計装の2箇所でspanが作成されています。 sampleapp/main.go r.HandleFunc("/outgoing-http-call", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") client := http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)} ctx := r.Context() xrayTraceID, _ := func(ctx context.Context) (string, error) { req, _ := http.NewRequestWithContext(ctx, "GET", "https://aws.amazon.com", nil) res, err := client.Do(req) if err != nil { handleErr(err, "HTTP call to aws.amazon.com failed") } _, _ = ioutil.ReadAll(res.Body) _ = res.Body.Close() return getXrayTraceID(trace.SpanFromContext(ctx)), err }(ctx) ctx, span := tracer.Start( ctx, "CollectorExporter-Example", trace.WithAttributes(commonLabels...)) defer span.End() json := simplejson.New() json.Set("traceId", xrayTraceID) payload, _ := json.MarshalJSON() _, _ = w.Write(payload) })) 以下のコマンドで実行します。 % go build -o sampleapp % ./sampleapp Aws-OTel-Collectorインスタンスの実行 先ほどのdocker版サンプルのシングルインスタンス版を使用します。 AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYを環境変数に設定した上で、以下を実行します。 % cd aws-otel-collector/examples/docker/ % docker run --rm -p 4317:4317 -p 55680:55680 -p 8889:8888 \ -e "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" \ -e "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" \ -e AWS_REGION=us-west-2 \ -v "${PWD}/examples/docker/config-test.yaml":/otel-local-config.yaml \ --name awscollector public.ecr.aws/aws-observability/aws-otel-collector:latest \ --config otel-local-config.yaml; この状態で、localhost:8080/aws-sdk-callにアクセスすると、X-Rayで以下トレースが確認できます。 また、localhost:8080/outgoing-http-callにアクセスすると同じく以下が確認できます。 CollectorExporter-Exampleの方のメタデータは以下になっていました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む