ゆきばた のBlog

備忘録と備忘録。あと備忘録。

Pandas の ファイル書き込みサンプル一覧

DataFrame のデータを各種ファイルに書き出すサンプルと
そのオプションをまとめる。

こんな感じのデータを書き込んでいく

No team Number name kana position born
1 Swallows 1 Yamada 山田 内野手 1992/7/16
2 Eagles 3 Asamura 浅村 内野手 1990/11/12
3 Carp 4 Kikuchi 菊池 内野手 1990/3/11
4 Giants 6 Sakamoto 坂本 内野手 1988/12/14
5 Fighters 8 Kondo 近藤 外野手 1993/8/9
6 Carp 51 Suzuki 鈴木 外野手 1994/8/11
7 Giants 10 Kobayashi 小林 捕手 1989/6/7
8 Eagles 11 Kishi 投手 1984/12/4
9 Baysters 19 Yamasaki 山崎 投手 1992/10/2
10 Buffaloes 43 Yamamoto 山本 投手 1998/8/17

まずは基本形

df_data.to_csv('./output/baseball.csv')
f:id:yukibata:20200727230432p:plain
オプション指定なし

 

「ファイル形式」を指定したい

csvファイル

df_data.to_csv('./output/baseball.csv')

tsvファイル

df_data.to_csv('./output/baseball.tsv', sep='\t')

excelファイルに書き出し

df_data.to_excel('./output/baseball.xlsx', sheet_name='players')

※ sheet_name を省略すると Sheet1 で書き出し

「文字コード」を指定したい

UTF-8

df_data.to_csv('./output/baseball.csv', encoding='utf_8')

shift-jis

df_data.to_csv('./output/baseball.csv', encoding='shift_jis')

cp932

df_data.to_csv('./output/baseball.csv', encoding='cp932')

 

「行」の操作をしたい

header なし(カラム名なし)

df_data.to_csv(
    './output/baseball.csv',  # ファイル名
    header=False              # header なし
)
f:id:yukibata:20200727231647p:plain
元のファイル
f:id:yukibata:20200727231703p:plain
heaerなしファイル

 

「列」の操作をしたい

index なし

df_data.to_csv(
    './output/baseball.csv',  # ファイル名
    index=False               # header なし
)
f:id:yukibata:20200727231935p:plain
元のファイル
f:id:yukibata:20200727231948p:plain
indexなしファイル

 

追記モードで出力したい

追記モードで出力

df_data.to_csv(
    './output/baseball.csv',  # ファイル名
    header=False,             # header なし
    mode='a'                  # 追記モード
)

※ header=False を指定しないと header も追記される
※ デフォルトは mode='w' (上書き)

Pandas の データ読み込みサンプル一覧(csv, tsv, オプション)

CSVデータなどのファイルからデータを読み込み DataFrame に格納する方法と
そのオプションをまとめる。

こんな感じのデータを用意

No team Number name kana position born
1 Swallows 1 Yamada 山田 内野手 1992/7/16
2 Eagles 3 Asamura 浅村 内野手 1990/11/12
3 Carp 4 Kikuchi 菊池 内野手 1990/3/11
4 Giants 6 Sakamoto 坂本 内野手 1988/12/14
5 Fighters 8 Kondo 近藤 外野手 1993/8/9
6 Carp 51 Suzuki 鈴木 外野手 1994/8/11
7 Giants 10 Kobayashi 小林 捕手 1989/6/7
8 Eagles 11 Kishi 投手 1984/12/4
9 Baysters 19 Yamasaki 山崎 投手 1992/10/2
10 Buffaloes 43 Yamamoto 山本 投手 1998/8/17

 

まずは基本形

import pandas as pd

# Data 読み込み
df_data = pd.read_csv('./input/baseball.csv')

# Data 確認
df_data.head()
f:id:yukibata:20200726230405p:plain
df_data.head()

 

「ファイル形式」を指定したい

csv ファイル

df_data = pd.read_csv('./input/baseball.csv')
df_data.head()

tsv ファイル

df_data = pd.read_csv('./input/baseball.tsv', delimiter='\t')
df_data.head()

Excel ファイル

df_data = pd.read_excel('./input/baseball.xlsx', sheet_name='Sheet1')
df_data.head()

※ sheet_name を指定しない場合は、先頭のシート

 

「文字コード」を指定したい

UTF-8

df_data = pd.read_csv('./input/baseball.csv', encoding='utf_8')
df_data.head()

shift_jis

df_data = pd.read_csv('./input/baseball.csv', encoding='shift_jis')
df_data.head()

cp932

df_data = pd.read_csv('./input/baseball.csv', encoding='cp932')
df_data.head()

 

