GitHubのProfileページにREADMEを追加した。

tl;dr

  • GitHubのProfileページに自分のREADMEを載せることが出来るようになった。

f:id:teitei_tk:20200801030736p:plain

いつからか分からないが、このようにGitHubのProfileページに自分のREADMEを載せることが出来るようになっている。 いくらか調べてみたが、どれも一次ソースが無いので何時から始まったからは分からなかった。

dev.to

やり方は簡単でGitHub上で、下記の手順で出来る。

  1. 自分のGitHubのアカウント名と同じ名前のRepositoryを作る
  2. RepositoryにREADME.mdを編集してpushする。

私の場合はteitei-tkというアカウント名なので、teitei-tkというrepositoryを作った。 github.com

他の人がどんなREADMEを書いているのか知りたい場合や、どんなツールがあるのかはawsome-github-profile-readmeというRepositoryによくまとまっているので、そこを見ると良い github.com

結構いろんなことが出来て、自分のGitHubのstatsを表示したり、GitHubアカウントで一番利用している言語を表示することが出来たりする。

f:id:teitei_tk:20200731220449p:plain f:id:teitei_tk:20200731221317p:plain

その他にもShields.ioとSimpleIconsを利用してカスタムBadgeをつけれたりもする shields.io simpleicons.org

これは試しに作ったRubyRailsのカスタムBadge

Ruby RubyOnRails

ソースコードはこんな感じ

