読者です 読者をやめる 読者になる 読者になる

Webサービスで起業を目指すプログラマーblog

仕事で使ったプログラミング、サーバー周りで役に立つこと、Webサービス開発に必要な技術情報、モバイル情報を書いてます。わかりやすく見やすくをモットーにしています。

MacのVMWare FusionからWindowsのVMWare Workstation Playerに移行する手順

VMWare

MacWindowsでは、日本語ファイル名の濁点・半濁点の扱いが異なるため、そのまま移行してもファイルのパスを認識しないため動作しません。

そのため、MacからWindowsに移行するには、事前に日本語を含まないファイル名に変更しておく必要があります。

同じようなサイトを参考に行ってみましたが、どうもスムーズにいかなかったので、スムーズにいった手順を書いてみました。

MacVMWare Fusionの手順

1.ターミナルを起動し、移行したい仮想マシンがあるディレクトリに移動します。

cd "/Users/{ユーザー名}/Documents/Virtual Machines.localized/Windows 7 x64.vmwarevm"

2.アプリケーションディレクトの「VMWare Fusion.app」内にある「vmware-vdiskmanager」を使って仮想ディスクの名前を変更します。
仮想ディスク名は、「仮想ディスク-s001.vmdk」と連番が付いていますが、それを除いた名前を指定します。
コマンドを実行すると全てのファイル名が変更されます。

/Applications/VMware\ Fusion.app/Contents/Library/vmware-vdiskmanager -n 仮想ディスク.vmdk win7.vmdk

3.仮想マシンにある「*.vmx」ファイルを開き、10行目あたりの「scsi0:0.fileName」に2で設定した新しい名前に変更します。

Finderの場合、仮想マシン「*..vmwarevm」ファイルを右クリックし「パッケージの内容を表示する」をクリックします。

ターミナルの場合、VI等のエディタで編集します。

vi "/Users/onishi/Documents/Virtual Machines.localized/Windows 7 x64.vmwarevm/Windows 7 x64.vmx"

「*.vmx」を以下のように変更します。

# 変更前
scsi0:0.fileName = "仮想ディスク.vmdk"

# 変更後
scsi0:0.fileName = "win7.vmdk"

4.ファイル名を変更した仮想マシンWindowsにコピーします。
ネットワーク経由でも良いですが、ファイルサイズが大きいのでUSB3.0対応USBメモリを使うと早くコピーできます。

WindowsVMWare Workstation Playerの手順

1.Macからコピーした仮想マシンVMWare Workstation Playerで開きます。

デフォルトの仮想マシンフォルダは、「C:¥Users¥{ユーザー名}¥Documents¥Virtual Machines」です。

2.仮想マシンを問題なく起動できると、移動またはコピーしたかのダイアログが表示されるので、「移動しました」を選択します。
f:id:shinsuke789:20170329095330p:plain

3.環境によっては、キーボードフックタイムアウトの設定ダイアログが表示されるので、「OK」を選択します。
f:id:shinsuke789:20170329095337p:plain

4.仮想マシンが正常に起動しWindowsが操作できることを確認します。追加でVMWare Toolsのインストールを行います。

Visual Studio 2015でWindows Installerを使えるようにする

VisualStudio

Visual Studio 2015から2010のときに標準だったインストーラーが拡張機能として使えるようになりました。
英語表記ですが、機能的にほとんど変わっていないので心配ないと思われます。

インストール方法をまとめました。

環境

手順

1.ファイルメニューの「ツール」→「拡張機能と更新プログラム」を開きます
f:id:shinsuke789:20170130075810p:plain:w300


2.右上の検索欄に「installer」と入力して検索すると、一覧に「Microsoft Visual Studio 2015 Installer Project」が表示されるので「ダウンロード」をクリックします
f:id:shinsuke789:20170130075818p:plain


3.ブラウザが起動するのでファイルをダウンロードします
f:id:shinsuke789:20170130075834p:plain


4.ダウンロードしたファイルを起動します
f:id:shinsuke789:20170130075842p:plain:w150


5.Visual Studioを起動していると終了を促すメッセージが表示されるので、Visual Studioを終了させ「Retry」をクリックします
f:id:shinsuke789:20170130075848p:plain:w300


6.セットアップの内容が表示されるので確認し「Install」をクリックします
f:id:shinsuke789:20170130075857p:plain:w300


7.Windowsの権限許可が表示されるので「はい」をクリックします
f:id:shinsuke789:20170130075905p:plain:w300