「行」の操作をしたい

Header を無視
Headerのないファイルに使用します。
Headerがあるファイルの場合、Headerもデータとして認識されます。

df_data = pd.read_csv('./input/baseball.csv', header=None)
df_data.head()
f:id:yukibata:20200726234143p:plain
元のデータ
f:id:yukibata:20200726231818p:plain
Header なし

行をSkipして読み込み
header=None も同時に指定しないと、SKIPした次の行が Header になってしまいます。

df_data = pd.read_csv('./input/baseball.csv', header=None, skiprows=3)
df_data.head()
f:id:yukibata:20200726234143p:plain
元のデータ
f:id:yukibata:20200726232122p:plain
Headerなし・3行SKIP


行を先頭から切り取る

df_data = pd.read_csv('./input/baseball.csv', nrows=3)
df_data.head()
f:id:yukibata:20200726234143p:plain
元のデータ
f:id:yukibata:20200726232707p:plain
先頭3行を切り取った例

 

「列」の操作をしたい

指定した列番号を切り取る

df_data = pd.read_csv('./input/baseball.csv', usecols=[0, 1, 4])
df_data.head()
f:id:yukibata:20200726234143p:plain
元のデータ
f:id:yukibata:20200726233632p:plain
0列目、1列目、4列目 を取得


指定した列(カラム名)を切り取る

df_data = pd.read_csv('./input/baseball.csv', names=['No.', 'team', 'kana'])
df_data.head()
f:id:yukibata:20200726234143p:plain
元のデータ
f:id:yukibata:20200726233817p:plain
カラム名で取得

 

index の操作をしたい

指定したカラムを index にする

df_data = pd.read_csv('./input/baseball.csv', index_col=['number']) # number を index にする
df_data.head()
f:id:yukibata:20200726234143p:plain
元のデータ
f:id:yukibata:20200726234156p:plain
number を index にしたデータ

scikit-learn から取得できるpythonサンプルデータの種類

データ分析を始めたり、グラフや関数の動作を試したいとき、サンプルデータが必要になります。「いますぐ試したい」のに、サンプルデータの生成は時間がもったいないです。
scikit-learn (sklearn) には「いますぐ使えるデータ」が load できるようになっています。

sklearn のサンプルデータ 7種類を、すぐに import して使える形で準備しました。

 

本家はこちら(英語)- サンプルデータ全7種類

以下のバージョンでは、7種類のデータの取得が可能です
scikit-learn.org

scikit-learn version 0.23.1 

 

サンプル1:load_boston - ボストンの住宅価格データ

ボストンの住宅価格と、関連する環境項目のデータセット。

scikit-learn.org


説明変数

データ件数:506
カラム数:13

CRIM 都市別の1人当たり犯罪発生率
ZN 25,000平方フィート以上の住宅地の割合(広さ)
INDUS 非小売業が占める面積の割合
CHAS Charles川のダミー変数(1:河川の周辺; 0:その他)
NOX 一酸化窒素濃度(1000万分の1)
RM 一戸当たりの平均部屋数
AGE 1940年以前に建てられた持ち家の割合
DIS ボストンの5つの雇用センターまでの距離(加重あり)
RAD 高速道路へのアクセスのしやすさ指数
TAX 1万ドル当たりの総資産税率
PTRATIO 町別の児童教師比率
B Bkの割合
LSTAT 低所得者の割合
import pandas as pd

# データ読み込み
from sklearn.datasets import load_boston
boston = load_boston()

# dataframe化
df_boston = pd.DataFrame(boston.data, columns=boston.feature_names)
df_boston.head()
f:id:yukibata:20200726001902p:plain
df_boston.head()

目的変数

住宅価格の中央値

df_target = pd.DataFrame(boston.target, columns=['target'])
df_target.head()
f:id:yukibata:20200726002001p:plain
df_target.head()

 

サンプル2:load_iris - アヤメ(花)の品種データ

アヤメの各部位の特徴によって、品種を特定するデータセット。
機械学習では最も有名なサンプルデータかもしれません。

scikit-learn.org


説明変数

データ件数:150
カラム数:4

sepal length (cm) がく片の長さ(cm)
sepal width (cm) がく片の幅(cm)
petal length (cm) 花弁の長さ(cm)
petal width (cm) 花弁の幅(cm)
import pandas as pd

# データ読み込み
from sklearn.datasets import load_iris
iris = load_iris()

# dataframe化
df_iris = pd.DataFrame(iris.data, columns=iris.feature_names)
df_iris.head()
f:id:yukibata:20200726131016p:plain
df_iris.head()

目的変数

アヤメ品種の番号

