DrizzleでCould not connectエラー

以下サイトを試していたときに発生したエラー。

Microsoft Ignite ブロックチェーン開発の概要 演習 - Drizzle を使ってみる

環境

  • macOS Big Sur 11.6
  • Truffle v5.4.15 (core: 5.4.15)
  • Solidity v0.5.16 (solc-js)
  • Node v12.22.7
  • Web3.js v1.5.3
  • テキストエディターATOM

今回はVisual Studio Codeは利用せずにATOMを利用。

現象

記事内では以下のように、Visual Studio Codeを使ったビルドやデプロイが説明されていたが、すべてターミナルで実行した。

[記事の説明]

1. Visual Studio Code 内から、[ターミナル] > [新しいターミナル] に移動してターミナルを開きます。
2. 次に、「ganache-cli」と入力して、Ganache CLI を起動します。
いずれかのコントラクトを右クリックし、[Build Contracts](コントラクトをビルドする) を選択します。 ビルドとコンパイルが正常に完了するまで待ちます。
3. もう一度コントラクトのいずれかを右クリックし、[Deploy Contracts](コントラクトをデプロイする) を選択します。 デプロイ先のウィンドウが表示されたら、develop ネットワークを選択します。 移行が正常に完了するまで少し待ちます。

上記のかわりに以下を実行。

$ truffle compile
〜省略(これは成功する)〜

$ truffle migrate

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.

> Something went wrong while attempting to connect to the network at http://127.0.0.1:7545. Check your network configuration.

Could not connect to your Ethereum client with the following parameters:
    - host       > 127.0.0.1
    - port       > 7545
    - network_id > 5777
Please check that your Ethereum client:

そうするとネットワークに接続できない旨のエラーが発生。

原因

Ethereumブロックチェーン(ノードサーバー)に接続ができていない。つまり、サーバーが動いていない or ネットワーク設定が誤り。
今回のケースはブロックチェーンを動かしていなかった。

なお、ネットワーク設定の誤りでよくあるのは、truffle_config.jsの「network_id: "*"」を「network_id: "5777"」と記載しているケース。これだと文字列になってしまうため、「network_id: 5777」と記載する必要あり。

対応

案1(truffle develop)

ブロックチェーン起動からmigrateまで1セットで実行できる truffle develop を利用して、コンパイルとマイグレーションを実行する。
(前提)ganache-cliは停止していること

$ truffle develop
truffle(develop)> compile
truffle(develop)> migrate

そのあとに記事の以下内容を実行すると画面表示までできる。

[記事の内容]

- cd app: app/ フォルダーに移動します。
- npm rebuild: app/ フォルダーでビルドを実行し、変更を再コンパイルします。
- npm run start: React の Web パック開発サーバーを起動します。 これにより、React プロジェクトの新しいブラウザー ウィンドウが開きます。

案2(Ganache起動)

デスクトップアプリのGanacheでブロックチェーンを動かしてからmigrateする。

  1. 以下をDLして起動(SERVERのPORT NUMBERは「7545」にする)
    Ganache ONE CLICK BLOCKCHAIN - Truffle Suite

  2. 以下をターミナルで実行

$ truffle compile
$ truffle migrate

(試してはいないが)Ganacheに接続して画面確認する場合は、GanacheでWORKSPACEを立ち上げたあとに、設定で以下のように「ADD PROJECT」ボタンでtruffle-config.jsを読み込ませて、リンクさせる必要あり。

MetaMaskの接続先アカウントが変更できない

Truffle Suiteのチュートリアルをやっていたときに、MetaMaskで接続したいアカウントに変更できなかったときの対応メモ。
以下のようなポップアップ表示されてウォレットを選択するやつです。

現象

Truffle Suiteで構築したブロックチェーン(Pet Shopサイト)で犬を選択するときに、決済したいウォレットアドレスが選択できない。表示された画面上からも、「ウォレットの変更」のような選択方法もない。

上記例の「Test1ウォレット」には、ETHを入れていないため決済できない。

