Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

Windows 10 ProでWordPressをDocker Composeで10分以内で構築してみる

f:id:fa11enprince:20190420105826j:plain Docker for Windowsが入っていれば30秒以内です。
Java大好き人間ですがPHP系の話題を書いてみます。
Dockerは既に入ってるよって人はdocker-composeのための設定から読んでください。

前提条件

Dockerが使える環境であること前提となります。
やや語弊がありますが、ほぼWindows Nativeで使いたい場合、
Windows 10 Professional Edition (64bit)である必要があります(=要Hyper-V)。
もしくはmacOSかLinuxであることが前提になります。
どうしてもWindows Home Editionでdockerを使う場合、 通常はVirtual Box/VMware上にUbuntu/CentOS等をインストールしてそのうえでDockerを使うことになります。
一応Windows Subsystem for Linuxでも可ですが、少し環境構築のハードルは上がると思います。
あとは…Docker Tool Boxなるものがあったのでそれでも良いです。

今回はWindows 10 Professional Editionの場合のみ説明します。

Hyper-Vの有効化

管理者権限で以下のコマンドを入力した後に、Windowsを再起動します。

bcdedit /set hypervisorlaunchtype auto

このあたりは上記コマンドラインでなくてもググるといろいろやり方が書いてあるので、どの方法でやっていただいても結構です。

Docker for Windowsのインストール

https://docs.docker.com/docker-for-windows/install/
よりDocker for Windowsをダウンロードします。
Docker Hubのアカウントが必要ですが、無料ですので作ってしまいましょう。
あとはインストーラーを起動するだけでOKです。

docker-composeのための設定

Win+Rでcmdと入力します %USERPROFILE%になっている(通常C:\Users\[ユーザ名])ことを確認します。
docker-wpディレクトリを作成し、そのディレクトリ内に移動します。

> mkdir docker-wp
> cd docker-wp

docker-compse.ymlのファイルを作ります。
まずはstartコマンドでカレントディレクトリを開きます。

> start .

Explorerが立ち上がるので右クリック等で新規ファイル(テキストドキュメント)を作成し、 F2キー等でdocker-compose.ymlにリネームし、メモ帳等で開き、次の内容を記入します(コピペ) お試し環境のためパスワード等は脆弱な設定になっています。

version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: root
       MYSQL_DATABASE: wp_db
       MYSQL_USER: wp_user
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8080:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_NAME: wp_db
       WORDPRESS_DB_USER: wp_user
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data: {}

簡単に記載していることを説明しますと、
データベースであるMySQLとWordPressを入れるようにするのと、
それぞれデータベースのユーザ名とパスワードを指定しています。
また、HTTPでアクセスするときのポートをデフォルトの80から8080へ変更しています。
あとPC再起動のときなどrestart: alwaysで必ず勝手に立ち上がるようにしています。 それが嫌な場合は毎回手動でdocker-compse up/downをする必要があります。

MySQLは5.7系を使うこととします。WordPressは最新版を使います。

docker-compose.ymlのあるディレクトリでdocker-compose up -dを実行します -dはバックグラウンド実行を意味します。

> docker-compose up -d

このとき、右下にクジラが出てきてShare itってのが出てくるのでそれを押します(押さないとエラーになってしまいます) docker pullコマンドが自動的に実行され、最終的にMySQLとWordPressのプロセスが立ち上がります。 確認のため下記のコマンドを実行します

> docker container ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
1a19e6e913ad        wordpress:latest    "docker-entrypoint.s…"   54 seconds ago      Up 52 seconds       0.0.0.0:8080->80/tcp   docker-wp_wordpress_1
4d4964e58524        mysql:5.7.26        "docker-entrypoint.s…"   55 seconds ago      Up 54 seconds       3306/tcp, 33060/tcp    docker-wp_db_1

このように表示されていればOKです。

Chrome等のブラウザにてhttp://localhost:8080 を押します。

WordPressの初期設定画面に行くはずです。

以降、PCの電源をOFFにしても上記URLをブラウザで入力するとWordPressを使うことができます。
それをやめたい場合はymlファイルを編集するか、下記のコマンドを入力すればOKです。

docker update --restart=no [CONTAINER-ID]

PC再起動時の補足

再起動後、 Docker desktop is running ... と出るまで待ってあげましょう。
横着な人は、タスクバーに隠れてるDocker for WindowsのアイコンのSettingsをみて
Docker is runningになっているのを確認しましょう。
結構起動するまで待たされます。

その後、 http://localhost:8080
と打ってあげるとうまくいきます。

参考リンク

https://docs.docker.com/compose/wordpress/
https://qiita.com/shimisunet/items/1406e33e1eeb36665f2c
https://qiita.com/koyo-miyamura/items/a760dd57160155d3b764

次回はUbuntuでの環境構築を書きたいと思います…(あくまで予定)

GitHubで2段階認証を利用していてhttpでgit cloneできなくなった際の対処法

f:id:fa11enprince:20180728223008j:plain 何台かマシンを所有していて、たまに使うマシンでgit cloneするとユーザ名とパスワードを聞かれて、しかもパスワードを正しいのを入れても