df_target = pd.DataFrame(iris.target, columns=['target'])
df_target.head()
f:id:yukibata:20200726002504p:plain
df_target.head()

 

サンプル3:load_diabetes - 糖尿病患者の属性データ

基礎データ(性年代など)、血液データなどで、疾患予測を行うデータセット。

scikit-learn.org


説明変数

データ件数:442
カラム数:10

age 年齢
sex 性別
bmi BMI 肥満指数
bp 血圧の平均
s1 tc : T細胞(白血球の一種)
s2 ldl : 低密度リポタンパク質
s3 hdl : 高密度リポタンパク質
s4 tch : 甲状腺刺激ホルモン
s5 ltg : ラモトリギン
s6 glu : 血糖値
import pandas as pd

# データ読み込み
from sklearn.datasets import load_diabetes
diabetes = load_diabetes()

# dataframe化
df_diabetes = pd.DataFrame(diabetes.data, columns=diabetes.feature_names)
df_diabetes.head()
f:id:yukibata:20200726003051p:plain
df_diabetes.head()

目的変数

病状の進行状況

df_target = pd.DataFrame(diabetes.target, columns=['target'])
df_target.head()
f:id:yukibata:20200726003139p:plain
df_target.head()

サンプル4:load_digits - 手書き文字(数字)認識

手書きの文字(0~9の1文字)が数値化されているデータセット。
1つの画像のデータが64(8×8)マスのデータとして表現されている。

scikit-learn.org


説明変数

データ件数:1797 (デフォルト値 n_class=10 のとき)
カラム数:64

import pandas as pd

# データ読み込み
from sklearn.datasets import load_digits
digits = load_digits(n_class=10) # default = 10

# dataframe化
df_digits = pd.DataFrame(digits.data)
df_digits.head()
f:id:yukibata:20200726131210p:plain
df_digits.head()
import matplotlib.pyplot as plt
plt.imshow(digits.images[0], cmap='Greys', interpolation='NONE')

f:id:yukibata:20200726131257p:plain

目的変数

データが表現する数字

df_target = pd.DataFrame(digits.target, columns=['target'])
df_target.head()
f:id:yukibata:20200726131517p:plain
df_target.head()

サンプル5:load_linnerud - 身体的特徴と身体的能力の関連性

身体的な特徴と能力(体重とジャンプ力の関係性など)をまとめたデータセット。

scikit-learn.org


説明変数

データ件数:20
カラム数:3
※ 目的変数のカラム数:3

Chins 懸垂
Situps 腹筋
Jumps 跳躍

※単位不明

import pandas as pd

# データ読み込み
from sklearn.datasets import load_linnerud
linnerud = load_linnerud()

# dataframe化
df_linnerud = pd.DataFrame(linnerud.data, columns=linnerud.feature_names)
df_linnerud.head()
f:id:yukibata:20200726133121p:plain
df_linnerud.head()

目的変数

Weight 体重
Waist ウエスト
Pulse 脈拍
df_linnerud_target = pd.DataFrame(linnerud.target, columns=linnerud.target_names)
df_linnerud_target.head()
f:id:yukibata:20200726133252p:plain
df_linnerud_target.head()

サンプル6:load_wine - ワインの品質を示すデータセット。

ワインの成分などの特徴と品質を関連させたデータ。

scikit-learn.org


説明変数

データ件数:178
カラム数:13

alcohol アルコール度数
malic_acid リンゴ酸
ash 灰(あく)
alcalinity_of_ash 灰のアルカリ度
magnesium マグネシウム量
total_phenols 総フェノール
flavanoids フラボノイド
nonflavanoid_phenolsv 非フラボノイド・フェノール
proanthocyanins プロアントシアニン
color_intensity 色の明度
hue 色相
od280/od315_of_diluted_wines 希釈ワイン
proline プロリン
import pandas as pd

# データ読み込み
from sklearn.datasets import load_wine
wine = load_wine()

# dataframe化
df_wine = pd.DataFrame(wine.data, columns=wine.feature_names)
df_wine.head()
f:id:yukibata:20200726135100p:plain
df_wine.head()

目的変数

ワインの品質

df_wine_target = pd.DataFrame(wine.target, columns=['target'])
df_wine_target.head()
f:id:yukibata:20200726135157p:plain
df_wine_target.head()

サンプル7:load_wine - ワインの品質を示すデータセット。

ワインの成分などの特徴と品質を関連させたデータ。

scikit-learn.org


説明変数

データ件数:569
カラム数:30

