高木のブログ

stfuawsc

Tags: メモ

Shut the fxxk up and write some code 🔗

うだうだ言ってないでコードを書け

【Sinatra】ページ単位で Basic 認証を入れる

Tags: Sinatra

Sinatra で Basic 認証を実装したい時は以下のような書き方で実現できる

use Rack::Auth::Basic do |username, password|
  username == 'admin' && password == 'secret'
end

しかし、アプリケーション全体に認証が掛かってしまう

ページ単位で Basic 認証 🔗

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'sinatra'
  gem 'puma'
end

helpers do
  def protected!
    return if authorized?

    halt(401, 'Unauthorized.')
  end

  def authorized?
    @auth ||= Rack::Auth::Basic::Request.new(request.env)

    return unless @auth.provided? && @auth.basic? && @auth.credentials

    @auth.credentials == ['takagi', 'thisispassword']
  end
end

get '/' do
  'Hello!'
end

get '/auth' do
  protected!

  'Authorized.'
end

Sinatra::Application.run!
$ curl localhost:4567
Hello!
$ curl localhost:4567/auth
Unauthorized.
$ curl --user takagi:thisispassword localhost:4567/auth
Authorized.

【Rails / Sinatra】ID を UUID にする

Tags: Rails Sinatra

実際は Sinatra アプリでやった話だけど、Rails でもほとんど一緒だからタイトルに Rails を入れてる

ユーザーの ID を UUID にした時のメモ(デフォルトでは BigInt になっている)

手順 🔗

マイグレーションファイル 🔗

class CreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users, id: false do |t|
      t.string :id, null: false, primary_key: true
      t.string :name, null: false

      t.timestamps
    end
  end
end

モデル 🔗

class User < ActiveRecord::Base
  before_create -> { self.id = SecureRandom.uuid }
end

本来であれば被らない UUID が生成されるまでループした方が良さげだけど、被る確立は低そうなので端折った

参考 🔗

[Rails]idにuuid(乱数)

【Sinatra】GraphQL 用の最低限の CORS の設定

Tags: Sinatra CORS

Sinatra アプリに生やした GraphQL のエンドポイントに、フロント(React)からアクセスできるように CORS の設定をした

CORS 用の Gem を使わないやり方で、1番シンプルな書き方になってると思う

 require 'sinatra/base'
 
 class App < Sinatra::Application
+  before do
+    response.headers['Access-Control-Allow-Origin'] = '*'
+    response.headers['Access-Control-Allow-Methods'] = 'POST'
+    response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
+
+    halt(200) if request.request_method == 'OPTIONS'
+  end
 
   post '/graphql' do
     result = AppSchema.execute(
       params[:query],
       variables: params[:variables],
       context: { current_user: nil }
     )
     json result
   end
 
   use Rack::JSONBodyParser
 end

response.headers['Access-Control-Allow-Origin'] は厳密にやるならちゃんと指定した方がいいと思う

【Hono】Basic 認証で認証失敗時のレスポンスをカスタムする方法

Tags: Hono

Hono で Basic 認証を実装したい時、ミドルウェアを使えばサクッと実現できる

import { Hono } from 'hono'
import { basicAuth } from 'hono/basic-auth'

const app = new Hono()

const username = 'hono'
const password = 'acoolproject'

app.use('/auth/*', basicAuth({ username, password }))

app.get('/auth', (c) => c.json({ message: 'Authorized.' }))

export default app
$ curl --user hono:acoolproject localhost:8787/auth
{"message":"Authorized."}

しかし、認証に失敗した時のレスポンスが固定で「Unauthorized」なっている

$ curl --user hono:foooooo localhost:8787/auth
Unauthorized

https://github.com/honojs/hono/blob/8879f241e895ab5229baa40d12144817ca1aa3d3/src/middleware/basic-auth/index.ts#L58
ソースを見たけど、ベタ書きになっていて指定できそうにもなかったので、Issue に質問を投げてみた

ステータスコード 401 をキャッチするカスタムミドルウェアを書いたら実現できるよとすぐに返答が

app.use('/auth/*', async (c, next) => {
  await next()
  if (c.res.status === 401) {
    return c.json({ message: 'Unauthorized.' }, 401)
  }
})
$ curl --user hono:foooooo localhost:8787/auth
{"message":"Unauthorized."}