8.インストールが始まるのでしばらく待ちます
f:id:shinsuke789:20170130075912p:plain:w300


9.インストールが完了したら「Close」をクリックします
f:id:shinsuke789:20170130075920p:plain:w300


10.Visual Studioを起動して任意のプロジェクトを開いてから、ファイルメニューの「ファイル」→「新しいプロジェクト」を選択します
f:id:shinsuke789:20170130075928p:plain:w300


11.「その他のプロジェクトの種類」→「Visual Studio Installer」を選択し、一覧の「Setup Project」を選択します。
f:id:shinsuke789:20170130075944p:plain


12.既存のプロジェクトにSetupプロジェクトが追加され、インストーラーを作成できるようになります。
f:id:shinsuke789:20170130075950p:plain


作って覚えるVisual C# 2015 デスクトップアプリ入門

作って覚えるVisual C# 2015 デスクトップアプリ入門

GlassFish4でSpringBootを動かすとログが無限に出力される対処方法

GlassFish SpringBoot

GlassFish4でSpringBootアプリを動かすと、アプリで設定したログファイルに無限にログが出力され、サーバーのディスクを使い切るという現象に遭遇しました。

いろいろ調べてもなかなか対処方法がありませんでしたが、困った時の「stack overflow」に似たようなことで質問が上がっていたので試したら無事解決したので、その手順を紹介します。

動作環境

SpringBoot 1.3.6
Logback 1.1.7
SLF4j 1.7.21
GlassFish 4.1.1 Full Profile

GlassFishは、PayaraServer 163 Fullのdomain1を使用

問題の現象

GlassFishにSpringBootアプリをwarでデプロイし、アプリが起動するとアプリで設定したログファイルに次のようなものが無限に出力される。