原因

選択したいウォレットのトリガーポイント(ウォレットが表示されるタイミング)が決まっているため、それにあわせる必要がある。

対応

アドオンのMetaMaskで決済したいウォレットを選択したあとに、サイト上の決済ボタンを押す。

ただし、これでもうまくいかない切り替わらないケースがあった。

その場合は、一度異なるウォレットを選択してから、再度決済したいウォレットを選択する。
以下の例だと、「Ganacheウォレット」を選択したい場合、「Test1ウォレット」を選択したあとに、再度「Ganacheウォレット」を選択する。

これで無事に決済できた。

truffle consoleでmigrateすると「insufficient funds」エラー

ブロックチェーンのtruffleでmigrateすると「GAS代が足りない」というエラーが出る件。

現象

truffle(development)> migrate

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.



Starting migrations...
======================
> Network name:    'development'
> Network id:      5777
> Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------

Error:  *** Deployment Failed ***

"Migrations" could not deploy due to insufficient funds
   * Account:  0xd89Bcc7B08CbBA3bC8f1E69F03DB4ac9b59aDF07
   * Balance:  0 wei
   * Message:  Returned error: sender doesn't have enough funds to send tx. The upfront cost is: 4104360000000000 and the sender's account only has: 0
   * Try:
      + Using an adequately funded account
      + If you are using a local Geth node, verify that your node is synced.

原因

ganache-cli起動時にデータ永続化の --db を指定しているため、それが影響している(と思われる。未検証)。

$ yarn ganache-cli --db ./db/ --mnemonic "xxx" --networkId 5777

対策

暫定対応として、--dbの引数を外して起動する。

$ yarn ganache-cli --mnemonic "xxx" --networkId 5777

参考サイト

Rails APIでJbuilderのViews出力時のエラー

現象1 配列ではないのにjson.array利用でエラー

エラー内容とコード

"exception": "#<ActionView::Template::Error: undefined method `map' for #<AgendaItem id: 10, agenda_group_id: 1, name: \"Project Phases\", order_number: 1, created_at: \"2021-09-05 07:21:39.276841000 +0000\", updated_at: \"2021-09-05 07:21:39.276841000 +0000\", indent_level: 1>\nDid you mean?  tap>",
json.agenda_items do
    json.array! @agenda_groups.agenda_items do |ai|
        json.extract! ai,
        :id,
        :name,
        :order_number,
        :indent_level,
        :created_at,
        :updated_at
    end
end

原因

配列ではないのにjson.arrayを利用している。

対応

変数として出力する。

json.agenda_item do
    json.extract! dai.agenda_item,
        :id,
        :name,
        :order_number,
        :indent_level,
        :created_at,
        :updated_at
end

現象2 オブジェクトなのにjson.extract利用でエラー

エラー内容とコード

"exception": "#<ActionView::Template::Error: undefined method `id' for #<ActiveRecord::Associations::CollectionProxy []>\nDid you mean?  ids>",
json.agenda_details do
    json.extract! dai.agenda_item.agenda_details,
        :id,
        :body,
        :created_at,
        :updated_at
    end
end

原因

オブジェクトなのにjson.extractを利用している。

対応

配列取得(json.array)してから出力する。

json.agenda_details do
    json.array! dai.agenda_item.agenda_details do |ad|
        json.extract! ad,
        :id,
        :body,
        :created_at,
        :updated_at
    end
end

その他

Jbuilder出力時は以下の確認が重要

  • 配列か変数か(json.arrayが必要か、そのまま出力可能か)
  • 複数形か単数形か(例:has_manyのitemsか、has_oneのitemか)
  • アソシエーション設定が適切か
  • こまめなデバッグ(pで各オブジェクトごとに配列かどうか、値が取得できているかどうか、など)

Rails APIのJbuilderで親・子・孫をアソシエーションで取得

Rails6 APIモードで、親・子・孫のリレーション関係をアソシエーション設定したあとに、Jbuilderのviewsで取得する方法。

