docker exec で cd する方法
dockerを使っていて、普段は↓のコマンドでコンテナ内に入って作業してます。
$ docker exec -it {container-name} /bin/bash
最近はコンテナ内でお決まりの作業(特定のディレクトリに移動してコマンド実行など)をしたいときに
$ docker exec -i {container-name} "cd /path/to && ls"
の様な形で実行できると思っていたのですが、実際は違っていて上手くいきませんでした。
↓の様なエラーが出ました。
$ docker exec -i {container-name} "cd /var/log && ls" oci runtime error: exec failed: container_linux.go:265: starting container process caused "exec: \"cd /var/log && ls\": stat cd /var/log && ls: no such file or directory"
cd する方法
$ docker exec -i {container-name} /bin/bash -c "cd /path/to && ls"
という風に、 /bin/bash -c
としてその後に実行したいコマンドを書いてあげると動く。
参考
docker-exec failed: "cd": executable file not found in $PATH - Stack Overflow
ISUCON7予選に参加しました
id:Maco_Tasu に、ISUCONに一緒に出ませんかと誘ってもらえたのでいい機会だしと思い参加しました。
LabALICEというチームで、メンバーはid:Maco_Tasu, id:karia です。
全員のスコアと順位を出して頂けて運営の方には感謝です。
最終スコアは 79,590 で、43位でした。
当日私は、画像周りの修正をしたのでそのあたりについて記録を残しておこうと思います。
事前準備
チームで3回集まって過去問を解きました。
解いた過去問は
- isucon6予選
- isucon4予選
- pixiv社の社内向けisucon
です。
過去問を解くことで全体的な流れを掴むことができました。
そこで一番感じたのが、競技中にNginxの設定などを動作確認しながら作成してると時間がもったいないということでした。
NginxやMySQLなど、あらかじめ使うであろう物の設定ファイルはひな形を作っておこうとチームで話あって事前準備をしていました。
当日
最初の役割分担は id:Maco_Tasu がgithubへのソースコード登録、id:karia がインフラの整備となっていました。
私は、DBテーブルの確認をしてからアプリを触って動作確認をしていました。
今回のお題はチャットアプリで、画像の数が多いためNginxから返せれば速くなるのかなと思いながら触ってました。
一通りアプリを触ったので、ソースコードの確認に入りました。
ソースコードを見ると、pixiv社の社内向けisuconと同様に画像をMySQLに入れている部分が目に付きました。
予選の環境はDBサーバー1台とAPサーバー2台の構成でした。
画像はMySQLにいれるのを止めてローカルに保存してNginxから返す様にするというのはすぐに思いつきました。
問題はどのサーバーで保存するかというところで少し考えました。
- APサーバーからDBサーバーのMySQLに画像を保存するのを止める
- DBサーバーのローカルに画像を保存する
と考えたときに、DBサーバーのローカルに保存したいならDBサーバーをフロントにして、画像の保存はDBサーバーがやってそれ以外の処理は後ろのAPサーバーに流してあげれば良いんじゃないかと考えてインフラの構成を変更しました。
インフラの変更は id:karia にお願いをして、アプリの改修をしました。
改修内容は下の2つです。
- 画像の登録/更新があったらMySQLには保存せずにローカルに保存する
- 初期にDBに登録されている画像をローカルに書き出しておく
この後ベンチを回したりして動作を確認していたのですが、どうもDBサーバーの負荷が高くフロントと兼任させるのは良くないという事がわかってきました。
ここで、構成を変更することにしました。
次に試した方法は AP1台をフロントにして、フロント・AP・DBがそれぞれ1台づつの構成です。
- フロントサーバーは、追加された画像のローカル保存
- APは、画像処理以外の実行
に担当を分けてみました。
この構成だとDBに余裕ができたので、スコアを上げることができました。
その後は、GET /message
GET /history/:channel_id
のクエリを直したりということをしていました。
結果は予選敗退でしたが、気づきがとても多く参加して良かったと思います。
運営の皆様ありがとうございました。
id:Maco_Tasu, id:karia チームを組んでくれてありがとうございました。
学び/勘違いしていたこと
- DBの接続設定
リクエストごとにコネクションが作られる
def db return @db_client if defined?(@db_client) @db_client = Mysql2::Client.new(
コネクションの使い回しができる
def db return Thread.current[:isuconp_db] if Thread.current[:isuconp_db] client = Mysql2::Client.new(
- MySQLのコネクションがちゃんと閉じられていることを確認するのは大切
javascriptのスプレッド演算子(...)
javascriptで関数を呼び出すところで、引数に ...
と書いているソースコードを見かけるがこれが何か調べてみた。
ES2015から追加された、スプレッド演算子というらしい。
参考
「…」←これ、ただの省略記号かと思ってました。(Spread operatorのお話)|もっこりJavaScript|ANALOGIC(アナロジック)
TypeScript2からのReactとnon-null assertion
TypeScript2からコンパイルオプションの strictNullChecks
で、nullability をチェックできるようになった。
最近になってこのオプションを有効にしたら意外と修正するところが多かったのでメモ。
TypeScript1系の時は↓の様に書いてました。
import * as React from 'react' import * as ReactDom from 'react-dom' interface IAProps { } interface IAState { hoge?: string; fuga?: number; } class A extends React.Component<IAProps, IAState> { constructor(props: IAProps) { super(props); this.state = { hoge: '', fuga: 0 } } render() { return( <B hoge={this.state.hoge} fuga={this.state.fuga} /> ); } } interface IBProps { hoge: string; fuga: number; } interface IBState { } class B extends React.Component<IBProps, IBState> { constructor(props: IBProps) { super(props); this.state = { } } render() { return( <div> {this.props.hoge} <br /> {this.props.fuga} </div> ); } }
TypeScriptでstate管理するときは、毎回全部のパラメータを更新したいわけではないので
interface IAState { hoge?: string; fuga?: number; }
という感じに?
を付けてオプショナルにしていました。
そうすると、stateで管理しているhoge
fuga
の型が
hoge: string | undefined fuga: number | undefined
と、それぞれ undefined
になる可能性があるということになる。
Component B に値を渡すとき、Component B側では
interface IBProps { hoge: string; fuga: number; }
というようにundefined
は許容されないので、
render() { return( <B hoge={this.state.hoge!} fuga={this.state.fuga!} /> );
と!
を付けて、non-nullであることを明示してあげないといけない。
最終的にソースコードはこうなりました。
import * as React from 'react' import * as ReactDom from 'react-dom' interface IAProps { } interface IAState { hoge?: string; fuga?: number; } class A extends React.Component<IAProps, IAState> { constructor(props: IAProps) { super(props); this.state = { hoge: '', fuga: 0 } } render() { return( <B hoge={this.state.hoge!} fuga={this.state.fuga!} /> ); } } interface IBProps { hoge: string; fuga: number; } interface IBState { } class B extends React.Component<IBProps, IBState> { constructor(props: IBProps) { super(props); this.state = { } } render() { return( <div> {this.props.hoge} <br /> {this.props.fuga} </div> ); } }
参考
go言語をインストールしてvimで保存時にコードフォーマットを走らせるまでの設定
Macの環境でgo言語をインストールして、vimでソースコード保存時に自動でコードフォーマットが走るまでの環境設定です。
普段はIDEを使うので、vimでファイル保存時に go fmt
を実行させる設定に手間取ってしまったのでメモしておきます。
※ vim
のプラグイン追加方法がわからなかっただけです。
go言語のインストール
$ brew install go
ここまでで、go言語を書いてコンパイルして実行まではできるようになります。
go言語は標準で go fmt
でコード整形できるのですが、vimでファイル保存時に go fmt
を実行して欲しいのでその設定方法についてです。
vimで go fmt するまでの設定
1. vim-plugをインストールする
$ curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
2. ~/.vimrc
でプラグインを読み込むようにする
~/.vimrc
に下記3行を追加
call plug#begin('~/.vim/plugged') Plug 'fatih/vim-go' call plug#end()
3. vim
をリロードして :PlugInstall
を実行
ここまでの設定で vimでファイル保存時に自動で go fmt
が実行されるようになります。
AWS CloudFormationでECSを管理するときにハマったこと
CloudFormationでECSを構築したときにハマったメモです。
CloudFormationのテンプレートを書いて
あたりの設定をして、構築しました。
動作確認ができたので、AWS::ECS::Service
の設定を更新しました。
更新をしてみたところ、更新中のステータスから一向に進みませんでした。
テンプレートを確認すると、↓のようになっていました。
(下のテンプレートは余分な部分は書いてません)
Service: Type: AWS::ECS::Service Properties: DeploymentConfiguration: MaximumPercent: 100 MinimumHealthyPercent: 50
MaximumPercent: 100
ということで、新しいコンテナを追加できないのに追加しようとして動かない状態でした。
この状態だと、CloudFormationのタイムアウトを設定しないとずっと、更新中のステータスになってしまいます。
管理画面から手動でサービスの更新でタスク数を0にしてあげれば解決できました。
nodeのバージョン管理にnaveを使おうと思ったら上手くいかなかったのでメモ
basherからnaveをインストールしたあと、
$ nave use latest
を実行したところ、nodeのインストールに失敗した。
$ nave cache clear
したら直った
環境
AWS EC2 OS Debian Jessie AMI ami-dbc0bcbc
問題が発生した手順
- basherインストール
- naveインストール
- nodeインストール
basherのインストール
basherのInstallation手順に沿ってインストールした github.com
$ git clone https://github.com/basherpm/basher.git ~/.basher $ echo 'export PATH="$HOME/.basher/bin:$PATH"' >> ~/.bash_profile $ echo 'eval "$(basher init -)"' >> ~/.bash_profile $ bash $ basher update
naveインストール
naveのInstallation手順に従ってインストールした github.com
$ basher install isaacs/nave
nodeインストール(問題が起きたところ)
最新版のnodeを使おうと思い下記コマンドを実行した
$ nave use latest
コマンド結果
What version of node? lts, lts/<name>, latest, x.y, or x.y.z >
ここで latest
と入力してもnodeのインストールは実行されませんでした。
下記の通りキャッシュをクリアしたらインストールできました。
$ nave cache clear $ nave use latest