INFO  [2016-11-08 16:59:28.375] unknown.jul.logger .   ____          _            __ _ _  
INFO  [2016-11-08 16:59:28.397] unknown.jul.logger /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \  
INFO  [2016-11-08 16:59:28.397] unknown.jul.logger ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \  
INFO  [2016-11-08 16:59:28.397] unknown.jul.logger \\/  ___)| |_)| | | | | || (_| |  ) ) ) )  
INFO  [2016-11-08 16:59:28.397] unknown.jul.logger '  |____| .__|_| |_|_| |_\__, | / / / /  
INFO  [2016-11-08 16:59:28.398] unknown.jul.logger =========|_|==============|___/=/_/_/_/  
INFO  [2016-11-08 16:59:28.398] unknown.jul.logger :: Spring Boot ::        (v1.3.6.RELEASE)  
INFO  [2016-11-08 16:59:28.398] unknown.jul.logger 2016-11-08 16:59:28.375  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : .   ____          _            __ _ _  
INFO  [2016-11-08 16:59:28.398] unknown.jul.logger INFO  [2016-11-08 16:59:28.375] unknown.jul.logger .   ____          _            __ _ _  
INFO  [2016-11-08 16:59:28.398] unknown.jul.logger 2016-11-08 16:59:28.397  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \  
INFO  [2016-11-08 16:59:28.398] unknown.jul.logger INFO  [2016-11-08 16:59:28.397] unknown.jul.logger /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \  
INFO  [2016-11-08 16:59:28.399] unknown.jul.logger 2016-11-08 16:59:28.397  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \  
INFO  [2016-11-08 16:59:28.399] unknown.jul.logger INFO  [2016-11-08 16:59:28.397] unknown.jul.logger ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \  
INFO  [2016-11-08 16:59:28.399] unknown.jul.logger 2016-11-08 16:59:28.397  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : \\/  ___)| |_)| | | | | || (_| |  ) ) ) )  
INFO  [2016-11-08 16:59:28.399] unknown.jul.logger INFO  [2016-11-08 16:59:28.397] unknown.jul.logger \\/  ___)| |_)| | | | | || (_| |  ) ) ) )  
INFO  [2016-11-08 16:59:28.399] unknown.jul.logger 2016-11-08 16:59:28.397  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : '  |____| .__|_| |_|_| |_\__, | / / / /  
INFO  [2016-11-08 16:59:28.400] unknown.jul.logger INFO  [2016-11-08 16:59:28.397] unknown.jul.logger '  |____| .__|_| |_|_| |_\__, | / / / /  
INFO  [2016-11-08 16:59:28.400] unknown.jul.logger 2016-11-08 16:59:28.398  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : =========|_|==============|___/=/_/_/_/  
INFO  [2016-11-08 16:59:28.400] unknown.jul.logger INFO  [2016-11-08 16:59:28.398] unknown.jul.logger =========|_|==============|___/=/_/_/_/  
INFO  [2016-11-08 16:59:28.400] unknown.jul.logger 2016-11-08 16:59:28.398  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : :: Spring Boot ::        (v1.3.6.RELEASE)  
INFO  [2016-11-08 16:59:28.400] unknown.jul.logger INFO  [2016-11-08 16:59:28.398] unknown.jul.logger :: Spring Boot ::        (v1.3.6.RELEASE)  
INFO  [2016-11-08 16:59:28.400] unknown.jul.logger 2016-11-08 16:59:28.398  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : 2016-11-08 16:59:28.375  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : .   ____          _            __ _ _  
INFO  [2016-11-08 16:59:28.401] unknown.jul.logger INFO  [2016-11-08 16:59:28.398] unknown.jul.logger 2016-11-08 16:59:28.375  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : .   ____          _            __ _ _  
INFO  [2016-11-08 16:59:28.401] unknown.jul.logger 2016-11-08 16:59:28.398  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : INFO  [2016-11-08 16:59:28.375] unknown.jul.logger .   ____          _            __ _ _  
INFO  [2016-11-08 16:59:28.401] unknown.jul.logger INFO  [2016-11-08 16:59:28.398] unknown.jul.logger INFO  [2016-11-08 16:59:28.375] unknown.jul.logger .   ____          _            __ _ _  
INFO  [2016-11-08 16:59:28.401] unknown.jul.logger 2016-11-08 16:59:28.398  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : 2016-11-08 16:59:28.397  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \  
INFO  [2016-11-08 16:59:28.401] unknown.jul.logger INFO  [2016-11-08 16:59:28.398] unknown.jul.logger 2016-11-08 16:59:28.397  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \  
INFO  [2016-11-08 16:59:28.402] unknown.jul.logger 2016-11-08 16:59:28.398  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : INFO  [2016-11-08 16:59:28.397] unknown.jul.logger /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \  
INFO  [2016-11-08 16:59:28.402] unknown.jul.logger INFO  [2016-11-08 16:59:28.398] unknown.jul.logger INFO  [2016-11-08 16:59:28.397] unknown.jul.logger /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \  
INFO  [2016-11-08 16:59:28.402] unknown.jul.logger 2016-11-08 16:59:28.399  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : 2016-11-08 16:59:28.397  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \  
INFO  [2016-11-08 16:59:28.402] unknown.jul.logger INFO  [2016-11-08 16:59:28.399] unknown.jul.logger 2016-11-08 16:59:28.397  INFO 2466 --- [       Thread-8] unknown.jul.logger                       : ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \  

GlassFishでLoggerが認識されていないのが原因のようです。

手順

GlassFishにあるファイルを編集する前にバックアップを取りましょう。


1.GlassFishが起動している場合、停止する

glassfish4/glassfish/bin/asadmin stop-domain domain1


2.GlassFIshのlibディレクトリにlogback・slf4jライブラリを配置する

# 配置先
glassfish4/glassfish/lib/endorsed

# 配置するライブラリ
jul-to-slf4j-x.x.x.jar
slf4j-api-x.x.x.jar
logback-core-x.x.x.jar
logback-classic-x.x.x.jar


3.GlassFishのconfigディレクトリにlogback.xmlを配置し、次のように定義する

vi glassfish/domains/domain1/config/logback.xml

logback.xml

<configuration debug="true" scan="true">
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>log/server.log</file>
        <append>true</append>
        <encoder>
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{52} - %msg%n</Pattern>
        </encoder>
    </appender>
    <root>
        <level value="INFO"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>


4.GlassFishにある「logging.properties」の一部を書き換える
管理コンソールで変更している場合、変更した値になっているので注意して下さい。

vi glassfish4/glassfish/domain1/config/logging.properties

Before