設定

api/app/models/agenda_group.rb

class AgendaGroup < ApplicationRecord
  belongs_to :user
  has_many :agenda_items, -> { order('order_number') }, dependent: :destroy

  scope :ordered, -> {
    order('name')
  }
end

api/app/controllers/v1/agenda_groups_controller.rb

  def show_relations
    @agenda_groups = AgendaGroup.ordered
    render 'index', format: :json, handlers: 'jbuilder'
  end

api/app/views/v1/agenda_groups/index.json.jbuilder

#--- (親モデル)agenda_groups ---
json.array! @agenda_groups do |ag|
  json.extract! ag,
    :id,
    :name,
    :created_at,
    :updated_at

  #--- (子モデル)agenda_items ---
  json.agenda_items do # JSONのグループ
    json.array! ag.agenda_items do |ai| # 配列をループで取得
      json.extract! ai, # 指定した以下のカラムを出力
        :id,
        :name,
        :order_number,
        :indent_level,
        :created_at,
        :updated_at

      #--- (孫モデル)agenda_details ---
      json.agenda_details do
        json.array! ai.agenda_details do |ad|
          json.extract! ad,
            :id,
            :body,
            :created_at,
            :updated_at
        end
      end
      #--- /agenda_details ---

    end
  end
  #--- /agenda_items ---

end
#--- /agenda_groups ---

出力結果

[
    {
        "id": 86,
        "name": "2021/09/05 16:29の登録",
        "created_at": "2021-09-05T07:30:47.926Z",
        "updated_at": "2021-09-05T07:30:47.926Z",
        "agenda_items": []
    },
    {
        "id": 64,
        "name": "test",
        "created_at": "2021-09-05T07:05:15.065Z",
        "updated_at": "2021-09-05T07:05:51.025Z",
        "agenda_items": []
    },
    {
        "id": 3,
        "name": "Business Analysis Agenda",
        "created_at": "2021-08-14T07:04:29.496Z",
        "updated_at": "2021-08-14T07:04:29.496Z",
        "agenda_items": []
    },
    {
        "id": 1,
        "name": "RDD Agenda",
        "created_at": "2021-08-14T05:40:54.293Z",
        "updated_at": "2021-08-14T05:40:54.293Z",
        "agenda_items": [
            {
                "id": 1,
                "name": "Overview",
                "order_number": 1,
                "indent_level": null,
                "created_at": "2021-08-14T05:42:50.929Z",
                "updated_at": "2021-08-14T05:42:50.929Z",
                "agenda_details": [
                    {
                        "id": 1,
                        "body": "This document aims to give a detailed description on how the applications that will be implemented are designed."
                    },
                    {
                        "id": 12,
                        "body": "The Project will be divided into 6 phases."
                    },
                    {
                        "id": 5,
                        "body": "コレクションをインスタンスから取得できます。"
                    }
                ]
            },
            {
                "id": 9,
                "name": "Loadmap",
                "order_number": 2,
                "indent_level": 2,
                "created_at": "2021-09-05T07:21:23.096Z",
                "updated_at": "2021-09-15T10:50:29.379Z",
                "agenda_details": [
                    {
                        "id": 4,
                        "body": "The Project will be divided into 6 phases."
                    }
                ]
            },
            {
                "id": 10,
                "name": "Project Phases",
                "order_number": 2,
                "indent_level": null,
                "created_at": "2021-09-05T07:21:39.276Z",
                "updated_at": "2021-09-05T07:21:39.276Z",
                "agenda_details": []
            }
        ]
    },
    {
        "id": 63,
        "name": "RFP Agenda",
        "created_at": "2021-09-05T07:04:36.890Z",
        "updated_at": "2021-09-05T07:04:36.890Z",
        "agenda_items": []
    },
    {
        "id": 68,
        "name": "RFP Agenda",
        "created_at": "2021-09-05T07:19:15.892Z",
        "updated_at": "2021-09-05T07:19:15.892Z",
        "agenda_items": [
            {
                "id": 12,
                "name": "Project Phases",
                "order_number": 1,
                "indent_level": null,
                "created_at": "2021-09-05T07:27:39.135Z",
                "updated_at": "2021-09-05T07:27:39.135Z",
                "agenda_details": []
            },
            {
                "id": 13,
                "name": "Project Phases",
                "order_number": 1,
                "indent_level": 1,
                "created_at": "2021-09-15T11:01:24.145Z",
                "updated_at": "2021-09-15T11:01:24.145Z",
                "agenda_details": []
            },
            {
                "id": 11,
                "name": "Project Phases",
                "order_number": 3,
                "indent_level": null,
                "created_at": "2021-09-05T07:27:29.312Z",
                "updated_at": "2021-09-05T07:27:29.312Z",
                "agenda_details": []
            }
        ]
    },
    {
        "id": 4,
        "name": "Sample Agenda",
        "created_at": "2021-08-14T14:49:24.904Z",
        "updated_at": "2021-08-14T14:49:24.904Z",
        "agenda_items": []
    },
    {
        "id": 2,
        "name": "Sample Agenda",
        "created_at": "2021-08-14T07:04:11.558Z",
        "updated_at": "2021-08-14T07:04:11.558Z",
        "agenda_items": []
    },
    {
        "id": 9,
        "name": "Test Agenda",
        "created_at": "2021-08-14T14:56:24.066Z",
        "updated_at": "2021-08-14T14:56:24.066Z",
        "agenda_items": [
            {
                "id": 8,
                "name": "Sample Agenda Item",
                "order_number": 1,
                "indent_level": null,
                "created_at": "2021-08-15T14:56:33.134Z",
                "updated_at": "2021-08-15T14:56:33.134Z",
                "agenda_details": [
                    {
                        "id": 3,
                        "body": "1つのアカウントが1つのアカウント履歴に関連付けられる場合、以下のような感じになります。"
                    }
                ]
            }
        ]
    }
]