mean radius 平均半径
mean texture 平均組織
mean perimeter 平均周長
mean area 平均面積
mean smoothness 平均平滑度
mean compactness 平均コンパクト性
mean concavity 平均凹面
mean concave points 平均凹点
mean symmetry 平均対称性
mean fractal dimension 平均フラクタル次元
radius error 半径誤差
texture error テクスチャエラー
perimeter error 周辺誤差
area error 面積誤差
smoothness error 平滑度誤差
compactness error コンパクト性誤差
concavity error 凹面誤差
concave points error 凹点誤差
symmetry error 対称誤差
fractal dimension error フラクタル次元誤差
worst radius 半径の最悪数値
worst texture 組織の最悪数値
worst perimeter 外周の最悪数値
worst area 表面積の最悪数値
worst smoothness 滑らかさの最悪数値
worst compactness コンパクトさの最悪数値
worst concavity 最悪な陥没度合
worst concave points 最悪な凹点
worst symmetry 対称性の最悪数値
worst fractal dimension フラクタル次元の最悪数値
import pandas as pd

# データ読み込み
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()

# dataframe化
df_cancer = pd.DataFrame(cancer.data, columns=cancer.feature_names)
df_cancer.head()
f:id:yukibata:20200726140435p:plain
df_cancer.head()

目的変数

df_cancer_target = pd.DataFrame(cancer.target, columns=['target'])
df_cancer_target.head()
f:id:yukibata:20200726140750p:plain
df_cancer_target.head()

以上が、scikit-learn で簡単に import 可能なデータサンプル7つ。

Centos7とPHP7 の LAMP環境を構築する(ApacheのPathは /usr/local/apache/ で)

技術系記事です

yum を使って簡単に開発環境が構築できる現代で、
毎回2,3か所くらい詰まって解決するのが面倒だったので、手順をまとめました。

これで1発OKなはず。

 

◆前提◆
vagrant で centosが立ち上がっていることを前提としています

◆ゴール◆
local.xxxxx.com などの独自ドメインで phpinfo() が動くこと
apache のパスが /usr/local/apache/ であること
(ソースからapacheをインストールしていた時代のパスのが未だに慣れているため)

 

 

0.事前準備

yumのアップデートを行います

# sudo su root
# yum -y update

1.Apacheのインストール

centOS7 では、2.4がデフォルトみたいです

### apache のインストール
# yum -y install httpd

## vesionの確認
# httpd -v

## サービスの設定と起動
# systemctl enable httpd
# systemctl restart httpd

2. MySQL のインストール

### 事前にリポジトリの追加
# yum -y localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm

### MySQL のインストール
# yum -y install mysql-community-server

### version確認
# mysqld --version

### サービス設定と起動
# systemctl enable mysqld.service
# systemctl restart mysqld.service

### passwordの取得
# cat /var/log/mysqld.log | grep "temporary password"
-----------------------------------------------------------------------
2017-06-17T07:05:30.855638Z 1 [Note] A temporary password is generated for root@localhost: {初期パスワード}
-----------------------------------------------------------------------

### passwordの設定(上の{初期パスワード}を使用)
# mysql_secure_installation

### passwordの有効期限設定(デフォルト1年なので、以下を追記して無期限にします)
# vi /etc/my.cnf
-----------------------------------------------------------------------
default_password_lifetime=0
-----------------------------------------------------------------------

### 再起動
# systemctl restart mysqld
 

3. PHP7インストール

### リポジトリインストール
# yum -y install epel-release
# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

### PHPのインストール
# yum install --enablerepo=remi,remi-php70 php php-devel php-mbstring php-pdo php-gd php-mysql php-xml

### version確認
# php -version


基本はここまでで完了です。
以下、/usr/local/apache/ のパスで動かしたいので、シムリンクで対応します

4. ドメイン設定

### httpd.conf の編集
# cd /etc/httpd/conf
# cp httpd.conf httpd.conf_bk
# vi httpd.conf


編集内容

### ServerNameの設定(編集)
------------------------------------------------------
# ServerName www.example.com:80
ServerName yukibata.com
------------------------------------------------------


### アクセス許可(編集)
------------------------------------------------------
<Directory />
    AllowOverride none
    # Require all denied
    Require all granted
</Directory>
------------------------------------------------------

### ドメイン設定(追記)
------------------------------------------------------
<VirtualHost *:80>
    DocumentRoot /usr/local/apache/vhosts/local.yukibata.com/htdocs
    ServerName local.yukibata.com.com
    ErrorLog vhosts/local.yukibata.com.com/logs/error_log
    TransferLog vhosts/local.yukibata.com.com/logs/access_log
    <Directory />
        Options FollowSymLinks
        AllowOverride All
    </Directory>
    <Directory "/usr/local/apache/vhosts/local.yukibata.com/htdocs">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>
------------------------------------------------------

