私的Linux爆速環境
はじめに
SONYのVAIO一体型PCにWindow7とLubuntuDesktopが
入った環境でプログラミングをしてきた。
この環境は悪くはないが、ちょいちょいフリーズするときがある。
もう少し快適にプログラミングしたい。
ハードウェア
中古のThinkpadX230を買った。
ハードの構成的には、
1. CPU Corei5(2.6GHz)
2. SSD 250GB
3. メモリ 8GB
PCの立ち上がりが早い。
起動中もザックザックに早く動く。
フリーズすることもない。
これらがSSDのおかげなのか、メモリ8GBのおかげなのかはわからない。
ただ、とにかく早い。
ソフトウェア
ソフトウェアは以下のような構成にした。
OS Ubuntu Server
ThinkpadにはもともとWindows10が入っていたが、全て削除。
デュアルブートはもうやめて、Ubuntu Server一本でいくことにした。
Ubuntu ServerはGnomeやUnityなどのデスクトップ環境なしでCUI環境のみでインストール。
そこからXwindow Systemを追加で入れる。
なるべく余計なものを入れずに、やっていきたい。
今のところ、40GB/250GBくらいのディスク消費量で済んでいる。
ウィンドウマネージャ i3wm
もともとVAIOでもタイル型のウィンドウマネージャi3wmを使っていた。
引き続きこれを使う。
もうウィンドウがかぶって、うあああアアってなることもない。
~/.config/i3/configに書く設定も簡単に書ける。
i3wmの公式ドキュメントとこの方のブログの情報でほとんど設定できる。
ターミナルエミュレータ Gnome Terminal
とくにこだわりはない。
シェル fish shell
一時期zshを使っていたが、遅かったので使うのを止めた。
そこからるびきち氏のページを見て、fishに乗り換えた。
しかし、これが良い判断だったのかはわからない。
やっぱりいまだにWEB上にはbashの情報が多い。
fishの文法に慣れていないので、ちょっとした作業でつまずくことがある。
あと、そもそもLinuxはbashを前提にして成り立っているのでbashなしというわけにはいかない。
エディタ Spacemacs
emacsベースで最近注目のエディタ。
emacsの拡張性を引き継ぎつつも、UIは本家よりも格好良い。
Spaceキーから始まるキーバインドが初心者にも優しい。
編集時はvimのキーバインドでなんとかやっている。
こちらもfish同様、まだまだ全ての機能を活かせていない。
ブラウザ vivaldi
もともとFirefoxを使っていた。
vimperatorを使っていたからだ。
しかし、Quantumくらいからvimperatorが使えなくなるというので、
Firefoxを泣く泣く諦めることにした。
特にこだわりがなければChromeでいいと思うが、天邪鬼なのでvivaldiにしている。
vivaldiはChromiumベースのブラウザ。
タブタイリングなどのChromeにはない便利な機能が入っている。
アドオンはvimiumを使っている。
しかし、vimperatorの方がいろいろと良かった。
終わりに
もっとミニマルな構成にしようと思えば、多分できるのだと思う。
OSをArchLinuxにしたり、エディタを生Vimにしたりするやり方もある。
ただ、Archでイチから環境を組み立てていくほど、私は潔癖なミニマリストにはなりえない。
一日で従来の環境をなるべく変えずに、いかにミニマルな環境を構築するかという点ではなかなか上出来だったと思う。
やっぱり開発環境が快適かどうかは、作業の効率に影響を及ぼす。
フリーズは開発のリズムを壊すのである。
Ubuntuやi3wmなどの設定は他のブログの情報でできると思うので、
そちらに丸投げさせていただいて今回は終わらせていただく。
WEB開発の門外漢がReactでお試しSPAを作成する
作成前
今までPythonでデータ分析とかスクレイピングのためのプログラムは書いてきた。
でも、WEB開発はあまりやってこなかった。
自分で何かWEBサービスを作ってみたいという思いがむくむくと湧いてきた。
少しずつWEB開発をやっていこう。
とりあえずサーバーサイドは脇に置いて、フロントエンドから取り掛かろう。
道具の選択
Javascriptのフロントエンドライブラリは、無難にReactを選択する。
React Nativeもあるので、将来的にはスマホアプリへの広がりも少し期待した。
いきなりゴリゴリと本格的にサービスを開発するわけにもいかない。
まずは何か見本ページをパクっ...真似てReactに慣れよう。
ここにReactで作成したWEBアプリがたくさんあるので、その中からこれを真似る。
CSSフレームワークはBootstrapが使われているようだ。
何作る
まんま見本サイトをパクってロボットの写真を使うのは趣がない。
ジャズのプレイヤーの写真に差し替えてみよう。
ジャズマン名鑑のようなものを作ろう。
何やりたい
「ページを変えた時に画面全体を再描画するのではなく、パネル内の文字と写真だけを描画する」という機能を実装してみたい。
実際に試作してみたSPAはこちら。
手を付けなかったもの
ゆくゆくは使ってみないといけないだろうが、今回は小規模な開発なのでFluxやReduxは使わない。
また、サーバー部分はとりあえず脇に置いているので、AWSとかは使わない。
デプロイがとても簡単にできるGithub Pagesを使う。
詰まったところ
作業はReact公式やReact本、Web上の情報を収集すれば、大体進めていける。
とはいえ、「現在のページをどのように管理するか、またページが変わったことをどのようにパネル部分のコンポーネントに伝えるか」で詰まった。
どうやら、この部分はReactでアプリを構築していく上で基礎の部分であり、これをきちんと理解できていないとWebアプリっぽい機能は全く実装できないようだ。
ページ管理
そもそもどのようにページを管理したいいのかが分からない。
React-Bootstrapの公式を眺めた。
どうやら、今何ページ目が開かれているかはコンポーネントが持つ内部状態で管理するらしい。
ちなみにコンポーネント間のデータの受け渡しについては、こちらのページに詳しく書いてある。
以下の手順でデータの受け渡しをやる。
- ページネーションのボタンがクリックされる。
- ページが変更されたことを、ページネーションの子コンポーネントからをページを管理している親コンポーネントに通知する
- 通知を受け、親コンポーネントが内部状態として持っている「activePage」を書き換える
- 親コンポーネントからパネル部分の子コンポーネントへページが変更されたことを通知する
- 変更されたページに属するジャズマンの写真と名前を描画する
親コンポーネントと子コンポーネント間の連携
Pageのコンポーネントと親コンポーネントの連携は以下のように行う。
- React-Bootstrapの
Pagination
コンポーネントを子コンポーネントとして配置 - 親コンポーネントのメソッドとして
activePage
を書き換えるイベントハンドラを定義 - そのイベントハンドラを
this.props
経由でPagination
コンポーネントへと渡し、onSelect
属性に代入
また、写真を描画するItems
コンポーネントの方と親コンポーネントの連携は以下のように行う。
親は以下のようなコードになる。
class Center extends Component { constructor(props) { super(props) this.state = { //ここで現在のページ数を管理する activePage: 1 } } //ページ数を書き換えるメソッド updateActivePage (e) { this.setState({activePage: e}) } render () { const activePage = this.state.activePage const updateActivePage = (e) => this.updateActivePage(e) return ( <Grid className="container-fluid"> <Title /> <Page activePage={activePage} //このようにしてPageコンポーネントにupdateActivePageを渡す updateActivePage={updateActivePage} /> //ItemコンポーネントにacitivePageの値を渡す <Items page={activePage} /> <Page activePage={activePage} //このようにしてPageコンポーネントにupdateActivePageを渡す updateActivePage={updateActivePage} /> </Grid> ) } }
ちなみに、子のPage
コンポーネントのこのようになっている。
Item
コンポーネントの方も値の受け取り方は同じである。
render(){ const pageNumber = Math.ceil(this.getPageNum() / 12) //親から受け渡されたupdateActivePage()はこのように受け取る。 const updateActivePage = this.props.updateActivePage return ( <Pagination prev next first last ellipsis boundaryLinks items={pageNumber} activePage={this.props.activePage} //SelectイベントによってactivePageを書き換えるようupdateActivePage()をセットする。 onSelect={(e) => updateActivePage(e)} />) }
最後に
SPAを作成したと言っても、これはまだ試作段階なので、不十分な点が色々とある。
色々と作っていって、Reactに早く慣れていきたい。
ClosedXMLによるExcelの操作・その1
とりあえずClosedXMLを使う
今回はC#でExcelを操作します。 C#ではNPOI、NetOffice、EPPlusといったパッケージや、.NET FrameworkからCOMコンポーネントを使ってExcelを操作することができます。 ここでは ClosedXML というパッケージを使ってみたいと思います。 現段階ではどの方法が最も効率がいいかということは分かりませんが、ネット上の「ClosedXMLが直観的で使いやすい」という情報をもとにClosedXMLを選択した次第です。
ちなみに、COMコンポーネントを使う方法については、リソースを開放するコードを自分で実装しないといけないので、いくらか手間がかかってしまいます。 しかし、ClosedXMLではできないが、COMならできることもありますので(チャートの挿入など)、いずれはCOMコンポーネントを触らなければならない状況も出てくると思われます。 ま、それはともかく、以下にずらずらっと実行コードを並べていきたいと思います。
実行コード
- using部分
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using ClosedXML.Excel;
- ワークブックを開き、ワークシートを追加し、特定のセルに値を代入
var workbook = new XLWorkbook(); var ws = workbook.Worksheets.Add("WorksheetName"); ws.Cell("A1").Value = "Hello World!";
- ワークブックを保存
workbook.SaveAs("Workbook.xlsx");
- 特定の範囲を指定し、その範囲内のセルでは入力した数字を円単位で表示
var range = ws.Range("B2:B100"); range.Style.NumberFormat.Format = " #,##0 円";
- プルダウンリストからセルに入力できるようにする
var namelist = new string[] { "高橋幸宏", "坂本龍一", "細野晴臣" }; string join = string.Join(",", namelist); string insertstring = $"\"{join}\""; var cell = ws.Cell(1, 1); cell.DataValidation.List(insertstring);
- 隠れた形でコメントを挿入する
ws.Cell("A1").Comment .SetAuthor("Taro") .AddSignature() .AddText("Hello!");
- 見える形でコメントを挿入する
ws.Cell("A1").Comment.SetVisible() .SetAuthor("Hanako") .AddSignature() .AddText("Good Night!");
- 「値が100以上なら背景を赤色にする」という条件付き書式を設定
ws.Range("C2", "C100").AddConditionalFormat().WhenGreaterThan(100) .Fill.SetBackgroundColor(XLColor.Red);
終わりに
今回はClosedXMLを使ってC#から、基本的なExcel操作をするコードを載せてみました。 ClosedXMLの使い方はgithubのwikiに掲載されていて、ここを見ればやりたいことは大体できるのではないでしょうか。 日本語・英語を含めて、結構ググれば情報は見つかりますし、ちょっとC#からExcelをいじってみたいなという人にはいいと思います。
また、図表の挿入などやりたいことを一通り試した後、簡単な入力フォームを作成したら、記事をUPしてみたいと思います。
ConohaVPSでのCentOSサーバーの設定手順(ssh編)
はじめに
以前にConohaVPSを契約してましたが、完全に放置していて毎月財布から英世が消えていくのはもったいない… ということで、CentOS上にWEBサーバーを立ててみることにしました。 ひとまず、LAMP環境を構築することを当面の目標にしたいと思います。
今回の記事はssh編ということで、sshでリモートホストにログインするところから始めて、最終的にはセキュリティ的にあまり心配のないssh設定をするところまで行いたいと思います。 (とはいえ、どこまでやればセキュリティ的に心配ないかは各人次第です。よりセキュアな設定をしたい方はググれば、他の対策も出てきますので、そちらも参考にしてください。)
Conohaの管理画面
いきなりですが、ConohaのVPS契約から管理画面上の操作は割愛させてください…
サーバーを追加すると、様々な設定項目がありますが、この記事では2017/7/4現在で最も新しいCentOSを使い、またsshでは公開鍵認証でのログインをデフォルトにしました。 途中で、公開鍵認証で使う秘密鍵をダウンロードできますので、しておきます。 また、設定したrootパスワードも使用しますので、記録しておきましょう。 さらに、サーバーを追加すると、IPアドレスやMACアドレスなどのサーバー情報を見ることができますので、IPアドレスをメモしておくとよいかと思います。
ログイン
まずは、ローカルPC上のホームフォルダに.sshディレクトリを作成し、ダウンロードした秘密鍵をそこに移動させます。
mkdir .ssh mv /path_to_pem/123456789.pem .ssh
次に、以下のコマンドで、リモートサーバーにsshでrootログインします。 xxx.xxx.xxx.xxxのところには、リモートサーバーのIPアドレスを入力します。
ssh root@xxx.xxx.xxx.xxx -i ~/.ssh/123456789.pem
一般ユーザーの追加とそのユーザーのwheelグループへの追加
次に、リモートサーバ上でrootとは別の一般ユーザー を追加します。 さらに、そのユーザのパスワードを設定し、さらにユーザをwheelグループに追加します。
useradd <username> passwd <username> gpasswd -a <username> wheel
wheelグループにsudoを許可
wheelグループに属する一般ユーザーがsudoコマンドを使えるようにします。 先ほど一般ユーザをwheelグループに追加したのは、そのためです。
visudo
//この行の#を消す
#%wheel ALL=(ALL) ALL
suコマンドの実行はwheelグループのみに
suを利用すると、ユーザーを切り替えることができます。 もちろん、rootユーザに切り替えることも可能です。 しかし、rootユーザに切り替える必要のない一般ユーザーがsuを使えるようにしておくと、何かのときにroot権限に移行し、変なことをしでかすかもしれません。 そこでwheelグループ以外からはsuコマンドを実行できないようにします。
vi /etc/pam.d/su
//この行の#を消す
#auth required pam_wheel.so use_uid
.sshディレクトリとauthorized_keysファイルの所有者とパーミッションの変更
ここからはsshの設定をしていきます。 まずは、sshを使って先ほど作成した一般ユーザでログインできるように設定します。
一般ユーザのホームディレクトリに.sshディレクトリを作成し、/root/.ssh内にあるauthorized_keysをそこにコピーします。 (authorized_keysファイルは、個別の公開鍵を登録しておくファイルです) 次に、今作成した.sshディレクトリとコピーしたauthorized_keysファイルのパーミッションを変更します。 どのパーミッションが本当に適切なのかが自分の中でまだはっきりとしていませんが、WEB上では
という情報が多かったので、とりあえずはそれに従います。 これらのパーミッションが適切でないと、あとでリモートログインするときにdenyされます。
mkdir /home/<username>/.ssh cp .ssh/authorized_keys /home/<username>/.ssh/authorized_keys chown <username>:<username> /home/<username>/.ssh chown <username>:<username> /home/<username>/.ssh/authorized_keys chmod 700 /home/<username>/.ssh chmod 600 /home/<username>/.ssh/authorized_keys
sshに関するセキュリティ設定
sshは悪い人達(bot達?)に標的にされやすいです。 (自分も設定が一区切りついたところで、/var/log/secureを見てみました。サーバー作成してからまだ数時間だというのに、mysqlやらadminやらの名前でログインしようとする鬼畜が….) ですので、sshで不正ログインされないようにきっちりと設定しなければなりません。 そこで、/etc/ssh/sshd_configを編集して、以下のような設定を行っていきます。
sudo vi /etc/ssh/sshd_config
- ポート番号を22から変更する
- sshを使ってrootユーザーでログインできないようにする
- sshのパスワード認証を切る
- ssh可能ユーザーを限定
- sshdのプロトコルを2に
- 認証の試行回数、認証までの猶予時間の制限
自白すると、これらの設定は下のページを参考にさせてもらいました。 あーざっす! ですので、そちらを参考に設定してください。
参考:そこそこセキュアなサーバ
参考:ConohaとCentOS
一つだけ追加しておくと、ポート番号はsshdの設定ファイルで変えても、CentOSのファイアーウォールデーモンであるfirewalldではまだ22番のままなので、こちらも変更しておかなければなりません。
cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh.xml sed -e s/22/<変更するポート番号>/g /etc/firewalld/services/ssh.xml > /etc/firewalld/services/ssh.xml1 cat /etc/firewalld/services/ssh.xml1 mv /etc/firewalld/services/ssh.xml1 /etc/firewalld/services/ssh.xml
おわりに
とりあえず、ssh周りはこれで終わりたいと思います。 この次は、不要なサービスを止めたり、不要なポート閉じたり、firewalldでネットワークの流れを制御したりしていきます。
Vagrantで作るLAMP環境
はじめに
この記事では、「vagrant upと一発叩いて、LAMP環境(Apache + MySQL + PHP入りのCentOS)を起動させる」ことを目指します。 まずは、CentOS上にApache + MySQL + PHP(AMP)を導入していきます。 その次に、そのAMP入りの環境をBoxファイルにして保存するという流れです。
LAMPを入れるシェルスクリプトを書く
ここでは、vagrantとvirtualboxの導入する部分を一気に省いて(!)、それらが既に導入されているところから始めさしてください。
Vagrantでは、vagrant upと叩けば、現在のディレクトリのVagrantfileの設定を読みます。 Vagrantfileには様々な設定が書けますが、一番下のセクションに起動時に実行するシェルスクリプトを指定できる箇所があります。 それは、
config.vm.provision "shell", :path => "lamp.sh"
の部分です。 例えば、上のように書けば、vagrant upで仮想マシン上のOS起動した時にlamp.shが実行されます。 ですので、lamp.sh内にAMP導入のためのコマンドを書いておけば、vagrant upでAMPを入れてくれるというわけです。 この部分はAnsibleやChefなどの構成管理ツールでもできるそうです。 (早くAnsible覚えたい)
lamp.shをどのように書くかは各自の好みによるでしょう。 パッケージからAMPをとってきてもいいし、ソースコードからビルドしてもよいと思います。 私はこちらのブログを参考にさせていただいて、ソースコードからビルドしました。 そんでもって、lamp.shは以下のような内容になりました。
# basis yum -y install wget yum -y groupinstall development base # Mysql wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm rpm -ihv mysql57-community-release-el7-11.noarch.rpm yum repolist yum -y install mysql-server mysql-devel #OpenSSL yum -y install zlib-devel perl perl-core cd /usr/local/src/ wget https://www.openssl.org/source/openssl-1.1.0f.tar.gz tar xvzf openssl-1.1.0f.tar.gz cd openssl-1.1.0f/ ./config --prefix=/usr/local/openssl-1.1.0f shared zlib make depend make make test make install echo /usr/local/openssl-1.1.0f/lib > /etc/ld.so.conf.d/openssl110f.conf ldconfig # Nghttp2 yum -y install libev-devel c-ares-devel cd /usr/local/src/ wget https://github.com/nghttp2/nghttp2/releases/download/v1.23.1/nghttp2-1.23.1.tar.gz tar xvzf nghttp2-1.23.1.tar.gz cd nghttp2-1.23.1/ env OPENSSL_CFLAGS="-I/usr/local/openssl-1.1.0f/include" OPENSSL_LIBS="-L/usr/local/openssl-1.1.0f/lib -lssl -lcrypto" ./configure -enable-app make make install echo /usr/local/lib > /etc/ld.so.conf.d/usr-local-lib.conf ldconfig # Apache ## APR cd /usr/local/src/ wget http://ftp.jaist.ac.jp/pub/apache//apr/apr-1.6.2.tar.gz tar xvzf apr-1.6.2.tar.gz cd apr-1.6.2/ ./configure make make install ## ARP-util yum -y install expat-devel pcre-devel cd /usr/local/src/ wget http://ftp.jaist.ac.jp/pub/apache//apr/apr-util-1.6.0.tar.gz tar xvzf apr-util-1.6.0.tar.gz cd apr-util-1.6.0/ ./configure --with-apr=/usr/local/apr make make install echo finARP-util ## Apache cd /usr/local/src/ wget http://ftp.riken.jp/net/apache//httpd/httpd-2.4.26.tar.gz tar xvzf httpd-2.4.26.tar.gz cd httpd-2.4.26/ ./configure \ --enable-http2 \ --enable-ssl \ --with-ssl=/usr/local/openssl-1.1.0f \ --enable-so \ --enable-mods-shared=all \ --enable-mpms-shared=all make make install #PHP yum -y install libxml2-devel libjpeg-devel libpng-devel wget http://jp2.php.net/get/php-7.1.6.tar.gz/from/this/mirror -O php-7.1.6.tar.gz tar -zxvf php-7.1.6.tar.gz cd php-7.1.6 ./configure --enable-mbstring --with-apxs2=/usr/local/apache2/bin/apxs --enable-pdo --with-gd --with-png-dir=/usr/local --with-jpeg-dir=/usr/local --with-mysql make make install
おそらく2017/6月末時点では最新のAMPを導入できたと思います。 ソースコードはその時々で新しいものと変わっていると思うので、適宜lamp.shを書き換えてやってください。
それが書けたら、vagrant upしてみましょう。 恐らく、OSが起動し、その後lamp.shが実行されます。 結構時間がかかるので、コーラをすすって気長に待ちましょう。 それが終わったら、サービスを起動したり、各サービスの設定を行いましょう。
LAMP導入済みのBoxファイルを作る
vagrantでは、Boxファイルさえあれば、いくつでも同じ環境を構築できますし、違うPCにその環境を持ち運びすることもできます。 ですので、ある程度LAMP環境が整ったら、次はBoxファイルを作成していきましょう。 Boxファイルの作成は難しいと思いきや、とても簡単です。
vagrant package default --output lamp.box
でlamp.boxというファイルが作成されます。 その後、
vagrant box add lamp lamp.box
とすれば、lamp.boxが使用可能になります。
mkdir lamp && cd lamp vagrant init lamp
としてlampディレクトリにVagrantfileを作成します。(Vagrantfileの中身を確認して必要ならば書き換えてください) 最後に、
vagrant up
でAMP入りのCentOSを起動します。 これ以降は「vagrant upと一発叩けば、LAMP環境(Apache + MySQL + PHP入りのCentOS)が起動する」ことができます。
終わりに
Vagrantはそれほど学習コストをかけることなく、手軽に環境構築の自動化や持ち運びを可能にしてくれます。 仮想環境構築ツールは色々ありますが、まずはVagrantでお手軽にやってみるというのがいいかもしれません。