handlers=java.util.logging.ConsoleHandler
handlerServices=com.sun.enterprise.server.logging.GFFileHandler
java.util.logging.ConsoleHandler.formatter=com.sun.enterprise.server.logging.UniformLogFormatter
com.sun.enterprise.server.logging.GFFileHandler.formatter=com.sun.enterprise.server.logging.ODLLogFormatter
com.sun.enterprise.server.logging.GFFileHandler.file=${com.sun.aas.instanceRoot}/logs/server.log
com.sun.enterprise.server.logging.GFFileHandler.rotationTimelimitInMinutes=0
com.sun.enterprise.server.logging.GFFileHandler.flushFrequency=1
java.util.logging.FileHandler.limit=50000
com.sun.enterprise.server.logging.GFFileHandler.logtoConsole=false
com.sun.enterprise.server.logging.GFFileHandler.rotationLimitInBytes=2000000
com.sun.enterprise.server.logging.GFFileHandler.excludeFields=
com.sun.enterprise.server.logging.GFFileHandler.multiLineMode=true
com.sun.enterprise.server.logging.SyslogHandler.useSystemLogging=false
java.util.logging.FileHandler.count=1
com.sun.enterprise.server.logging.GFFileHandler.retainErrorsStasticsForHours=0
log4j.logger.org.hibernate.validator.util.Version=warn
com.sun.enterprise.server.logging.GFFileHandler.maxHistoryFiles=0
com.sun.enterprise.server.logging.GFFileHandler.rotationOnDateChange=false
java.util.logging.FileHandler.pattern=%h/java%u.log
java.util.logging.FileHandler.formatter=java.util.logging.XMLFormatter

After

handlers=org.slf4j.bridge.SLF4JBridgeHandler #変更
handlerServices=com.sun.enterprise.server.logging.GFFileHandler
java.util.logging.ConsoleHandler.formatter=com.sun.enterprise.server.logging.UniformLogFormatter
com.sun.enterprise.server.logging.GFFileHandler.formatter=com.sun.enterprise.server.logging.ODLLogFormatter
com.sun.enterprise.server.logging.GFFileHandler.file=${com.sun.aas.instanceRoot}/logs/server.log #そのまま
com.sun.enterprise.server.logging.GFFileHandler.rotationTimelimitInMinutes=0
com.sun.enterprise.server.logging.GFFileHandler.flushFrequency=1
java.util.logging.FileHandler.limit=50000
com.sun.enterprise.server.logging.GFFileHandler.logtoConsole=false
com.sun.enterprise.server.logging.GFFileHandler.rotationLimitInBytes=2000000
com.sun.enterprise.server.logging.GFFileHandler.excludeFields=
com.sun.enterprise.server.logging.GFFileHandler.multiLineMode=true
com.sun.enterprise.server.logging.SyslogHandler.useSystemLogging=false
java.util.logging.FileHandler.count=1
com.sun.enterprise.server.logging.GFFileHandler.retainErrorsStasticsForHours=0
log4j.logger.org.hibernate.validator.util.Version=warn
com.sun.enterprise.server.logging.GFFileHandler.maxHistoryFiles=0
com.sun.enterprise.server.logging.GFFileHandler.rotationOnDateChange=false
java.util.logging.FileHandler.pattern=%h/java%u.log
com.sun.enterprise.server.logging.GFFileHandler.formatter=com.sun.enterprise.server.logging.UniformLogFormatter #変更
com.sun.enterprise.server.logging.GFFileHandler.alarms=false #追加


5.GlassFishの「domain.xml」にJVMオプションを追加する

vi glassfish4/glassfish/domains/domain1/config/domain.xml


domain.xml

# <domain>
#   <configs>
#     <config name="server-config">
#       <java-config> 配下に追加する(250行目の次)
<jvm-options>-Djava.util.logging.config.file=${com.sun.aas.instanceRoot}/config/logging.properties</jvm-options>
<jvm-options>-Dlogback.configurationFile=file:///${com.sun.aas.instanceRoot}/config/logback.xml</jvm-options>


6.GlassFishを起動する

glassfish4/glassfish/bin/asadmin start-domain domain1

補足

SpringBootアプリには、「jul-to-slf4j」は含んでいません。
logback.xmlは、SpringBootのbase.xmlを読み込み、独自設定を追加しています。
application.propertiesの「logging.file」は、設定していません。
logging.properties(alarms以外)、jvm-optionは、管理コンソールの「server-config」で設定できます。

まとめ

ネットにあった内容をそのまま試して日本語に起こしただけです。
詳しいことは分からないので聞かないようにお願いしますw

この記事で関連する書籍

Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築

Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築

XamarinをMacにインストールする

Xamarin

スマホアプリをクロスプラットフォーム開発できる「Xamarin」をMacにインストールしたときの手順です。