5. ドメインに合わせてディレクトリ設定

### ディレクトリ作成と権限
# mkdir -p /usr/local/apache/vhosts/local.yukibata.com/htdocs
# mkdir -p /usr/local/apache/vhosts/local.yukibata.com/logs
# touch /usr/local/apache/vhosts/local.yukibata.com/logs/error_log
# touch /usr/local/apache/vhosts/local.yukibata.com/logs/access_log
# chmod -R 777 /usr/local/apache/vhosts/

### シムリンクを張る
# cd /etc/httpd/
# ln -s /usr/local/apache/vhosts vhosts
# ls -la | grep vhost
---------------------------------------------------------
lrwxrwxrwx   1 root root   24 Jun 18 04:12 vhosts -> /usr/local/apache/vhosts
---------------------------------------------------------

### apache再起動
# systemctl restart httpd.service

6. htdocsにファイルを置いて確認

# echo "<?php phpinfo();" > /usr/local/apache/vhosts/local.yukibata.com/htdocs/test.php

ブラウザから local.yukibata.com/test.php へアクセスして、phpinfo を確認



以上です。
シンプルですが、機械的にやっていけば構築は完了になります。

Apacheが起動しないと思ったら... (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80

技術系です

結論:Apacheの再起動ができないと思ったら、Listenを2回していたという話



windows アップデートで、開発環境がぶっとんだので、再構築中のことでした

apache 入れて、php 入れて、mysql 入れて、python 入れて、
動作確認OK

バーチャルホスト設定をしていたところ、
Apache再起動時に以下のようなエラー

[root@localhost httpd]# systemctl restart httpd.service
Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.


いわれた通りに、'systemctl status httpd.service' を実行

Jun 18 04:31:42 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
Jun 18 04:31:42 localhost.localdomain httpd[4077]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
Jun 18 04:31:42 localhost.localdomain systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
Jun 18 04:31:42 localhost.localdomain kill[4079]: kill: cannot find process ""
Jun 18 04:31:42 localhost.localdomain systemd[1]: httpd.service: control process exited, code=exited status=1
Jun 18 04:31:42 localhost.localdomain systemd[1]: Failed to start The Apache HTTP Server.
Jun 18 04:31:42 localhost.localdomain systemd[1]: Unit httpd.service entered failed state.

どうやら、「80ポートが使われている」らしい。


ポートをチェックします

[root@localhost httpd]# netstat -lnp | grep :80
[root@localhost httpd]#

・・・・ない


lsofコマンドで、古いプロセスがないか確認

[root@localhost httpd]# sudo lsof -i | grep http
[root@localhost httpd]#

・・・・ない


プロセスがない、でも「既に使われています」
ということは、1回の起動で2回ロードしようとしていないか疑う

[root@localhost httpd]# cat /etc/httpd/conf/httpd.conf | grep "Listen"                                                                 
# Listen: Allows you to bind Apache to specific IP addresses and/or                                                                     
# Change this to Listen on specific IP addresses as shown below to                                                                      
#Listen 12.34.56.78:80                                                                                                                  
Listen 80                                                                                                                               
Listen 80

いました。 Listen 80 が2個
昔の httpd.conf からコピペした際に、余分に入っちゃった系

1行消して解決しました。

Apacheのマルチドメインが効いていない原因は、httpd.conf だった件

 

Apacheのマルチドメインに関してハマった点を書きます。

 

困ったこと、

「マルチドメイン設定をしたのに、同じページが表示される」

です。

 

 

 

元々、

  A:local.yukibata.com/home/

があった状態で、

  B:local.test.yukibata.com/home/

を追加してBにアクセスしてみました。

が、なぜがAが表示されるという問題に遭遇しました。

 

現象を詳しく見てみる

 

まずは、Aである local.yukibata.com/home/ にアクセス。

すると、ちゃんとアクセスログは

/usr/local/apache2/vhosts/local.yukibata.com/logs/access_log ⇒ 来ている

/usr/local/apache2/vhosts/local.test.yukibata.com/logs/access_log ⇒ 来てない

これはOK

 

次に、Bである local.test.yukibata.com/home/ にアクセス。

すると

/usr/local/apache2/vhosts/local.yukibata.com/logs/access_log ⇒ 来ている

/usr/local/apache2/vhosts/local.test.yukibata.com/logs/access_log ⇒ 来てない

これはNG

 

原因は、やっぱり httpd.conf 

 

思い当たる節はほとんどないので、

新鮮な目で httpd.conf を見ていったら、やっぱり原因は httpd.conf だった。

 

f:id:yukibata:20170323223819p:plain

 

(誤)

  ServerName yukibata.com

  ServerName test.yukibata.com

(正)

  ServerName local.yukibata.com

  ServerName local.test.yukibata.com

 

でした。 local が抜けていました。

 

Apacheの挙動として、Virtualhost が複数設定されている場合、

振り分けが不明な場合に、先頭の振り分けに従う

というルールがあるようです。

 

ってことは、

いままで、

local.yukibata.com/home/ にアクセスして、

/usr/local/apache2/vhosts/local.yukibata.com/logs/access_log に来ているからOK

だと思っていた思っていたのは、

実は、全て不明だったから、たまたま先頭の Virtualhost 設定に従っていた

という状態だったんですね。。。

 

 

おわり

 

 

[ImageFrom]

http://manifoldcf.apache.org/ja_JP/

 

 

 

Centos+Apache+PHP で .htaccess 導入時のエラーについて

 

Centos + Apache + PHP で環境構築を設定した際に

.htaccess を書いたらエラー

 

原因は単純なことでした。

 

問題について

 

CentosにApacheとPHPをインストールして index.html が表示できた後で、

.htaccessを入れた際に表示されたエラーがこんな感じ

 

     ↓ ↓ ↓ ↓ ↓

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at you@example.com to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.

 

f:id:yukibata:20161002154830p:plain

 

解決について

 

.htaccessを導入する前は問題なく動いていたということなので、

 

 1:.htaccess の中に書いてある内容がオカシイ

 2:.htaccess に必要なモジュールの実行権限がない

 

このあたりだと予想。たぶん1だけど。

 

ということで、Apacheの httpd.conf を見てみると、

 

  ♯LoadModule rewrite_module modules/mod_rewrite.so

 

となっていた。

これのコメントアウトを外せばOK

(Apache再起動も忘れずに)

 

 

ちなみにエラーログをみるとちゃんとありますので

似たようなエラーの際は必ずチェックしましょう

 

[Sun Oct 02 06:36:01.926266 2016] [core:alert] [pid 3422:tid 140211212248832] [client 192.168.33.1:61031] /usr/local/apache2/vhosts/.local.yukibata.com/htdocs/.htaccess: Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration

 

 

おわり

 

windows+vagrantを使ってバーチャルドメイン構築のチェックポイント

 

vagrantでローカル環境構築でハマった点がいくつかありました。

ローカル環境構築の方法は、また別途記載するとして

今回は、構築中にハマった点を記載します。

同様につまづいた方は、チェックポイントとしてご利用ください。

 

 

環境について

 

今回の環境はこんな感じです。

 

   windows10

   vagrant 1.8.5

   VirtualBox 5.1.4

   centos7

 

まず前提として、上記がインストールされていることとします。

 

 

問題とゴール

 

問題は、ホストOS(windows)からゲストOS(centos)のドメインに

何故かアクセスできないこと。

 

ゴールは、アクセスし、ゲストOS側の access_log でアクセスが確認できること。

f:id:yukibata:20160922160451p:plain

とします。

(写真は403ですが、アクセスできることをゴールとします。)

 

 

最初に概要の説明

 

ゲストOSのドメインにアクセスが流れるためには

ざっくりいうと

 

  ・ブラウザが外(インターネット)にいかず、内部に接続が向かうこと

  ・その接続がゲストOSに向かうこと

  ・ゲストOSが正しくドメインをさばくこと

 

です。

今回は「ちゃんとそれぞれが正しい設定になっていますか」という

点で1つずつみていこうと思います。

 

そして今回は

 

  IP:192.168.33.10 (vagrantのデフォルトIP)

  バーチャルホスト名:local.yukibata.com

 

という条件で進めていこうと思います。

 

 

ポイント1: windows の hosts ファイル

 

ホストOS(windows)側の設定です。 

hostsファイルは、ブラウザが処理をする際にチェックするファイルです。

ここに、記載をすることで「この IP or バーチャルホスト は外に行かない」

ということが実現されされます。

 

つまり、このように記載しましょう。

”C:\Windows\System32\drivers\etc” にある hosts というファイルに

 

 192.168.33.10    local.yukibata.com

 

という1行をファイルの最終行に加えます。

(このような大事なファイルは、編集する前にバックアップを取りましょう)

 

これで、ブラウザが http(s)://local.yukibata.com とうアクセスを受け取った際、

外にアクセスしなくなります。

 

 

ポイント2:Vagrantfile の記載は正しいか?

 

vagrant が起動する際に、参照される設定ファイルが Vagrantfile です。

ここにある設定を読み込んで環境が起動します。

 

ここで大事な設定は3つです

 

 ・vm.boxの名前が正しいか?

 ・port forward は正しいか?

 ・ネットワークのIPは正しいか?

 

です。初期設定ではコメントアウトされているので、注意してください。

私の場合 box の名前が centos7 としてあります。

(boxの名前は、"vagrant box list" コマンドで確認できます。)

 

f:id:yukibata:20160922172724p:plain

 

名前を確認した上で以下の設定を記載してください。

 

Vagrant.configure("2") do |config|

## boxの名前
config.vm.box = "centos7"

## 追加変更
config.vm.define :centos7 do |centos7|
centos7.vm.box = "centos7"
centos7.vm.network "forwarded_port", guest: 80, host:8080
end

## IP の設定
config.vm.network "private_network", ip: "192.168.33.10"

end

 

極端な話、ファイルの中身を全部消して、これだけ書いてあればOKです。

 

 

 ポイント3:vagrant のバグを踏んでいないか?

 

私は、ここで結構ハマりました。

これは、私と同じ vagrant 1.8.5 を利用している方向けです。

それ以外のバージョンの方は飛ばしてください。

vagrant の 1.8.5には、バグが1件あるそうです。

 

"vagrant up" のコマンドを打つと、vagrant は起動するのですが、

private key の発行が上手くいかず、中途半端な設定で起動が

完了してしまします。

ssh接続はできるので、「行けてるかも?」と思いがちですが

行けてません。

 

このようなメッセージが出ていませんか?

”Warning: Remote connection disconnect. Retrying...”

 

f:id:yukibata:20160922162501p:plain

 

この場合、vagrant のソースファイルの修正が必要です。

 

windows側から修正したい場合は vagrant をインストールした

HashiCorpのディレクトリの中にあります。

私の場合は、

 

”C:\Program Files (x86)\HashiCorp\Vagrant\embedded\gems\gems\vagrant-1.8.5\plugins\guests\linux\cap”

 

にある "public_key.rb" ファイルの 57行目付近を以下のように修正します。

 

if test -f ~/.ssh/authorized_keys; then
  grep -v -x -f '#{remote_path}' ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.tmp
  mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keys
  chmod 0600 ~/.ssh/authorized_keys // ←ここを追加
fi

 

contos側から修正したい場合は 

/home/vagrant/.ssh/authorized_keys の権限を 600 に設定します。

 

f:id:yukibata:20160922163421p:plain

 

これで vagrant が無事に起動すると思います。

逆に言うと、この問題に引っかかり無事に起動しない場合、

centos側で ip の振り分けが正しく行われていないような気がします。

 

(参考)

www.thisprogrammingthing.com

 

 

ポイント4:VirtualBoxの設定が正しいか?

 

vagrant はあくまで、VirtualBoxをKickしている立場なので、

VirtualBoxの設定が正しくないとダメです。

もう一度、VirutalBoxの設定を見てみましょう。

 

ただし、設定を見る前に、centosが正しくOFFになっているかを

確認してください。起動中だと設定は変更できません。

 

”vagrant halt” と "vagrant status" のコマンドでOFFになっていることを

確認しましょう。

 

f:id:yukibata:20160922164038p:plain

 

確認ができたら、VirtualBoxを起動します。

 

f:id:yukibata:20160922164256p:plain

 

メニューから「設定」を選択

 

f:id:yukibata:20160922164322p:plain

 

左メニューの「ネットワーク 」を選択し、

「アダプター2」の「ネットワークアダプターを有効化」に

チェックが入っていること 。

そして、「割り当て」が「ホストオンリーアダプター」になっていることを

確認してください。

それ以外は、デフォルトのままでOKです。

 

これで "vagrant up" を行ってください。

以下のように Adapter 2 : hostonly と正しく認識されると思います。

 

f:id:yukibata:20160922165813p:plain

 

この「ホストオンリーアダプター」の設定がないと、

ホストOSからゲストOSへの接続ができなくなります。

 

ホストオンリーアダプターとは、簡単に言うと

ホストOSとゲストOSを結ぶ「仮想的なネットワーク」の作成

行ってくれるものです。

 

ここまでくれば、

ブラウザからアクセスし、windowsの内部から centosに向かうまでが完成です。

ここからは、

「centosが受け付けてくれること」

「apacheが受け付けてくれること」

のチェックポイントを見ていきましょう。

 

 

ポイント5:centos側がIPを認識しているか?

 

ゲストOSが対象(192.168.33.10)のIPを認識していなければいけません

ifconfig コマンドで確認しましょう。

 

ただ、centos7 では、ifconfigコマンドが非推奨となっているので、

インストールしなければいけません。

まず ”yum -y install net-tools” コマンドでインストールしましょう。

 

そして、正しく認識されているか確認してください。

 

f:id:yukibata:20160922173738p:plain

 

もしここに 192.168.33.10 がなければ、

"vagrant halt" や "vagrant destroy" をして再トライしてみてください。

 

 

ポイント6:centosの hosts ファイルが正しいか?

 

windows の hosts ファイルのようなイメージで

centos にも hosts ファイルがあります。

 

"vi /etc/hosts " で編集してみましょう。

 

f:id:yukibata:20160922165957p:plain

 

このように

 

 192.168.33.10  [バーチャルホスト名]  localhost.localdoain localhost

 

となってればOKです。

 

ここまでで、

ブラウザからアクセスし、centosへのアクセスが可能となっています。

 

 

ポイント7:apacheの設定

 

最後にapacheの設定を見てみましょう。

人によって、apacheのインストール方法は異なると思いますが、

私は /etc/httpd のような構成が気持ち悪いので、

個別にapacheをインストールしました。

"/usr/local/apache2/" という構成です。

(ただ、このような構成でなくてもまったく問題ありません)

 

”vi /usr/local/apache2/conf/httpd.conf” コマンドで

httpd.conf ファイルを編集してみましょう。

 

以下のように編集します。

 

f:id:yukibata:20160922170805p:plain

 

<VirtualHost *:80>
  DocumentRoot /usr/local/apache2/vhosts/local.yukibata.com/htdocs
  ServerName local.yukibata.com
  ErrorLog vhosts/local.yukibata.com/logs/error_log
  TransferLog vhosts/local.yukibata/logs/access_log
  <Directory />
    Options FollowSymLinks
    AllowOverride All
  </Directory>
  <Directory "/usr/local/apache2/vhosts/local.yukbiata.com/htdocs">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

 

これでバーチャルドメインごとにディレクトリを作成できるので、

複数ドメインや今後のデバッグが便利になります。

 

ポイントとしては、

 

  ・<VirtualHost *:80> 

  ・DocumentRoot

  ・ServerName

  ・ErrorLog

  ・TransferLog

 

の5つです。

local.yukibata.com のアクセスが来るとそれぞれが機能してくれます。

 

忘れがちなのは、

 

 "/usr/local/apache2/vhosts/local.yukiabta.com/logs/"

 "/usr/local/apache2/vhosts/local.yukibata.com/htdocs/"

 

のディレクトリを mkdir コマンドで作成し

apacheが書き込めるように権限設定をしておいてください。

 

上記のように apache の設定が終わったら、

apacheの再起動をします。

 

コマンドは

"/usr/local/apache2/bin/apachectl stop"

"/usr/local/apache2/bin/apachectl start"

です。(restartでもOK)

 

f:id:yukibata:20160922171557p:plain

 

 

ポイント8:firewall は無効になっているか

 

firewallとは、外部の不正なネットワークを遮断する仕組みです。

この設定が有効だと、ホストOSからのアクセスは遮断されます。

設定を確認して、有効になっていたらOFFにしましょう。

 

設定確認のコマンドは

 

  systemctl status firewalld

 

です。

 

f:id:yukibata:20160929231536p:plain

 

このように(画像の緑色の部分) Active:active(running) となっていたら

ONになっている証拠です。

 

これを

 

  systemctl stop firewalld

 

でOFFにして、再度 systemctl status firewalld で確認しましょう。

以下のように、 Active:inactive(dead) となればOKです。

 

f:id:yukibata:20160929231825p:plain

 

 

ポイント9:ホストOSからゲストOSに ping が通るか?

 

コマンドプロンプトなのどで ping を打ってみましょう

 

 "ping 192.168.33.10"

 

もしくは

 

 "ping local.yukibata.com" 

 

でOKです。

すると以下のように、接続ができていることがわかります。

 

f:id:yukibata:20160922171929p:plain

 

これで、ブラウザからアクセスした際に

 

 /usr/local/apache2/vhosts/local.yukibata.com/logs/access_log

 

にアクセスが来ることが確認できます。

 

firewall (ファイヤーウォール)の詳しい仕組みは

このサイトがわかりやすかったです。

 

www.infraexpert.com

 

 

まとめ

 

以上8項目が、チェックポイントとして記載しました。

もしかしたら、これらのチェックポイントでもうまくいかない方も

いらっしゃるかもしれませんが、

少なくとも、1つずつチェックしていくことで、

どこまでOKかのイメージがつくと思います。 

 

最後に参考になったサイトを記載します。

もし詰まったり、これって何?と思ったら参照してみてください。

 

labs.septeni.co.jp

 

sui.hateblo.jp

 

 

おわり

 

 

[ImageFrom]
https://www.vagrantup.com/
http://www.thisprogrammingthing.com/2016/fixing-vagrant-connection-error/