Rails APIでJbuilderを使わずControllersのrender jsonを親・子・孫・ひ孫で出力

RailsのAPIモードで、Controllersのrender jsonを親・子・孫・ひ孫という、深いリレーションをJSON形式でそれぞれネストし出力する方法のメモ。

環境

  • Rails6のAPIモードでJbuilderは不使用のためviewはなくController完結
  • ControllerでJSONを標準で利用(render jsonで出力)
  • 親・子・孫・ひ孫のアソシエーションを設定。きれいな4階層の世代関係ではなく2つの塊でリレーション
    • 1つ目の塊:親ー子
    • 2つ目の塊:子ー孫ーひ孫

設定

(親モデル)api/app/models/document_group.rb

class DocumentGroup < ApplicationRecord
  belongs_to :user
  has_many :document_agenda_items, -> { order('order_number') }, dependent: :destroy

  scope :ordered, -> {
    order('name')
  }
end

(子モデル)api/app/models/document_agenda_item.rb

class DocumentAgendaItem < ApplicationRecord
  belongs_to :document_group
  belongs_to :agenda_item
  has_one :agenda_details, through: :agenda_item

  scope :ordered, -> {
    order('order_number')
  }
end

(孫モデル)api/app/models/agenda_item.rb

class AgendaItem < ApplicationRecord
  belongs_to :agenda_group
  has_many :agenda_details, dependent: :destroy
  has_one :document_agenda_item, dependent: :destroy

  scope :ordered, -> {
    order('order_number')
  }
end

(ひ孫モデル)api/app/models/agenda_detail.rb

class AgendaDetail < ApplicationRecord
  belongs_to :agenda_item
end

api/app/controllers/v1/document_groups_controller.rb

class V1::DocumentGroupsController < ApplicationController

  def show_relations
    @document_groups = DocumentGroup.ordered

    render json:
      @document_groups, # 親モデル
      include: {
        :document_agenda_items => { # 子モデル
          :include => {
            :agenda_item => { # 孫モデル
              include: :agenda_details # ひ孫モデル
            }
          }
        }
      }
  end