これで成功時も失敗時も同じ JSON 形式のレスポンスに統一することができる

「While executing gem ... (Gem::RemoteFetcher::FetchError) bad response Forbidden 403 (https://api.rubygems.org/quick/Marshal.4.8/nokogiri-1.13.8-x64-unknown.gemspec.rz)」の対応

Tags: Ruby Gem

問題 🔗

Ruby 2.5.7 の環境でとある Gem をインストールしようとしたらエラーになった

$ ruby -v
ruby 2.5.7p206 (2019-10-01 revision 67816) [x86_64-linux]
$ gem install solargraph
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    bad response Forbidden 403 (https://api.rubygems.org/quick/Marshal.4.8/nokogiri-1.13.8-x64-unknown.gemspec.rz)

解決方法 🔗

RubyGems をアップデートして解決した

$ gem update --system
$ gem --version
3.3.19

問題が起きていたバージョンは確認し忘れ

参考 🔗

【Hono】POST リクエストで JSON データを受け取る

Cloudflare Workers 向けフレームワーク、Hono を触っていて、POST リクエストで JSON データを受け取るところで詰まったのでメモ

cURL で以下のように JSON データを送った時、c.req.parseBody() で受け取ることができる

$ curl -X POST localhost:8787 -H 'Content-Type: application/json' -d '{"id":"takagi","password":"thisispassword"}'
import { Hono } from 'hono'

const app = new Hono()

app.post('/', async (c) => {
  const { id, password } = await c.req.parseBody()

  console.log({ id, password })
  // { id: 'takagi', password: 'thisispassword' }

  return c.text('Hello, Hono!')
})

export default app

上のやり方はドキュメントにも書いてあるやり方で

Content-Type を指定しない場合 🔗

$ curl -X POST localhost:8787 -d '{"id":"takagi","password":"thisispassword"}'

Content-Type を指定しないと
{ id: undefined, password: undefined } になってしまった

c.req.parseBody() の結果を確認してみると、丸ごとキーに格納されていた

app.post('/', async (c) => {
  const body = await c.req.parseBody()

  console.log(body)
  // { '{"id":"takagi","password":"thisispassword"}': '' }

  return c.text('Hello, Hono!')
})

c.req.json() で受け取ることができる

【Ruby】Timers を使って定期実行する

Tags: Ruby

スクリプト内でとある処理を一定の間隔で繰り返し実行したい時、すぐ思いつくのは loop と sleep を使う方法

しかし、これだと処理の実行時間分ズレが発生する

loop do
  puts Time.now

  # 少し時間が掛かる処理
  [*1..5000000].map(&:to_s).count

  sleep 60
end
$ ruby sleep.rb
2022-07-25 22:12:22 +0900
2022-07-25 22:13:26 +0900
2022-07-25 22:14:28 +0900
2022-07-25 22:15:29 +0900
2022-07-25 22:16:31 +0900
2022-07-25 22:17:33 +0900
2022-07-25 22:18:35 +0900
2022-07-25 22:19:36 +0900
2022-07-25 22:20:38 +0900
2022-07-25 22:21:40 +0900

どうにかならないかと探してみたら、それを解決する timers という Gem を見つけた

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'timers'
end

timers = Timers::Group.new

timers.every(60) do
  puts Time.now

  # 少し時間が掛かる処理
  [*1..5000000].map(&:to_s).count
end

loop { timers.wait }
$ ruby timers.rb
2022-07-25 22:13:20 +0900
2022-07-25 22:14:20 +0900
2022-07-25 22:15:20 +0900
2022-07-25 22:16:20 +0900
2022-07-25 22:17:20 +0900
2022-07-25 22:18:20 +0900
2022-07-25 22:19:20 +0900
2022-07-25 22:20:20 +0900
2022-07-25 22:21:20 +0900
2022-07-25 22:22:20 +0900

しっかり60秒ごと実行されている

SwitchBot のスマートロックを API で操作する

Tags: SwitchBot API IoT

SwitchBotのスマートロック を買ったので、APIから操作をサクッと試してみた記録

手順 🔗

ドキュメント: SwitchBotAPI/README.md at main · OpenWonderLabs/SwitchBotAPI

APIキーは公式アプリから取得できる。(「SwitchBotのスマート加湿器をAPIで操作する 」に書いた)

デバイスを探す(スマートロックのdevice IDを取得) 🔗

$ curl -s -X GET -H 'Authorization: token' https://api.switch-bot.com/v1.0/devices | jq '.body.deviceList[] | select(.deviceType == "Smart Lock")'
{
  "deviceId": "EX0DEVICE0ID",
  "deviceName": "ロック A8",
  "deviceType": "Smart Lock",
  "enableCloudService": true,
  "hubDeviceId": "EX0HUB0DEVICE"
}

たくさんデバイスが出てくるので、deviceTypeで絞り込みをする

enableCloudServiceがfalseになっている場合、アプリからクラウドサービスを有効にしておく

ステータスを確認する 🔗

$ curl -s -X GET -H 'Authorization: token' https://api.switch-bot.com/v1.0/devices/EX0DEVICE0ID/status | jq
{
  "statusCode": 100,
  "body": {
    "deviceId": "EX0DEVICE0ID",
    "deviceType": "Smart Lock",
    "hubDeviceId": "EX0HUB0DEVICE",
    "lockState": "locked",
    "doorState": "closed",
    "calibrate": true
  },
  "message": "success"
}

解錠・施錠する 🔗

セキュリティの都合か何かでドキュメントに書いてなかったけど、それっぽいコマンドを叩いたらできた(やる時は自己責任で)

解錠 🔗

$ curl -s -X POST -H 'Authorization: token' https://api.switch-bot.com/v1.0/devices/EX0DEVICE0ID/commands -H 'Content-Type: application/json' -d '{"command": "unlock","parameter": "default","commandType": "command"}' | jq
{
  "statusCode": 100,
  "body": {},
  "message": "success"
}

施錠 🔗

$ curl -s -X POST -H 'Authorization: token' https://api.switch-bot.com/v1.0/devices/EX0DEVICE0ID/commands -H 'Content-Type: application/json' -d '{"command": "lock","parameter": "default","commandType": "command"}' | jq
{
  "statusCode": 100,
  "body": {},
  "message": "success"
}

Mac に ghq を導入する

Mac に ghq を入れた時のメモ書き

ghq handbook にいろいろわかりやすく書いてある

インストール 🔗

$ brew install ghq
$ ghq -v
ghq version 1.3.0 (rev:ccbbc18)

リポジトリ取得ディレクトリの設定 🔗

デフォルトでは $HOME/ghq になっている

$ ghq root
/Users/ytkg/ghq

自分は普段 $HOME/Workspace を作業用ディレクトリにしているのでそこに変更した

$ git config --global ghq.root '~/Workspace'

反映されていることを確認

$ ghq root
/Users/ytkg/Workspace

~/.gitconfig に設定が追記される

[ghq]
  root = ~/Workspace

SSH を用いてリポジトリを取得する設定 🔗

デフォルトでは https でリポジトリを取得するらしい
SSH で取得したいので変更

これは ghq の設定ではなく、git の設定になる

git config --global [email protected]:.insteadOf https://github.com/

~/.gitconfig に設定が追記される

[url "[email protected]:"]
  insteadOf = https://github.com/

リポジトリを取得 🔗

$ ghq get ytkg/takagi_blog
$ tree ~/Workspace -L 3
/Users/ytkg/Workspace
└── github.com
    └── ytkg
        └── takagi_blog

リポジトリ一覧 🔗

$ ghq list
github.com/ytkg/jmo
github.com/ytkg/kusa
github.com/ytkg/resque
github.com/ytkg/switchbot
github.com/ytkg/takagi-dev
github.com/ytkg/takagi_blog
github.com/ytkg/toggl_to_pixela
github.com/ytkg/tools

peco と組み合わせて瞬時に移動する 🔗

$ cd "$(ghq list --full-path | peco)"
QUERY>                                            IgnoreCase [8 (1/1)]
/Users/ytkg/Workspace/github.com/ytkg/jmo
/Users/ytkg/Workspace/github.com/ytkg/kusa
/Users/ytkg/Workspace/github.com/ytkg/resque
/Users/ytkg/Workspace/github.com/ytkg/switchbot
/Users/ytkg/Workspace/github.com/ytkg/takagi-dev
/Users/ytkg/Workspace/github.com/ytkg/takagi_blog
/Users/ytkg/Workspace/github.com/ytkg/toggl_to_pixela
/Users/ytkg/Workspace/github.com/ytkg/tools

sw と入力すると、switchbot のリポジトリだけに絞り込み、エンターキーで移動できる

引数ありの「curl ~~ | bash」を実行する

サブタイトル「【Bun】特定のバージョンを指定してインストールする」

Bun は、以下のコマンドでインストールすることができる

$ curl https://bun.sh/install | bash
$ bun -v
0.1.4

現時点で最新版の 0.1.4 が入った

動作確認で違うバージョンを入れたかったので、インストールスクリプトを確認すると引数でバージョンの指定ができることがわかった

if [ $# -eq 0 ]; then
    bun_uri="$github_repo/releases/latest/download/bun-${target}.zip"
else
    bun_uri="$github_repo/releases/download/${1}/bun-${target}.zip"
fi

引数は、-s で付与できるらしい

$ curl https://bun.sh/install | bash -s bun-v0.1.1
$ bun -v
0.1.1

0.1.1 をインストールすることに成功

参考 🔗

curlで取得したスクリプトに引数 - Mazn.net

GitHub GraphQL API でコントリビューション数(草の情報)を取得する

GitHub のコントリビューション数(草の情報)を使ってやりたいことができたので、GitHub GraphQL API を使って取得してみる

手順 🔗

アクセストークンの発行 🔗

GitHub の Settings -> Developer setting -> Personal access tokens から発行する

コントリビューション数だけ取れたらいいので、権限は user -> read:user だけ付与した

動作確認 🔗

発行したトークンがちゃんと使えるかの確認

公式では、GraphQL Explorer を使うことをおすすめされているが、今回は cURL を使った

エンドポイント https://api.github.com/graphql に対して POST リクエストで、クエリを投げる

query {
  viewer {
    login
  }
}
$ curl -s -H "Authorization: bearer [token]" https://api.github.com/graphql -d '{"query": "query { viewer { login } }"}' | jq
{
  "data": {
    "viewer": {
      "login": "ytkg"
    }
  }
}

自分の GitHub のユーザー名が返ってきたらOK

コントリビューション数の取得 🔗

認証も無事通過できたので、本題のコントリビューション数を取得する

以下のクエリでコントリビューション数が取得できる

query {
  user(login: "ユーザー名") {
    contributionsCollection {
      contributionCalendar {
        weeks {
          contributionDays {
            date
            contributionCount
          }
        }
      }
    }
  }
}

クエリが長いので、ファイルに書き込んでからリクエストする

【Resque】「Pipelining commands on a Redis instance is deprecated and will be removed in Redis 5.0.0.」の警告を非表示にする

Rails アプリで Resque を使っている
エンキューをしたら以下の警告が出るようになった

Pipelining commands on a Redis instance is deprecated and will be removed in Redis 5.0.0.

redis.pipelined do
  redis.get("key")
end

should be replaced by

redis.pipelined do |pipeline|
  pipeline.get("key")
end

(called from /usr/local/bundle/gems/redis-namespace-1.8.2/lib/redis/namespace.rb:530:in `namespaced_block'}

どうやら、pipelined の書き方が変わったらしい
Resque が内部で使っている Redis の Gem の話なので、特に対応は必要なかった
まだリリースされていないが、「Update Redis#pipelined for redis-rb 4.6. #1806 」で修正されている

とはいえ、デバッグの邪魔になるので警告を一時的に非表示にした

+Redis.silence_deprecations = true

参考 🔗

hawksnowlog: Ruby Resque 超入門 (Rails なし)

フォームオブジェクトを導入した時に参考にした本、サイト、リポジトリ

【zx】実行するコマンドを非表示にする

Tags: zx

スクリプト内で実行するコマンドが表示されてしまうので非表示にしたい

#!/usr/bin/env zx

const date = await $`date`
console.log(`Current date is ${date}`)
$ zx script.mjs
$ date
2022年 6月30日 木曜日 23時29分22秒 JST
Current date is 2022年 6月30日 木曜日 23時29分22秒 JST

非表示にする方法 🔗

やり方は2つある

引数に –quiet を付けて実行する 🔗

$ zx script.mjs --quiet
Current date is 2022年 6月30日 木曜日 23時30分47秒 JST

verbose を false にする 🔗

デフォルトは true

#!/usr/bin/env zx

$.verbose = false

const date = await $`date`
console.log(`Current date is ${date}`)
$ zx script.mjs
Current date is 2022年 6月30日 木曜日 23時31分20秒 JST

参考 🔗

https://github.com/google/zx#verbose

【Ruby】2.7 から追加された Enumerable#filter_map メソッドが便利

Tags: Ruby

業務でも Ruby 3.1 を使うようになって今更感あるけど、2.7 から追加された Enumerable#filter_map が便利だったので紹介

名前からわかるように、Enumerable#filterEnumerable#map を合体させたメソッド
ちなみに Enumerable#filterEnumerable#select のエイリアス

使用例 🔗

「1から10まで数字の配列から、偶数のみを2倍にした数字の配列を返す」は以下のように書ける

(1..10).filter_map { |n| n * 2 if n.even? }
=> [4, 8, 12, 16, 20]

今までのやり方 🔗

パッと思いつくのは以下の3つ

select + map 🔗

(1..10).select(&:even?).map { |n| n * 2 }
=> [4, 8, 12, 16, 20]

map + compact 🔗

(1..10).map { |n| n * 2 if n.even? }.compact
=> [4, 8, 12, 16, 20]

each_with_object 🔗

(1..10).each_with_object([]) { |n, arr| arr.push(n * 2) if n.even? }
=> [4, 8, 12, 16, 20]

所感 🔗

簡潔に書けて良い(賛否両論あるらしいけど、個人的にはこっちの方がわかりやすい)
長さでいうと select + map の方が短いが、2回ループが走るのでパーフォマンスが悪い
内部で select + map をしていたら意味ないけど(後日、内部実装を確認してみる)

いつも each_with_object を使うことが多かったけど、これからは filter_map を積極的に使っていきたい

参考 🔗

zx で Hello, World!

Tags: zx

JavaScript でシェルスクリプトが書ける zx を触ってみたかったけど、いい題材がすぐ思いつかなかったので、取り急ぎ Hello, World! だけやった

インストール 🔗

まず、Node.js は 16.0.0 以上が必要だったので、volta でインストール

$ volta install node@16
$ node -v
v16.15.1
$ yarn global add zx
$ zx -v
7.0.1

Hello, World 🔗

#!/usr/bin/env zx

console.log('Hello, World!')
$ zx ./script.mjs
Hello, World!

一応、「知っている」から「触ったことある」に変わった

React Router を使った React アプリを Vercel にデプロイする時の設定

Tags: React Vercel

React アプリに React Router を使ってページを追加した
ローカルでは動いたが、Vercel にデプロイすると 404 エラーが表示されてうまく動かない

プロジェクトルートに以下のような vercel.json を追加してデプロイすると解決する

{
  "rewrites": [
    { "source": "/(.*)", "destination": "/" }
  ]
}

SPA でありがちな問題っぽい

参考 🔗

【Sinatra】Rack::URLMap を使ってコントローラーを分割する

Tags: Sinatra

app.rb がだんだんファットになってきて、コントローラーを分割したくなった
コントローラーを分割するやり方はいくつかあって、Rack::URLMap を使う方法を試したのでメモ

require 'sinatra/base'

class RootController < Sinatra::Base
  get '/' do
    "RootController"
  end
end

class UsersController < Sinatra::Base
  get '/' do
    "UsersController"
  end
end

class TasksController < Sinatra::Base
  get '/' do
    "TacksController"
  end
end

app.rb にまとめて書いたけど、本来は別ファイルに書く(controllers ディレクトリを作って)

require './app'

run Rack::URLMap.new({
  '/' => RootController,
  '/users' => UsersController,
  '/tasks' => TasksController
})
$ bundle exec rackup
Puma starting in single mode...
* Puma version: 5.6.4 (ruby 3.1.2-p20) ("Birdie's Version")
*  Min threads: 0
*  Max threads: 5
*  Environment: development
*          PID: 29609
* Listening on http://127.0.0.1:9292
* Listening on http://[::1]:9292
Use Ctrl-C to stop
$ curl localhost:9292
RootController

$ curl localhost:9292/users
UsersController

$ curl localhost:9292/tasks
TacksController

サクッとできた
ただ /users/:user_id/tasks みたいな名前付きパラメータが含まれるルーティングはうまくいかなかった

【Sinatra】404 Not Found のエラーハンドリング

Tags: Sinatra

存在しないパスにアクセスが来た時の対応

not_found ハンドラが用意されているので、これを使ったら良い

not_found do
  json(message: '404 Not Found.')
end
$ curl localhost:4567/foo
{"message":"404 Not Found."}

ステータスコードもちゃんと 404 になっている

$ curl localhost:4567/foo -v
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 4567 (#0)
> GET /foo HTTP/1.1
> Host: localhost:4567
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< X-Cascade: pass
< Content-Type: application/json
< X-Content-Type-Options: nosniff
< Content-Length: 28
<
* Connection #0 to host localhost left intact
{"message":"404 Not Found."}* Closing connection 0

【Github Actions】続・Dynamic Matrix を使って常に最新の Ruby バージョンでテストをする試み

【Github Actions】Dynamic Matrix を使って常に最新の Ruby バージョンでテストをする試み の続き

安定版のバージョンを返すAPI 🔗

公式?でAPIが用意された
https://cache.ruby-lang.org/pub/misc/ci_versions/

$ curl https://cache.ruby-lang.org/pub/misc/ci_versions/cruby.json
["2.7","3.0","3.1","head"]

Dynamic Matrix で扱いやすいフォーマットで返されるので、加工なしでそのまま使える

データソースは同じく ruby-builder-versions.json を使っているっぽい
https://github.com/ruby/actions/blob/6d30e4fb0c1a1189be3da336353842873301bd7a/tool/snapshot/update_ci_versions.rb#L9

バージョンを追加する 🔗

古いバージョンも使いたい場合はこんな感じ

$ curl -s 'https://cache.ruby-lang.org/pub/misc/ci_versions/cruby.json' | jq -c '. + ["2.6", "2.5", "2.4"]'
["2.7","3.0","3.1","head","2.6","2.5","2.4"]

GitHub Actions のアクション 🔗

上記のAPIをラップしたアクションも出来ていた
https://github.com/ybiquitous/dynamic-ruby-versions-action

jobs:
  ruby-versions:
    runs-on: ubuntu-latest
    outputs:
      versions: ${{ steps.versions.outputs.versions }}
    steps:
      - id: versions
        uses: ybiquitous/dynamic-ruby-versions-action@v1

  test:
    needs: ruby-versions
    runs-on: ubuntu-latest
    strategy:
      matrix:
        ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
    steps:
      - uses: actions/checkout@v3
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby }}
          bundler-cache: true
      - run: bundle exec rake

バージョンを追加する 🔗

古いバージョンも使いたい場合はこんな感じ

steps:
  - id: versions
    uses: ybiquitous/dynamic-ruby-versions-action@v1
    with:
      add: '"2.5", "2.6"'

所感 🔗

公式で用意された感じなので、安心して「Dynamic Matrix を使って常に最新の Ruby バージョンでテスト」ができそう
さっそく ruby/net-pop でも使われている(Pull Request #13

Docker + MySQL 8 で mbind: Operation not permitted が出る時の対応

Tags: Docker MySQL

問題 🔗

Docker で MySQL 8 を使っていたらログに mbind: Operation not permitted がたくさん出た

db:
  image: mysql:8.0.29
  environment:
    MYSQL_ROOT_PASSWORD: password
  ports:
    - "3306:3306"
  command: --default-authentication-plugin=mysql_native_password
  volumes:
    - mysql_vol:/var/lib/mysql
habitra-db-1   | 2022-05-27T05:48:22.844580Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
habitra-db-1   | 2022-05-27T05:48:22.871235Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
habitra-db-1   | 2022-05-27T05:48:22.871392Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.29'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.
habitra-web-1  | Puma starting in single mode...
habitra-web-1  | * Puma version: 5.6.4 (ruby 3.1.2-p20) ("Birdie's Version")
habitra-web-1  | *  Min threads: 0
habitra-web-1  | *  Max threads: 5
habitra-web-1  | *  Environment: development
habitra-web-1  | *          PID: 1
habitra-web-1  | * Listening on http://0.0.0.0:4567
habitra-web-1  | Use Ctrl-C to stop
habitra-db-1   | mbind: Operation not permitted
habitra-db-1   | mbind: Operation not permitted
habitra-db-1   | mbind: Operation not permitted
habitra-db-1   | mbind: Operation not permitted
habitra-db-1   | mbind: Operation not permitted

解決方法 🔗

CAP_SYS_NICE を有効にすると解決する

【Github Actions】Dynamic Matrix を使って常に最新の Ruby バージョンでテストをする試み

新しいバージョンが出る度にワークフローファイルを更新するのは面倒だなと思ったので試してみた

jobs:
  versions:
    name: Get versions
    runs-on: ubuntu-latest
    steps:
      - id: set-matrix
        name: Set Matrix
        run: |
          versions=$(
            curl -s https://raw.githubusercontent.com/ruby/setup-ruby/master/ruby-builder-versions.json |
              jq -c '[.ruby[]
                | select(test("preview|rc|debug") | not)
                | if test("^[a-z]") then . else .[0:3] end
                | select(. >= "2.5")]
                | unique'
            )
          echo "::set-output name=matrix::${versions}"
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
  build:
    needs: versions
    runs-on: ubuntu-latest
    strategy:
      matrix:
        ruby: ${{ fromJson(needs.versions.outputs.matrix) }}
    name: Ruby ${{ matrix.ruby }}
    steps:
    - uses: actions/checkout@v2
    - name: Set up Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: ${{ matrix.ruby }}
        bundler-cache: true
    - name: Run the default task
      run: |
        bundle exec rake

001.png https://github.com/ytkg/ruby-dynamic-matrix-testing/actions/runs/1799057068

Vercel + Cloudflare DNS でリダイレクトループエラー

問題 🔗

React アプリを Vercel にデプロイして、Cloudflare DNS でカスタムドメインを設定したら、リダイレクトループエラーが発生した

001.png

解決方法 🔗

SSL/TLS 暗号化モードを フル にしたら解決した
デフォルトは フレキシブル だった

002.png

同じドメインでサブドメインを他の用途でも使っているが、今のところ不具合は起きていない

参考 🔗

Cloudflare + Vercelでのリダイレクトループエラーの解消メモ - Qiita

Google Chrome での 301 リダイレクトのキャッシュを削除する

Cloudflare Workers のリダイレクトのサンプルコードを試していたら、ハマってしまった

https://developers.cloudflare.com/workers/examples/redirect/#redirect-all-requests-to-one-url

const destinationURL = 'https://example.com';
const statusCode = 301;

async function handleRequest(request) {
    return Response.redirect(destinationURL, statusCode);
}

addEventListener('fetch', async event => {
    event.respondWith(handleRequest(event.request));
});

何も考えずに Chrome からアクセスしたらずっとリダイレクトされるようになってしまった
コードを書き換えても、開発サーバー止めても

ステータスコード 301 と 302 の違い 🔗

両方ともリダイレクトのステータスコードだけど、意味合いが違う

301 は恒久的なリダイレクトで、サイトをドメインごと移転した場合やURLの正規化目的などに使う

302 は一時的なリダイレクトで、メンテナンスなどで一時的に別のページを見せたい場合やデバイスに応じてページを振り分けたい場合などに使う

Chrome は 301 リダイレクトを永久にキャッシュする 🔗

ステータスコード 301 は恒久的なリダイレクトなので、Chrome は気を利かせて永久にキャッシュするらしい
リダイレクト元がどうなっていようが、直接リダイレクト先にアクセスしてしまう

キャッシュの削除(キャッシュを使わない) 🔗

開発者ツールを開いて、「Network」タブの「Disable chache」にチェックを付ける
これでアクセスしたらキャッシュを使わないので、リダイレクトされない
そのあとはチェックを外しても大丈夫だった

001.png

参考 🔗

Categories


Tags