![Ruby](https://img.shields.io/badge/-Ruby-CC342D?style=flat-square&logo=Ruby)
![RubyOnRails](https://img.shields.io/badge/-Ruby%20on%20Rails-CC0000?style=flat-square&logo=Ruby+on+Rails)

具体的にはこのように書く。

![](https://img.shields.io/badge/-(message)-(badgeの色。16進数でも可能)?style=(表示するstyle)&logo=(simpleIcons.orgにあるlogoの名前)&logoColor=(logoの色)

StatsとBadgeの詳しいことはQiitaに良いまとめ記事があるのでそこに譲る。

qiita.com

qiita.com

個人的な感想

LaprasやFindyのActivityLogやスキルまとめなどと相性が良さそうなので、Lapras社とFindy社はGitHub Profileに載せることが出来るBadgeを作って欲しい。

まとめ

  • 自分のGitHubアカウントのトップページにREADMEを載せることが出来るようになった。
  • GitHub上のStatsやBadgeを載せたりカスタマイズが出来る。

ref

dev.to

github.com

qiita.com

qiita.com

Next.jsの開発環境をDocker with Multi Stage Build

tl;dr

  • Multi Stage Buildを利用することで147MBほど減った。
  • 今回は開発環境のDocker化が目的。production環境ではSSG or SSRだと思うのでまた別の対応が必要になりそう。

Example Project

github.com

完成形

gist.github.com

Multi Stage Buildを利用しないケース

$ docker build -f Dockerfile_dev .
Sending build context to Docker daemon  139.6MB
Step 1/9 : FROM node:12.18.2-alpine as builder
 ---> 057fa4cc38c2
Step 2/9 : WORKDIR /app
 ---> Running in f53a1b123569
Removing intermediate container f53a1b123569
 ---> 485a44f0ebd3
Step 3/9 : COPY package.json .
 ---> 5b58fb396840
Step 4/9 : COPY yarn.lock .
 ---> 8fbd886ebe49
Step 5/9 : COPY tsconfig.json .
 ---> dd9ea9f86d64
Step 6/9 : RUN yarn install --production
 ---> Running in 997d0a1b080d
yarn install v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.13: The platform "linux" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@2.1.3: The platform "linux" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 39.21s.
Removing intermediate container 997d0a1b080d
 ---> df1be46b2ed3
Step 7/9 : COPY . .
 ---> d91d29256d71
Step 8/9 : EXPOSE 3000
 ---> Running in f6db73858185
Removing intermediate container f6db73858185
 ---> ef8b3ac6a59f
Step 9/9 : CMD [ "yarn", "dev" ]
 ---> Running in 003480d5135e
Removing intermediate container 003480d5135e
 ---> f9590e7cb54e
Successfully built f9590e7cb54e
$ docker image ls | grep f9590e7cb54e
<none>                             <none>              f9590e7cb54e        16 seconds ago      431MB

431MB

Multi Stage Buildを利用するケース

$ docker build -f Dockerfile_dev .
Sending build context to Docker daemon  139.6MB
Step 1/11 : FROM node:12.18.2-alpine as builder
 ---> 057fa4cc38c2
Step 2/11 : WORKDIR /app
 ---> Using cache
 ---> 485a44f0ebd3
Step 3/11 : COPY package.json .
 ---> Using cache
 ---> 5b58fb396840
Step 4/11 : COPY yarn.lock .
 ---> Using cache
 ---> 8fbd886ebe49
Step 5/11 : COPY tsconfig.json .
 ---> Using cache
 ---> dd9ea9f86d64
Step 6/11 : RUN yarn install --production
 ---> Using cache
 ---> df1be46b2ed3
Step 7/11 : FROM node:12.18.2-alpine
 ---> 057fa4cc38c2
Step 8/11 : COPY --from=builder /app/node_modules /app/node_modules
 ---> fd4d5616ed40
Step 9/11 : COPY . .
 ---> 8964cefa6942
Step 10/11 : EXPOSE 3000
 ---> Running in 16526606b919
Removing intermediate container 16526606b919
 ---> e5a03c34f700
Step 11/11 : CMD [ "yarn", "dev" ]
 ---> Running in a74809ecc5d4
Removing intermediate container a74809ecc5d4
 ---> 5ca7bf661d87
Successfully built 5ca7bf661d87
$ docker image ls | grep 5ca7bf661d87
<none>                             <none>              5ca7bf661d87        28 seconds ago      284MB

まとめ

  • Multi Stage Buildを利用することでイメージの容量がだいぶ減るので利用しない手はない。

ref

tech.plaid.co.jp docs.docker.com

Docker with GoのMulti Stage Buildで"no such file or directory"と出てハマった話

対象のDockerfile。特に特殊なことは行っていない素朴なDockerfile。

FROM golang:1.14.4 as builder

WORKDIR /app
COPY . .
RUN go mod download
RUN go build path/to/main.go

FROM alpine
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/path/to/main /app/main
EXPOSE 5000
ENTRYPOINT [ "/app/main" ]

build log

$ docker build .
Sending build context to Docker daemon  24.16MB
Step 1/10 : FROM golang:1.14.4 as builder
 ---> 00d970a31ef2
Step 2/10 : WORKDIR /app
 ---> Using cache
 ---> 290d933fcd92
Step 3/10 : COPY . .
 ---> 5c338d20e119
Step 4/10 : RUN go mod download
 ---> Running in fa40233a9ad4
Removing intermediate container fa40233a9ad4
 ---> 32ededdd590c
Step 5/10 : RUN go build cmd/app/main.go
 ---> Running in 715374ae5931
Removing intermediate container 715374ae5931
 ---> 0df4e6ac142b
Step 6/10 : FROM alpine
 ---> a24bb4013296
Step 7/10 : RUN apk add --no-cache ca-certificates
 ---> Using cache
 ---> 63a365fab492
Step 8/10 : COPY --from=builder /app/main /app/main
 ---> 262cef1fcd0f
Step 9/10 : EXPOSE 5000
 ---> Running in d2cc58f47b7f
Removing intermediate container d2cc58f47b7f
 ---> 49e6a57ba3bd
Step 10/10 : ENTRYPOINT [ "/app/main" ]
 ---> Running in 887cc0dbb3a8
Removing intermediate container 887cc0dbb3a8
 ---> d5c6b638a8a7
Successfully built d5c6b638a8a7

buildしたimageを実行すると exec user process caused "no such file or directory" と出て実行が出来ない。

$ docker run -it d5c6b638a8a7
standard_init_linux.go:211: exec user process caused "no such file or directory"

Docker公式のDocumentを眺めると CGO_ENABLED=0 という変数を指定している。

docs.docker.com

CGO_ENABLEについて公式のDocumentに書いてある。

golang.org

The cgo tool is enabled by default for native builds on systems where it is expected to work. It is disabled by default when cross-compiling. > You can control this by setting the CGO_ENABLED environment variable when running the go tool: set it to 1 to enable the use of cgo, and to > 0 to disable it. The go tool will set the build constraint "cgo" if cgo is enabled. The special import "C" implies the "cgo" build constraint, as > > though the file also said "// +build cgo". Therefore, if cgo is disabled, files that import "C" will not be built by the go tool. (For more about >build constraints see https://golang.org/pkg/go/build/#hdr-Build_Constraints).

今回のMulti Stage Buildのようなビルド環境と実行環境が違うクロスコンパイル時には CGO_ENABLE=0 にする必要があるとのこと。go envで見てみると案の定 CGO_ENABLE=1 となっている。

Step 6/11 : RUN go env
 ---> Running in f2d4bf833350
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/app/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build835780014=/tmp/go-build -gno-record-gcc-switches"

Dockerfileのbuild箇所に CGO_ENABLE=0 を指定することで正常にビルドが出来ました。

FROM golang:1.14.4 as builder

WORKDIR /app
COPY . .
RUN go mod download
RUN CGO_ENABLED=0 go build path/to/main.go
RUN go env

FROM alpine
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/path/to/main /app/main
EXPOSE 5000
ENTRYPOINT [ "/app/main" ]
$ docker build .
Sending build context to Docker daemon  24.16MB
Step 1/11 : FROM golang:1.14.4 as builder
 ---> 00d970a31ef2
Step 2/11 : WORKDIR /app
 ---> Using cache
 ---> 290d933fcd92
Step 3/11 : COPY . .
 ---> 1e985aa7595b
Step 4/11 : RUN go mod download
 ---> Running in 4f47920a2f07
Removing intermediate container 4f47920a2f07
 ---> b3af89cc0fae
Step 5/11 : RUN CGO_ENABLED=0 go build cmd/app/main.go
 ---> Running in 5418122649bb
Removing intermediate container 5418122649bb
 ---> a22ffab8bc7c
Step 6/11 : RUN go env
 ---> Running in f2d4bf833350
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/app/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build835780014=/tmp/go-build -gno-record-gcc-switches"
Removing intermediate container f2d4bf833350
 ---> 658a897f518b
Step 7/11 : FROM alpine
 ---> a24bb4013296
Step 8/11 : RUN apk add --no-cache ca-certificates
 ---> Using cache
 ---> 63a365fab492
Step 9/11 : COPY --from=builder /app/main /app/main
 ---> 4aea7dfd10cd
Step 10/11 : EXPOSE 5000
 ---> Running in 17d50b507678
Removing intermediate container 17d50b507678
 ---> e35b39616e48
Step 11/11 : ENTRYPOINT [ "/app/main" ]
 ---> Running in 2a03dd0d5636
Removing intermediate container 2a03dd0d5636
 ---> 7f1b74a479da
Successfully built 7f1b74a479da
$ docker run -it 7f1b74a479da

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.1.16
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on 127.0.0.1:5000

ref

qiita.com docs.docker.com golang.org github.com

ポートフォリオサイトをGatsby.jsからNext.jsに移行した。

PR

github.com

動機

Next.jsが今後伸びていくと踏んで今のうちに技術投資をしておきたいと思い移行をしました。
Next.jsにはstatic HTML exportという機能があり、Gatsby.jsと同じ様に静的サイトを作れるのでキャッチアップにちょうど良かったという事情もありました。

nextjs.org

Nuxt.jsに投資するかも悩みましたが、

  1. Vue.jsよりReact.jsに慣れている
  2. TypeScript Full Support

という点もあり、Next.jsにしました。

移行で困った点

PRを見てもらえればわかると思うのですが、1枚だけのページという事もあって困るような事に遭遇することすらありませんでした。
styled-componentを使っていると大変という話を聞きましたが、使っていなかったこともあり、特につまずくようなところは無かったです。逆につまずいて知見を得たかったので残念

所管

Reactで静的なサイトを作る場合はGatsby.js以外にもNext.jsがあるよというお話でした。Next.jsの知見を利用出来る&貯めることが出来るので、今後静的なサイトを作る場合はNext.jsでやろうと思います。

Next.jsでfaviconを設定する

PR

github.com

Projectの構成はこのような形

$ tree src/pages public
src/pages
├── _app.tsx
├── _document.tsx
└── index.tsx
public
└── static
    └── favicon
        ├── android-chrome-192x192.png
        ├── android-chrome-512x512.png
        ├── apple-touch-icon.png
        ├── browserconfig.xml
        ├── favicon-16x16.png
        ├── favicon-32x32.png
        ├── favicon.ico
        ├── mstile-150x150.png
        └── site.webmanifest

1. publicディレクトリし、画像を置く

project直下にpublicというディレクトリを作成してfaviconの画像ファイルを置いてください。 以前はstaticというディレクトリ名でしたが、非推奨になりました。

github.com

2. pages/_document.tsxを作成し、link tagを追加する

nextjs.org

import Document, { Head, Main, NextScript } from "next/document";

export default class MyDocument extends Document {
  render() {
    return (
      <html>
        <Head>
          <link
            rel="apple-touch-icon"
            sizes="180x180"
            href="static/favicon/apple-touch-icon.png"
          />
          <link
            rel="icon"
            type="image/png"
            sizes="32x32"
            href="static/favicon/favicon-32x32.png"
          />
          <link
            rel="icon"
            type="image/png"
            sizes="16x16"
            href="static/favicon/favicon-16x16.png"
          />
          <link rel="manifest" href="static/favion/site.webmanifest" />
          <meta name="msapplication-TileColor" content="#da532c" />
          <meta name="theme-color" content="#ffffff" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

3. build and exportして確認する

$ npm run build && npm run export