end

アソシエーションを設定して「include」を利用すると取得できる。

出力結果

localhost:3000/v1/document_groups/{{DOCUMENT_GROUP_ID}}/show_relations

[
    {
        "id": 1,
        "user_id": 1,
        "name": "SFA PJ",
        "created_at": "2021-08-14T05:56:07.534Z",
        "updated_at": "2021-08-14T05:56:07.534Z",
        "document_agenda_items": [
            {
                "id": 3,
                "document_group_id": 1,
                "agenda_item_id": 10,
                "order_number": 1,
                "created_at": "2021-09-18T09:06:53.429Z",
                "updated_at": "2021-09-18T09:06:53.429Z",
                "indent_level": 1,
                "agenda_item": {
                    "id": 10,
                    "agenda_group_id": 1,
                    "name": "Project Phases",
                    "order_number": 2,
                    "created_at": "2021-09-05T07:21:39.276Z",
                    "updated_at": "2021-09-05T07:21:39.276Z",
                    "indent_level": null,
                    "agenda_details": []
                }
            },
            {
                "id": 1,
                "document_group_id": 1,
                "agenda_item_id": 1,
                "order_number": 2,
                "created_at": "2021-08-14T05:57:13.772Z",
                "updated_at": "2021-09-15T11:00:40.122Z",
                "indent_level": 2,
                "agenda_item": {
                    "id": 1,
                    "agenda_group_id": 1,
                    "name": "Overview",
                    "order_number": 1,
                    "created_at": "2021-08-14T05:42:50.929Z",
                    "updated_at": "2021-08-14T05:42:50.929Z",
                    "indent_level": null,
                    "agenda_details": [
                        {
                            "id": 1,
                            "agenda_item_id": 1,
                            "body": "This document aims to give a detailed description on how the applications that will be implemented are designed. This is done by using high-level, component and more detailed class charts.",
                            "created_at": "2021-08-14T05:47:56.855Z",
                            "updated_at": "2021-08-14T05:47:56.855Z"
                        },
                        {
                            "id": 12,
                            "agenda_item_id": 1,
                            "body": "The Project will be divided into 6 phases.",
                            "created_at": "2021-09-14T15:06:34.994Z",
                            "updated_at": "2021-09-14T15:06:34.994Z"
                        },
                        {
                            "id": 5,
                            "agenda_item_id": 1,
                            "body": "コレクションをインスタンスから取得できます。",
                            "created_at": "2021-09-05T07:27:47.658Z",
                            "updated_at": "2021-09-15T10:54:58.337Z"
                        }
                    ]
                }
            },
            {
                "id": 2,
                "document_group_id": 1,
                "agenda_item_id": 8,
                "order_number": 3,
                "created_at": "2021-09-18T09:06:16.287Z",
                "updated_at": "2021-09-18T09:06:16.287Z",
                "indent_level": 2,
                "agenda_item": {
                    "id": 8,
                    "agenda_group_id": 9,
                    "name": "Sample Agenda Item",
                    "order_number": 1,
                    "created_at": "2021-08-15T14:56:33.134Z",
                    "updated_at": "2021-08-15T14:56:33.134Z",
                    "indent_level": null,
                    "agenda_details": [
                        {
                            "id": 3,
                            "agenda_item_id": 8,
                            "body": "9つの知識エリアをもとにプロジェクト管理を推進します。",
                            "created_at": "2021-08-15T15:08:04.410Z",
                            "updated_at": "2021-08-15T15:08:22.285Z"
                        }
                    ]
                }
            }
        ]
    },
    {
        "id": 4,
        "user_id": 1,
        "name": "SFA PJ Requirements Definition Document",
        "created_at": "2021-09-05T07:28:04.673Z",
        "updated_at": "2021-09-05T07:28:04.673Z",
        "document_agenda_items": []
    },
    {
        "id": 2,
        "user_id": 1,
        "name": "Webシステム開発RFP",
        "created_at": "2021-08-15T15:09:16.221Z",
        "updated_at": "2021-08-15T15:09:28.699Z",
        "document_agenda_items": [
            {
                "id": 8,
                "document_group_id": 2,
                "agenda_item_id": 9,
                "order_number": 1,
                "created_at": "2021-09-18T10:28:38.363Z",
                "updated_at": "2021-09-18T10:28:38.363Z",
                "indent_level": 1,
                "agenda_item": {
                    "id": 9,
                    "agenda_group_id": 1,
                    "name": "Loadmap",
                    "order_number": 2,
                    "created_at": "2021-09-05T07:21:23.096Z",
                    "updated_at": "2021-09-15T10:50:29.379Z",
                    "indent_level": 2,
                    "agenda_details": [
                        {
                            "id": 4,
                            "agenda_item_id": 9,
                            "body": "The Project will be divided into 6 phases.",
                            "created_at": "2021-09-05T07:22:30.368Z",
                            "updated_at": "2021-09-05T07:22:30.368Z"
                        }
                    ]
                }
            }
        ]
    }
]