環境

OS X 10.11.5
XCode 未インストール

手順

1.Xamarinダウンロードページにアクセスします。
www.xamarin.com


2.全項目を入力し、チェックボックスにチェックを入れ、ダウンロードボタンをクリックします。
f:id:shinsuke789:20160628170243p:plain


3.「XamarinInstaller.dmg」のダウンロードが開始されます。


4.ダウンロードが完了したら、dmgファイルを実行し、表示されたアイコンをダブルクリックします。
f:id:shinsuke789:20160628170334p:plain


5.Webからダウンロードしたので「開く」をクリックします。
f:id:shinsuke789:20160628170401p:plain


6.「同意する」にチェックします。
f:id:shinsuke789:20160628170415p:plain


7.インストールの準備中でしばらく待ちます。
f:id:shinsuke789:20160628170434p:plain


8.インストールするプロダクトを選択します。
f:id:shinsuke789:20160628170448p:plain


9.設定のインストール先を設定します。
f:id:shinsuke789:20160628170504p:plain


10.XCodeがインストールされていない場合のお知らせです。
f:id:shinsuke789:20160628170520p:plain


11.インストールされるプロダクトの一覧です。
f:id:shinsuke789:20160628170541p:plain

12.Android SDKのライセンスに同意します。
f:id:shinsuke789:20160628170556p:plain


13.Macのパスワードを入力します。
f:id:shinsuke789:20160628170607p:plain


14.インストールが開始されるので待ちます。
f:id:shinsuke789:20160628170624p:plain


15.インストールの進捗バーがなくなりますが、インストール中で、3回程Macのパスワードが求められるので入力します。
f:id:shinsuke789:20160628170654p:plain


16.インストールが完了しました。XCodeがインストールされていな場合、「インストールしてね」と表示されます。
f:id:shinsuke789:20160628170708p:plain


17.アプリケーションフォルダの「Xamarin Studio.app」を起動します
f:id:shinsuke789:20160628170922p:plain

f:id:shinsuke789:20160628171035p:plain

登録後に届くメール

以下の様なメールが届きます。
最終行に配信停止のリンクがあるので不要であればそこから手続きします。

Hi


Thanks for downloading Xamarin Studio! We just wanted to point you to a few key resources to help you get started quickly:

  • Cross-platform development with Xamarin Studio
  • Prebuilt Apps
  • Xamarin Developer Center


If you have any questions, please post them here in StackOverflow and our support team will answer them as quickly as they can.


Warm regards,


Unsubscribe from Xamarin marketing emails.
Team Xamarin

「doma-spring-boot-starter」を使ってSpringBootとDomaの連携を楽にする

SpringBoot Doma Java

JavaのDBアクセスフレームワーク「Doma2」にSpringBootと連携し自動で設定してくれる「doma-spring-boot-starter」が追加されました。

今までは独自にDoma用のクラスを作成し連携していましたが、それをする必要がなくなり導入と設定が楽になりました。


github.com

doma-spring-boot-starter」の適用概略

1.build.gradleに「https://oss.sonatype.org/content/repositories/snapshots」のリポジトリを追加する

2.build.gradleに「org.seasar.doma.boot:doma-spring-boot-starter」の依存を追加する

3.application.propertiesに必要であればdoma用の設定を追加する

doma-spring-boot-starter」を使うことでdoma設定クラスが不要になります。
application.propertiesdoma.namingを追加することで、@EntityNamingTypeの定義が不要になります。

サンプルコード

build.gradle

repositories {
	mavenCentral()
	// 追記
	maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}

dependencies {
	// 追記
	compile('org.seasar.doma.boot:doma-spring-boot-starter:1.0.2')
	// 削除
	//compile('org.seasar.doma:doma:2.6.2')
}

src/main/resources/application.properties

# DB
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:test_db
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

# DOMA
doma.dialect=ORACLE
doma.naming=SNAKE_LOWER_CASE

src/main/java/com.example.dao.EmpDao

package com.example.dao;

import java.util.List;

import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;

import com.example.entity.Emp;

@ConfigAutowireable
@Dao
public interface EmpDao {

	@Select
	List<Emp> findAll();
}

src/main/java/com.example.entity.Emp

package com.example.entity;

import java.util.Date;

import org.seasar.doma.Entity;
import org.seasar.doma.Id;

// application.propertiesの「doma.naming」で指定済みなので不要
//@Entity(naming = NamingType.SNAKE_LOWER_CASE)
@Entity
public class Emp {