$ git clone https://github.com/foo/private_reop_bar.git
fatal: Authentication failed for 'https://github.com/foo/private_repo_bar.git

となってしまって、何故だと思ったのでメモ。
ところが一方

$ git clone git@github.com:foo/private_repo_bar.git

のsshプロトコルではうまくいきます。
ちなみに2段階認証だけでなく公開鍵認証を使っています。

公開鍵認証が失敗している

そもそも公開鍵認証が失敗している可能性もある方もいると思うのでまずはそちらを疑ってみましょう

ssh -T git@github.com
Hi foo! You've successfully authenticated, but GitHub does not provide shell access.

となればOKです。
ダメな場合は次を疑ってみましょう。

GitHubに公開鍵を登録してない

複数台マシンを使っているとやりがちです。
あれ登録してなかったっけ・・・となります

秘密鍵が読めてない

秘密鍵をいくつかある場合、デフォルトの秘密鍵の名前から変えていることがあり、デフォルトでは

~/.ssh/id_rsa

です。これを~/.ssh/github_id_rsaとかに変えている場合は~/.ssh/configファイルに設定を書いてやらねばなりません。
パーミッションが0600になっていないケースもあります。

ssh-addしてない

Windowsマシンで起こりがちです。
Git Bashなどで

$ eval $(ssh-agent)
$ ssh-add ~/.ssh/id_rsa

を~/.bashrcなどに仕込んでやりましょう

2段階認証でhttpsが使えない

本題のこちら。こちらの場合はPersonal access tokenが必要なようです。
GitHubでProfileページから辿れるDeveloper Settingsの中にあるPersonal access tokensのページにてtokenを設定します。

そうすると40文字のアクセストークンが1度だけ作成時に表示されるのでそれを使いましょう。

参考情報

Githubに接続できない時の対処法 - Qiita
Githubの2段階認証を実施してgitコマンドが使えないときにやったこと - Qiita

フィボナッチ数列でメモ化

f:id:fa11enprince:20190413175245j:plain なんとなくC++をちょろっと書いてみたくなったので書いてみました。
いや、ほぼC言語だけど…。 それよりもWandboxがC++2aとかになってて…えぇ…C++11からかなりバージョン上がってるなぁ…という印象です。

#include <iostream>
#include <cstdlib>
#include <stdexcept>

#define CHECK(e) do { if (e < 0) { throw std::out_of_range("the number must be grater than or equal to 1"); } } while(0)

int x[] = {0, 1};  // fib(0) = 0, fib(1) = 1

/**
 * memoized fibonacci function
 */
int fib_memo(int e) {
    CHECK(e); 
    int ans = 0;
    for (int i = 0; i < e; ++i) {
        ans = x[i%2] + x[(i+1)%2];
        x[(i+1)%2] = ans;  // first, update 2nd index ...
    }
    return ans;
}

/**
 * recursive fibonacci function
 */
int fib_recv(int e) {
    CHECK(e);
    return e == 0 ? 0 : (e == 1 ? 1 : (fib_recv(e - 1) + fib_recv(e - 2)));
}

int main()
{
    using namespace std;
    ios::sync_with_stdio(false);
    try {
       cout << fib_memo(45) << endl;
       //cout << fib_recv(45) << endl;
    } catch (const out_of_range& e) {
       cerr << e.what() << endl;
    }
}

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

cpprefjpをのぞいたらC++11以降の記載がたくさん。。。 なんか見た目が結構変わった気がする…。

片手間でJavaScriptを書く際の定番の書き方メモ

f:id:fa11enprince:20171220162911j:plain ガシガシJavaScriptをかかないWebアプリで、比較的単純なJQueryだけのプロジェクトのときに極力名前空間を汚さず大してめんどくさくなく書く方法のメモ 見返したらただの感想文になってしまった。

とりあえず (function($) { ... })(jQuery);で引数ありの即時関数で包んでその中に愚直に処理を書くのが楽そう。 プロトタイプベースのオブジェクト指向でガシガシ書くのはオワコンっぽいんでとりあえずこんな感じでいいんじゃないでしょうか?
そもそもガシガシ書く場合、少なくともES6以上(or TypeScript)を使うはず。 こんな感じでよいかなと…。 化石のようなプロジェクトで対応する場合、この書き方が良いかと思われる。 関数も大体はオブジェクトリテラルで雑に定義しとけばだいたい事足りると思われる。 とか書いたらフロントエンドやってる人に怒られるかな…。

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    </head>
    <body>
        <div id="test" style="width: 100px; height: 50px; background-color: gray;">
        </div>
        <script src="https://code.jquery.com/jquery-3.3.1.js"
          integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
          crossorigin="anonymous"></script>
        <script>
        jQuery.noConflict();
        (function($) {
          console.log('immediately invoked function start');
          var mainFunc = {
            bindMouseOver: function() {
              $('#test').bind("mouseover", function() {
                alert("onmouseover");
              });
            },
          };
          $(document).ready(function() {
            console.log('ready function start');
            mainFunc.bindMouseOver();
            console.log('ready function end');
          });
          console.log('immediately invoked function end');
        })(jQuery);
        
        // !function($) {
        //   ...
        // } (jQuery)
        // でもOK
        </script>
    </body>