その他

親・子・孫の場合

3世代のリレーションにしたい場合

  def show_relations
    @document_groups = DocumentGroup.ordered

    render json:
      @document_groups,
      include: {
        :document_agenda_items => {
          include: :agenda_item
        }
      }
  end

根本的な解決

本件はあくまで暫定策になるため、プロトタイピングなどを除き、利用は非推奨(個人的な意見)。根本的な解決は以下が必要。

  • リレーションが深すぎる場合はDB設計の見直し
  • Fat Controllerになってしまい汎用性もなくなりバグ誘発の可能性あり。Fat Modelにするため、Modle側にアソシエーションとメソッドを定義して、それをJbuilderのViews側で出力する方法を推奨(おそらく一般的にはこの方法)

参考情報

Stack Overflow - Ruby on Rails 5.0.2 - Multiple Nested Json Render

Railsで「PG::UndefinedColumn: ERROR: xxx.xxx_id does not exist」

Docker x Rails6 APIモードでアソシエーション設定時に「外部キーがない」といったエラーが表示された。
原因はアソシエーションの設定誤りだった。

設定内容

断片的な情報になるが、前提となる設定内容は以下のとおり。

ER図:以下の赤枠部分が対象

ER図:外部キーの設定状況

(親モデル)api/app/models/agenda_item.rb

class AgendaItem < ApplicationRecord
  belongs_to :agenda_group
  has_many :agenda_details, dependent: :destroy
  has_one :document_agenda_item, dependent: :destroy
end

(子モデル)api/app/models/document_agenda_item.rb

class DocumentAgendaItem < ApplicationRecord
  belongs_to :document_group
  has_one :agenda_item
end

api/app/controllers/v1/document_agenda_items_controller.rb

  def index
    @document_agenda_items = DocumentAgendaItem.all

    render json: @document_agenda_items, include: [:agenda_item]
  end

現象

indexにアクセスすると(localhost:3000/v1/document_agenda_items/)、以下のエラーが表示される。

api_1  | ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR:  column agenda_items.document_agenda_item_id does not exist
api_1  | LINE 1: SELECT "agenda_items".* FROM "agenda_items" WHERE "agenda_it...

原因

アソシエーションの設定ミス。DBの外部キーの設定とアソシエーションをあわせする必要がある。

  • has_oneは相手側に外部キーがある場合
  • belongs_toは自分に外部キーがある場合
4.2 has_one関連付けの詳細
has_one関連付けは他のモデルと1対1対応します。データベースの観点では、この関連付けでは相手のクラスが外部キーを持ちます。相手ではなく自分のクラスが外部キーを持っているのであれば、belongs_toを使うべきです。

引用元:Railsガイド

対応

自分(子モデル)が親モデルの外部キーを持っているため、has_oneではなく、belongs_toを使う。