	@Id
	public String empNo;

	public String empNm;
}

src/main/java/com.example.web.TestController

package com.example.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.dao.EmpDao;
import com.example.entity.Emp;

@Controller
public class TestController {

	@Autowired
	private EmpDao empDao;

	@RequestMapping("/test")
	public String index() {

		List<Emp> list = empDao.findAll();
		for (Emp emp : list) {
			System.out.println(emp.empNo);
		}

		return "test/test";
	}

さくらのレンタルサーバーでCodeigniterを使いHTTPアクセスをHTTPSに強制リダイレクトする.htaccessの書き方

さくらレンタルサーバー CodeIgniter

さくらのレンタルサーバーでHTTPアクセスをHTTPSに強制リダイレクトするのにかなりハマりました。

ネットでひたすらHTTPSにリダイレクトする方法を調べ試してみましたが、リダイレクトループばかりで全く実現できず。

最終的にさくらの仕様のせいで通常の設定が効かないということが分かりました。

困っている方、コードをコピペしてさっさと解決してしまいましょう。

環境

サーバー さくらのレンタルサーバー スタンダード
Codeigniter 3.0.3
PHP 5.4

有効な「.htaccess」の設定

RewriteEngine On

# HTTP->HTTPSリダイレクト設定
RewriteCond %{ENV:HTTPS} !^on$
RewriteCond %{HTTP:X-SAKURA-FORWARDED-FOR} ^$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# Codeigniterの設定
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]


さくらの共有SSL、独自SSLとも上記設定でHTTPSリダイレクトが可能です。

%{ENV:HTTPS}と%{HTTP:X-SAKURA-FORWARDED-FOR}がミソです。


次のサイトで詳しく説明があり大変助かりました。
furyu.hatenablog.com


上記サイトより引用です。

%{SERVER_PORT} には、SSLかそうでないかによらず '80' が設定される。
このため、%{SERVER_PORT}ではSSL接続かどうかの判別はできない。
「RewriteCond %{SERVER_PORT} ^80$」や「RewriteCond %{SERVER_PORT} !^443$」は常に真となるために、リダイレクトループが発生してしまう。

SSLアクセス時には通常、 %{ENV:HTTPS} には 'on' が、%{HTTP:X-Sakura-Forwarded-For} にはクライアント(リクエスト元)のIPアドレスが設定される。*1
ただし、SSLアクセスした場合であっても、mod_rewrite.c の RewriteRule によりリライトされるケースでは、リライト後には %{ENV:HTTPS} が未設定となってしまう。
RewriteRuleの[R]フラグによりhttps://〜にリダイレクトされた場合には 'on' が設定される。

まとめ

さくらのレンタルサーバーでは独自仕様があるのでまずそれを確認すること。
Codeigniterで他にフックを使った方法があるが、この仕様を考慮したPHPコードを書く必要がある。
めんどくさいと思ったら.htaccessで設定した方が簡単!


サーバ構築の実際がわかる Apache[実践]運用/管理 (Software Design plus)

サーバ構築の実際がわかる Apache[実践]運用/管理 (Software Design plus)

さくらレンタルサーバーではRuby on Railsは動作するけどレスポンスが糞遅いのでやめとけ

Ruby on Rails さくらレンタルサーバー

タイトルの通りの内容で、さくらレンタルサーバーRailsは糞遅いというお話です。

経緯

ホームページを作成する案件があって、それに付随するプログラムの開発がありました。
ホームページを動作させるのがメインだったので、レンタルサーバーが選択されました。

個人的にPHPが嫌い(Java育ちなのでPHPの曖昧さがなじめない)なのでそれ以外の言語はないのかとRubyを選択しました。

初めてのRuby on Railsでしたが、Java経験者からすると今までにない感じのプログラミングだったので、非常に楽しくワクワクしながら開発できました。

Ruby on Rails動作環境構築

さて、ひと通り出来上がったのでテストしてもらうために、動作環境であるレンタルサーバーRuby on Railsが動作する環境を構築しました。

事前に動作するというのは確認できていたので、いろんなサイトを参考にしながら試行錯誤で環境を構築しました。

この時点で、レスポンスが遅いというのは情報として知ってました。

でも、本当に遅いのかというのがわからなかったのと、FCGIだと速いという情報もあったので大丈夫だろうと思ってました。

デプロイ

