Django を AWS ECS(FARGATE) + ELB で動かすときの ALLOWED_HOSTS の設定
めちゃくちゃ苦戦したのでメモ。
困ったこと
Django のアプリを ECS(FARGATE) 上で動かすと Invalid HTTP_HOST header: '10.0.X.Y'. You may need to add '10.0.X.Y' to ALLOWED_HOSTS.
みたいなエラーが出て、 ELB のヘルスチェックで落ちる。
だからといって、 ALLOWED_HOSTS = ['*']
みたいにするのはセキュリティ的にも気持ち的にもやりたくない。
解決策
Stack overflow に同じ問題にぶち当たっている人がいた。
通常の ALLOWED_HOSTS
の設定の下に、以下を追加すれば良いみたい。
try: resp = requests.get('http://169.254.170.2/v2/metadata') data = resp.json() container_meta = data['Containers'][0] EC2_PRIVATE_IP = container_meta['Networks'][0]['IPv4Addresses'][0] ALLOWED_HOSTS.append(EC2_PRIVATE_IP) except requests.exceptions.RequestException: pass
これで当該のエラーが出なくなって、タスクが再起動されまくる悪夢から解放されました!
参考URL
Debian Stretch で Bluetooth イヤホンを A2DP で利用する
本記事では、Debian Stretch の PC で Bluetooth イヤホンを A2DP プロファイルで利用する方法を説明します。
動作環境
Debian Stretch で Bluetooth で音楽再生
Debian Stretch をインストールするとデフォルトで Bluetooth のオーディオが利用できるのですが、デフォルトのままではモノラルの低音質(HSP/HFP プロファイル) での再生しかできなかったため、追加の設定を行うことでステレオの高音質(A2DP プロファイル)で再生できるようにしました。
必要なパッケージを追加
以下のコマンドで Bluetooth のオーディオ関連のパッケージを追加します。
sudo apt-get install pulseaudio pulseaudio-module-bluetooth pavucontrol bluez-firmware
そして、Bluetooth とオーディオのサービスを再起動します。
sudo service bluetooth restart sudo killall pulseaudio
Bluetooth のペアリング
All Settings > Bluetooth からイヤホンとペアリングします。
オーディオの設定
All Settings > Sound Settings > Output で先程ペアリングしたイヤホンを選択すると、Profile として A2DP もしくは High Fidelity Playback (A2DP Sink) が選択できるので、こちらを選択することでステレオ再生ができるようになりました。
関連URL
Gorm で PostgreSQL の JSONB 型の key, value で絞り込む
この記事では、Golang の ORM である Gorm を使って、 PostgreSQL の JSONB 型の中身の key や value による絞り込みをかける方法を紹介しています。
動作環境
- Go 1.10
- PostgreSQL 9.6
Gorm で PostgreSQL の JSONB を絞り込む
モデル
例えば、以下のような、JSON 型の任意のタグを持てるデータ型について考えます。
type TaggedData struct { ID uint32 `gorm:"NOT NULL;primary_key" sql:"TYPE:serial"` Name string `json:"name" gorm:"NOT NULL"` Tags postgres.Jsonb `json:"tags"` }
ここに、3件のデータを登録します。
host := "localhost" user := "postgres" password := "" db := "tagged" client, err := gorm.Open("postgres", fmt.Sprintf( "host=%s user=%s password=%s dbname=%s sslmode=disable", host, user, password, db, )) if err != nil { fmt.Printf("%v\n", err) return } // テーブルを作成 client.AutoMigrate(&TaggedData{}) // データを登録 client.Create(&TaggedData{Name: "data1", Tags: postgres.Jsonb{[]byte(`{"key1": "val1"}`)}}) client.Create(&TaggedData{Name: "data2", Tags: postgres.Jsonb{[]byte(`{"key1": "val1", "key2": "val2"}`)}}) client.Create(&TaggedData{Name: "data3", Tags: postgres.Jsonb{[]byte(`{"key1": "val3", "key2": "val2", "key3": {"key4": "val4"}}`)}})
JSONB の値で検索
例えば Tags
が "key1" == "val1"
のデータを検索してみます。
data := []TaggedData{} // JSONB の値で検索 res := client.Where("tags ->> 'key1' = ?", "val1").Find(&data) if res.Error != nil { fmt.Printf("%v\n", res.Error) return } // 結果を表示 for _, d := range data { fmt.Println(d.Name) }
結果は以下のようになります。
data1 data2
続いて、 "key2" == "val2"
のデータを検索してみます。
res := client.Where("tags ->> 'key2' = ?", "val2").Find(&data)
結果は以下の通りで、data1 の Tags
は "key2"
というフィールドを持っていませんが、エラーにはなりません。
data2 data3
入れ子になっているフィールドを検索することもできます。
// 入れ子のフィールドを検索 res := client.Where("tags #>> '{key3, key4}' = ?", "val4").Find(&data)
こちらも想定通り動きました。結果は以下。
data3
プログラム全体
package main import ( "fmt" "github.com/jinzhu/gorm" "github.com/jinzhu/gorm/dialects/postgres" ) type TaggedData struct { ID uint32 `gorm:"NOT NULL;primary_key" sql:"TYPE:serial"` Name string `json:"name" gorm:"NOT NULL"` Tags postgres.Jsonb `json:"tags"` } func main() { host := "localhost" user := "postgres" password := "" db := "tagged" client, err := gorm.Open("postgres", fmt.Sprintf( "host=%s user=%s password=%s dbname=%s sslmode=disable", host, user, password, db, )) if err != nil { fmt.Printf("%v\n", err) return } client.AutoMigrate(&TaggedData{}) client.Create(&TaggedData{Name: "data1", Tags: postgres.Jsonb{[]byte(`{"key1": "val1"}`)}}) client.Create(&TaggedData{Name: "data2", Tags: postgres.Jsonb{[]byte(`{"key1": "val1", "key2": "val2"}`)}}) client.Create(&TaggedData{Name: "data3", Tags: postgres.Jsonb{[]byte(`{"key1": "val3", "key2": "val2", "key3": {"key4": "val4"}}`)}}) data := []TaggedData{} res := client.Where("tags ->> 'key1' = ?", "val1").Find(&data) if res.Error != nil { fmt.Printf("%v\n", res.Error) return } for _, d := range data { fmt.Println(d.Name) } data = []TaggedData{} res = client.Where("tags ->> 'key2' = ?", "val2").Find(&data) if res.Error != nil { fmt.Printf("%v\n", res.Error) return } for _, d := range data { fmt.Println(d.Name) } res = client.Where("tags #>> '{key3, key4}' = ?", "val4").Find(&data) if res.Error != nil { fmt.Printf("%v\n", res.Error) return } for _, d := range data { fmt.Println(d.Name) } if err := client.DropTable(&TaggedData{}); err != nil { fmt.Printf("%v\n", err) return } }
参考URL
Debian Stretch に protobuf 3.6 をインストール
本記事では Debian 9 Stretch に protobuf 3.6 をインストールする方法を紹介しています。
C++ で gRPC/protobuf を利用するためには、ソースからコンパイルする必要があります。 deb パッケージ提供してほしい。。。
環境
- Debian 9 Stretch
- protobuf v3.6.0
インストール手順
protobuf/README.md at master · google/protobuf · GitHub を参考にインストールします。
依存パッケージのインストール
$ sudo apt-get install autoconf automake libtool curl make g++ unzip
protobuf のリポジトリをクローン
$ git clone https://github.com/google/protobuf.git
$ cd protobuf
$ git checkout v3.6.0
サブモジュールの更新
$ git submodule update --init --recursive $ ./autogen.sh
コンパイル&インストール
$ ./configure $ make # 10分〜20分くらいかかります $ make check # 5分〜10分くらいかかります $ sudo make install $ sudo ldconfig
これで protoc コマンド等が利用できるようになります!
参考URL
Debian Stretch に OpenCV 3.4 をインストール
この記事では Debian Stretch に OpenCV 3系をインストールする手順を紹介しています。
環境
インストール手順
Releases - OpenCV library からインストールしたいバージョンの zip ファイルをダウンロードします。
もしくはコマンドラインからダウンロード。
$ wget https://github.com/opencv/opencv/archive/3.4.0.zip
zip ファイルを展開します。
$ unzip opencv-3.4.0.zip
make && make install します。
$ cd opencv-3.4.0 $ mkdir build && cd build $ cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local .. $ make -j4 # -j4 の部分はCPU数に合わせて変更してください $ sudo make install
これだけ。6コア12スレッドの Core i7 だと make にかかったのは 1〜2分でした、はやい。