api/app/models/document_agenda_item.rb

class DocumentAgendaItem < ApplicationRecord
  belongs_to :document_group
    # has_one :agenda_item # ←コメントアウト
    belongs_to :agenda_item # ←追加
end

Docker上のPostgreSQLに接続するとエラー(Reason: column "adsrc" does not exist)

現象

MacのPostgreSQLクライアントで、Docker上に構築したPostgreSQLに接続すると以下のエラーが表示される。

Failed to load table schema.
Reason: column "adsrc" does not exist

Macで利用したPostgreSQLクライアントは以下2つ
- PSequel
- PG Commander

原因

はっきりした原因はわからないが、PostgreSQLクライアント側が原因のように思えた。
なお、Docker上のPostgreSQLは現時点の最新版 v13.3 になっていたので、サーバー側の原因ではなさそう。

対策

DBeaver というPostgreSQLクライアントに変えたら一発で通った。

SourceTreeでGitHubにプッシュするとPermission denied (publickey)

環境

やや特殊なことをしていて、SSHキーを ~/.ssh には格納していなくて、ファイルサービスのBoxにSSHキーファイルをアップしている。

何のサービスがどのSSHキーを参照するかは、 ~/.ssh/config で設定できるため、そこでBoxのURL(~/Box/.ssh)を記載していた。
(Box DriveというWebDavを利用しているため、マウントされているようなものなので、ローカルパスのSSHキーを記載)

現象

SourceTreeで非公開リポジトリのGitHub(SSH認証)にプッシュすると以下のエラー。

Pushing to git@github.com:mokuji-ya/docker-rails-api.git
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

原因

$ ssh -vT git@github.com コマンドで、どのSSHキーを参照しているのか確認すると、 ~/.ssh/id_rsa を参照していることがわかった。
でも本物は、 ~/Box/.ssh/id_rsa になっているので参照先が誤っている。

対策

MacだとSourceTreeのSSHキーの参照先を変更できないようで、 ~/.ssh/id_rsa を強制的に参照してしまうようだった。なお、Windowsだと参照先の変更が可能。

やむをえないため、 ~/Box/.ssh/id_rsa を ~/.ssh/id_rsa にコピペして解決。

備考

接続確認は $ ssh -T git@github.com のコマンド。

docker-compose upで大量のエラー

現象

docker-compose up すると、以下のように大量のエラーが発生。

mac$ docker-compose up

Traceback (most recent call last):
  File "docker/api/client.py", line 268, in _raise_for_status
  File "requests/models.py", line 941, in raise_for_status
requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: http+docker://localhost/version

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker/api/client.py", line 214, in _retrieve_server_version
  File "docker/api/daemon.py", line 181, in version
  File "docker/api/client.py", line 274, in _result
  File "docker/api/client.py", line 270, in _raise_for_status
  File "docker/errors.py", line 31, in create_api_error_from_http_exception
docker.errors.APIError: 500 Server Error for http+docker://localhost/version: Internal Server Error ("b'dial unix docker.raw.sock: connect: connection refused'")

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker-compose", line 3, in <module>
  File "compose/cli/main.py", line 81, in main
  File "compose/cli/main.py", line 200, in perform_command
  File "compose/cli/command.py", line 60, in project_from_options
  File "compose/cli/command.py", line 152, in get_project
  File "compose/cli/docker_client.py", line 41, in get_client
  File "compose/cli/docker_client.py", line 170, in docker_client
  File "docker/api/client.py", line 197, in __init__
  File "docker/api/client.py", line 221, in _retrieve_server_version
docker.errors.DockerException: Error while fetching server API version: 500 Server Error for http+docker://localhost/version: Internal Server Error ("b'dial unix docker.raw.sock: connect: connection refused'")
[17538] Failed to execute script docker-compose

原因

Dockerを起動し忘れていた。

対策

macの場合は、Docker Desktopを起動してから、docker-compose up を再度実行する。