環境の構築も完了したのでデプロイしていました。

トップページにアクセスしてみると、なかなか画面が表示されません。
何度やっても遅い、遅い、遅い。

確か画面表示に10秒以上かかってたと思います。

「これはあかん」ということで、PHPで最初から作りなおしました…。

構築手順

かなり日にちが経っててよく覚えてませんが、当時のメモをそのまま載せておきます。ものすごく適当です。

お遊びで構築したい人向けです。間違っても本番運用しないで下さい。泣くのは開発者であるあなたです。


1.wwwディレクトリと同階層にappディレクトリを作成する

2.appディレクトリにRailsプロジェクトを配置する

3.Rails/publicに.htaccessを作成する

RewriteEngine On
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

ErrorDocument 500 "Application errorRails application failed to start properly"

4.Rails/publicにdispatch.cgiを作成し、権限を755にする

#!/home/user/local/rbenv/versions/2.2.3/bin/ruby

# 本番環境設定
ENV["RAILS_ENV"] = "production"
# rake secretで生成したもの
ENV["SECRET_KEY_BASE"] = "7cd8a5e38cfeddd0d0a4b45ad4bf75fd2cffe124f43388c34e6f29cf2c2e78f7d9cc1b2003f913be65c54f6ec61c7032609d3c9d88d6b3dc5226925a825b8379"
# 静的ファイル
ENV["RAILS_SERVE_STATIC_FILES"] = "true"

require File.dirname(__FILE__) + '/../config/environment'

class Rack::PathInfoRewriter
  def initialize(app)
    @app = app
  end
  def call(env)
    env.delete('SCRIPT_NAME')
    parts = env['REQUEST_URI'].split('?')
    env['PATH_INFO'] = parts[0]
    env['QUERY_STRING'] = parts[1].to_s
    env['PATH_INFO'] = env['PATH_INFO'].gsub(/\A#{ENV['RAILS_RELATIVE_URL_ROOT']}(.*)\Z/, '\1')
    env['SCRIPT_NAME'] = ENV['RAILS_RELATIVE_URL_ROOT']
    @app.call(env)
  end
end
# アプリケーション名を設定する
Rack::Handler::CGI.run  Rack::PathInfoRewriter.new(Hoge::Application)

5.Rails/config/boot.rbに以下を追記する

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])

$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby/2.2.0')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby/site_ruby/2.2.0')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby/gems/2.2.0')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib')

ENV['PATH'] += ':/home/user/local/bin'

ENV['GEM_HOME'] ||= '/home/user/local/rbenv/versions/2.2.3/lib/ruby/gems/2.2.0'

# パスを設定する
ENV['RAILS_RELATIVE_URL_ROOT'] = '/hoge'

6.静的ファイルをプレコンパイルする

rake assets:precompile RAILS_ENV=production

7.node.jsを編集する
/local/src/node-v0.10.38/deps/v8/tools/gyp/v8.gyp

['OS=="freebsd"', {
    'include_dirs+':[
      '/home/user/local/include'
    ],
    'link_settings': {
      'libraries': [
        '-L/usr/local/lib -L${HOME}/local/lib -lexecinfo',
    ]},
    'sources': [
      '../../src/platform-freebsd.cc',
      '../../src/platform-posix.cc'
    ],
  }
],

FCGI対応

$ cd ~/local/src
$ wget http://www.fastcgi.com/dist/fcgi.tar.gz
$ tar xvzf fcgi.tar.gz
$ cd  fcgi-2.4.1-SNAP-0311112127
$ ./configure --prefix=$HOME/local CFLAGS="-g -O2 -Wall -fPIC" CXXFLAGS="-g -O2 -Wall -fPIC"
$ make
$ make install

#### $ gem install fcgi -- --with-fcgi-include=$HOME/local/include --with-fcgi-lib=$HOME/local/lib
$ cd ~/appdir
$ bundle exec gem install fcgi -- --with-fcgi-include=$HOME/local/include --with-fcgi-lib=$HOME/local/lib
$ vi Gemfile
   追記 gem 'fcgi'
$ bundle update

まとめ

さくらレンタルサーバーでは、Ruby on Railsは動作するが、レスポンスが糞遅いのでやめましょう。

レンタルサーバーというと全てのサーバーをイメージされると思いますが、root権限のない制約のあるレンタルサーバーのことです。
さくらのVPS等root権限のあるサーバーでは、普通に動作しますので勘違いされないようにお願いします。