</html>

HTTP/1.1(+ブラウザの組み合わせ)だとリクエストが同時に6までしか飛ばなかったはずなので、 <script>がたくさん増えた場合、まぁ、仕方ないってあきらめるのがいいんでしょうね。 こういうプロジェクトの場合。 いや、webpackとかでbundleしろよってのもあるかもしれない。 うん、ここまで書いて、化石プロジェクトにつぎ足しするとき時間があればwebpack+TypeScriptでいい、という結論になりそう(;^ω^)。いやでもめんどくさい…

ほぼ関係ないけど自分用メモ

blog.redbox.ne.jp

Apache + Spring Bootの環境構築メモ

f:id:fa11enprince:20180508140318j:plain 開発環境での構築手順です。 本番環境ならajpを使ったほうが良いと思います。
組込みTomcat(jar)を使った場合のajpの有効化方法は後述します。
今回は単純にApacheとSpring Bootをhttpで連携する方法を書きます。
Windowsを想定しています。
(Linuxとほぼ変わらないですが、
今回使うApcheのディストリビューションの形式がLinuxの一般的なものと配置などが違っています。)

Spring Bootのjarの準備

単純にmvn install / mvn packageなどすればjarが出来上がります(Mavenの場合)。

Apacheのインストール

入手先がわかりにくいので、
https://httpd.apache.org/download.cgi
Files for Microsoft Windowsのリンクをたどる
https://httpd.apache.org/docs/current/platform/windows.html#down
に飛ぶはずなので、Apache Loungeのリンクを押します。
そうすると、
https://www.apachelounge.com/download/
に飛びますので、 Apache 2.4.38 Win64
をダウンロードします

ダウンロードしたhttpd-2.4.38-win64-VC15.zipを展開します。

httpd-2.4.38-win64-VC15フォルダの中に

Apache24フォルダ
-- Win64 VC15  --
ReadMe.txt

があるので、ReadMe.txtを_ReadMe.txtにリネームしてApache24フォルダに移動させましょう。
リネームしたReadMe.txtは大事なことが書いてあるので一度読んでおきましょう。
-- Win64 VC15 --はどうでもいいのですが、これも一応移動させておきましょう。
あとはApache24フォルダをCドライブ直下に置けばOKです。

Apacheの設定とサービス化

最低限の設定をします。 今回は単純にhttp://localhost:8080をリバースプロクシするだけということにしておきます。

Apache24\conf\httpd.conf

なにやらいっぱいモジュールの設定がコメントアウトされていますが、

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

の2つを有効化するだけでOKです(今回はajpを使いませんが)。
今回DocumentRootの設定は特にいじりません。
htdocsが嫌とかそういうことがあれば変えてください。 Options Indexes FollowSymLinksとかAllowOverride Noneとかなんだっけという方はこちら。
core - Apache HTTP サーバ バージョン 2.4

あと、末尾にTimeOut 3600を付け加えておきます

Apache24\conf\extra\proxy-html.conf

末尾に追加します

# /images/... へのリクエストはプロキシしない(必要に応じて)
ProxyPass /images/ ! 

ProxyPass        / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/

2行目はWebアプリ内部で/imagesでアクセスできるものがあればプロクシしたくないはずなので、 たいていは書くことになるのかなと思います。 具体的にはSpring Boot配下に作ったstatic/imagespublic/imagesが存在するときです。

これらが終われば、管理者でコマンドプロンプトを立ち上げて

C:\Apache24\bin\httpd -t

と打ってSyntax OKとでればサービス化します

C:\Apache24\bin\httpd -k install

でおしまいです。サービス一覧で確認すると起動していると思います。

組込みTomcatでのajp有効化方法

SpringBootでAJPを通してみる | hiloの情報発信局 によると下記のように書くとできるそうです。 おそらくSpring Boot 1でも2でも同じでないでしょうか。実はここ検証してません。

import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import java.util.Optional;
 
@Configuration
public class AppConfig {
 
    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainer() {
        return server ->
            Optional.ofNullable(server)
                    .ifPresent(s -> s.addAdditionalTomcatConnectors(redirectConnector()));
    }
 
    private Connector redirectConnector() {
        Connector connector = new Connector("AJP/1.3");
        connector.setScheme("http");
        connector.setPort(8009);
        connector.setRedirectPort(8443);
        connector.setSecure(false);
        connector.setAllowTrace(false);
        return connector;
    }
}

この場合設定ファイルを

ProxyPass        / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/

とするだけです。 検証したら追記・修正するかも…。

そもそもAJPとは

ざっくりいうとAJPのほうが早いらしくHTTPのようなオーバヘッドがない。
Apache HTTP ServerとTomcat間をバイナリでやり取りするとのこと。