【完成版】DockerにPHP+Apache+MySQL開発環境を設定してみた

DockerPHP+Apache+MySQL開発環境を設定する方法を、最終的にDocker Composeにまとめて構築するまでを模索する。
今回は目次を見れば分かるように、非常に長い話なので、休み休み一読していただきたい。



開発環境

  • マシン:MacBook Pro
  • OS:macOS Big Sur(11.6.3)
  • 仮想環境:Docker Desktop(4.4.2 (73305))
  • Docker Engine:20.10.12
  • Docker Compose:2.2.3
  • エディタ:Sublime Text(Build 4126)
  • php:8.1.2
  • Xdebug:3.1.3
  • Apache:2.4.52
  • MySQL:8.0.28
  • phpMyAdmin:5.1.3(TerminalでMySQLを確認するより楽なので導入)


【必要】Docker Desktopをインストール

Docker Desktopをインストールしていない場合は、下記ブログの1と2を参考にしていただければ。

MacにDockerをインストールしPythonが使えるまでのまとめ【初心者向け】

初心者がDockerをインストールするのはハードルが高いですよね。初心者である筆者がDockerのインストール方法を調べて試してみたのでその手順を公開します。用語については、理解しないままとりあえず放置します。理解しようと用語を調べだしたらそれに時間を取られてインストールに進めないので。



階層構成

今回作成したフォルダ及びファイルの階層構造は以下の通り。
この階層構造を元に各ファイル内容を作成しているので、もし階層構造を変更した場合、各ファイル内容も変更する必要があることに注意。

php_test
	└data   # MySQLデータ保存用
	└docker-compose.yml
	└mysql
	│└Dockerfile
	│└my.cnf
	│└sql   # MySQLへインポートするファイル収納用
	│	└init.sql    # テスト用データベースデータ
	│
	└php
	│└Dockerfile
	│└log   # Apache、Xdebugログ保存用
	│└php.ini
	│└xdebug.ini
	│
	└phpmyadmin
	│└phpmyadmin-misc.ini    # データベースファイルのインポート可能容量を変更設定用
	│└sessions
	│
	└src
		└db_connect_test.php    # テスト用
		└index.php    # phpの情報ページ
		└xdebug.php    # xdebugの表示用


事前準備―各種ファイルの設定

php.iniの準備

PHP用の設定ファイルのこと。
以下の作業を進める。

  1. PHP公式サイトに行く
  2. PHPの最新版の圧縮ファイルをダウンロード後解凍
  3. php-X.X.Xフォルダ内の「php.ini-development」ファイルを複製
  4. 複製した「php.ini-development」ファイル名を「php.ini」に変更

(※上記2つの画像はPHP 8.1.0のもの)


こちらを参考にした。

php.iniファイルの作成と初期設定

PHP に関する設定を記述する php.ini ファイルはデフォルトでは作成されていません。用意されている雛形を使って新しく作成する必要があります。ここでは php.ini ファイルの作成方法、 php.ini ファイルに対して行っておく初期設定、および php.ini の設定内容を確認するための phpinfo 関数の使い方について解説します。



php.iniの修正

php.iniをテキストエディタ(筆者はSublime Textを使用)で開き、下記設定を検索し修正する。
なお、php.ini内では行頭に「;」を付けるとコメントになることに留意する。

  • upload_max_filesize = 2M → 128M
  • post_max_size = 8M → 128M
  • 596行目に、「error_log = /dev/stderr」を追加
    (コンテナ内で動作しているプロセスのログの標準エラー出力先)
  • 971行目の「;date.timezone =」を「date.timezone = Asia/Tokyo」に差替え、「;」は削除
  • 1628行目の「;mbstring.language = Japanese」から「;」を削除
  • 1637行目の「;mbstring.internal_encoding = UTF-8」から「;」を削除→PHP 8以降は非推奨なので「;」は削除しない。
  • mbstring.internal_encodingの代わりにinternal_encodingを使用のこととあるが、未設定時はdefault_charset=UTF-8に従うので、internal_encodingは未設定のままに。PHP公式サイトにもその記載あり。
  • 1668行目の「;mbstring.detect_order = UTF-8,SJIS,EUC-JP,JIS,ASCII」を設定、「;」を削除
  • 「;zend_extension=opcache」の次行に「zend_extension=xdebug」を追加(xdebug用の設定)

こちらを参考にした。

php.iniの編集 - Qiita

文字コードとタイムゾーンを指定するため、php.iniを編集します。



xdebugの設定

デバッグ実行もしてみたいので、php.iniにxdebug用の設定を追加。
→【2022.2.15追加】xdebug用のxdebug.iniを別途用意。

新規ファイルに、以下を記入。

[xdebug]
xdebug.client_host = host.docker.internal
xdebug.client_port = 8010
xdebug.mode = debug
xdebug.remote_handler = dbgp
xdebug.start_with_request = yes
xdebug.discover_client_host = false
xdebug.log = /var/log/xdebug.log
  • 1行目ホストのアドレスを設定。Docker Composeでの設定と同じにする。
    コンテナからホスト上のサービスに接続したい時に指定する特別なDNS名である。
  • 2行目ホストのポート番号を設定。Docker Composeでの設定と同じにする。
  • 3行目:Step Debuggingのみがアクティブであるように設定。
  • 4行目:「Xdebugのステップデバッガーは DBGPハンドラー のみをサポート」とのこと。
  • 5行目:デバッガーを自動で開始する。
  • 6行目:ホストのアドレスを探す機能を停止。1行目を設定しているので。
  • 7行目:Xdebugのログを収集する場所を指定。

以上を設定しないと、Xdebugのログに「error」や「warn」が吐き出される

php用Dockerfileの作成

FROM php:apache

COPY ./php.ini /usr/local/etc/php/php.ini
		
RUN apt-get update \
&& apt-get install -y libonig-dev libzip-dev unzip\
&& docker-php-ext-install pdo_mysql mbstring zip bcmath\
&& pecl install xdebug\
&& docker-php-ext-enable xdebug

RUN echo "ServerName localhost" | tee /etc/apache2/conf-available/fqdn.conf
RUN a2enconf fqdn
  • 1行目php公式Docker Imageを使用。バージョンは最新版を導入するのでTagは「:apache」にした。
  • 3行目前項で修正したphp.iniの階層(ディレクトリ)と、コンテナ内に作成されるphp.iniとを関連付けさせて、修正したphp.iniに置き換えている。→docker composeファイルのvolumesで紐付けるので不要
  • 7行目mbstringは、PHPの処理の中でmb系のマルチバイト文字を取り扱う為に必要。
  • 7行目bcmathは、Math関数を扱う為に導入。必須ではない。


my.cnfの作成

MySQL公式Docker Imageから、my.cnf自分のPCに複製することにする。

  1. Docker Desktopを立ち上げる
  2. Terminalを開く
  3. 以下のコマンドを入力し、MySQLの公式imageをpullする
    $ docker image pull mysql:latest
  4. コンテナを作成する。
    $ docker container run -e MYSQL_ROOT_PASSWORD=sample_pw --name mysql -d mysql:latest
  5. コンテナの中に入る
    $ docker exec -it mysql bash
  6. コンテナの中に入ると、Terminalの最終行は以下のようになる
    root@xxxxxxxx:/#
    (「xxxxxxxx」はコンテナID。「32e4dba626f1」のような文字列)
  7. 以下のコマンドを入力し、コンテナ内にmy.cnf があることを確認
    # ls /etc/mysql/my.cnf
    /etc/mysql/my.cnf
  8. コンテナを抜ける
    # exit
  9. my.cnfを自分のPCに複製する。
    mysqlはコンテナ名、/etc/mysql/my.cnfはmy.cnfのある場所、~/Desktop/は複製したmy.cnfの保存場所)
    $ docker container cp mysql:/etc/mysql/my.cnf ~/Desktop/
  10. コピーしたmy.cnf をテキストエディタで開き、以下を追加。
    [mysqld]
    (既存の3行あり)
    character-set-server=utf8mb4 #MySQLサーバーの文字エンコーディングを指定
    collation-server=utf8mb4_general_ci #MySQLサーバーの照合順序を指定
    secure-file-priv = /docker-entrypoint-initdb.d #MySQLサーバーのインポート・エクスポート可能ディレクトリの指定
    
    [mysql]
    default-character-set=utf8mb4
    
    [client]
    default-character-set=utf8mb4
修正前
修正後

こちらを参考にした。

【Mac/Win対応】DockerでPHPローカル開発環境の最強構築方法

こんにちは、タカフです。 Dockerでローカルマシンに開発環境を構築する時の悩み・やりたいことって色々ありますよね。 例えば僕の場合はこんな感じです。 コマンド一発でローカルマシンにLAMP開発環境を作りたい おなじみ ...

また、「secure-file-priv」については、以下を参照のこと。

PythonでMySQLにCSVファイルをインポートする【Docker & Jupyterlab環境】

郵便番号データをMySQLに追加する操作をPythonでしてみようと思い立ち実践するも様々なエラーに出くわしつつも無事インポートできるまでを報告。これをDocker & Jupyterlab環境で行った。



mysql用Dockerfileの作成

FROM mysql:latest

COPY ./my.cnf /etc/mysql/conf.d/my.cnf

RUN apt-get update && apt-get install -y locales \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*
  
RUN sed -i -E 's/# (ja_JP.UTF-8)/\1/' /etc/locale.gen \
  && locale-gen
  
ENV LANG ja_JP.UTF-8

CMD ["mysqld", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_general_ci"]


稼働確認用データベースファイルの作成

MySQLの稼働確認用のデータベースファイル(init.sql)を作成。
「sample_table」というテーブル名は任意。

DROP TABLE IF EXISTS sample_table;

CREATE TABLE sample_table (
	id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
	name TEXT NOT NULL
) ENGINE InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

INSERT INTO sample_table (name) VALUES ("昭和"),("平成"),("令和");


検証用PHPファイルの作成

検証用のindex.phpを作成。
Docker ImageとContainerの作成後にhttp://localhost:8010/にアクセスした時に表示される。

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<title>php-apache</title>
</head>
<body>
	<?php
	echo  __DIR__;
	phpinfo();
	?>
</body>
</html>


mysql接続確認用ファイルの作成

MySQLへの接続確認用のdb_connect_test.phpも用意
Docker ImageとContainerの作成後にhttp://localhost:8010/db_connect_test.phpにアクセスした時、init.sqlで作成したsample_tableが表示される。

<?php
				
try {
	// DB接続設定
	$dsn = 'mysql:host=mysql;dbname=test_db;';
	$db = new PDO($dsn, 'test_db_docker', 'test_db_docker_pass');
				
	// SQL実行
	$sql = 'SELECT * FROM sample_table;';
	$stmt = $db->prepare($sql);
	$stmt->execute();
	$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
				
	// デバッグ
	var_dump($result);
				
} catch (PDOException $e) {
	echo $e->getMessage();
	exit;
}


Xdebug検証用のxdebug.phpの作成

Xdebugの稼働が確認できるxdebug.phpも用意
Docker ImageとContainerの作成後にhttp://localhost:8010/xdebug.phpにアクセスした時、$samuraiは定義されていないのでエラー表示が出る。

<?php
	echo $samurai;
?>


docker-composeの作成

さて、以上の準備が整ったところで、docker-composeを作成する。
参照元を参考に作成したが、一部更新すべき箇所などがあるので、その点などの解説もしていく。
docker-composeは以下の通りである。

version: "3.8"
services:
  php:
	build:
	  context: ./php
	  dockerfile: Dockerfile
	volumes:
	  - ./src:/var/www/html
	  - ./php/log:/var/log
	  - ./php/php.ini:/usr/local/etc/php/php.ini
	  - ./php/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini #【2022.2.16追加】
	ports:
	  - 8010:80
	restart: always
	depends_on:
	  - mysql
	image: php
	container_name: php

  mysql:
	build:
	  context: ./mysql
	  dockerfile: Dockerfile
	volumes:
	  # データ永続化
	  # MySQL Database初期化用SQLを./mysql/sqlに配置します。
	  - ./mysql/sql:/docker-entrypoint-initdb.d
	  # MySQLの内容を./dataディレクトリに保持します。
	  - ./data:/var/lib/mysql
	  - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
	ports:
	  - 3306:3306
	environment:
	  MYSQL_ROOT_USER: root
		# Rootユーザーを、パスワードなしでMySQLへのログインを許可します。
		# MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
		# MySQLのRootユーザーのパスワードを設定する場合は、
		# MYSQL_ALLOW_EMPTY_PASSWORDをコメントアウトし、MYSQL_ROOT_PASSWORDでパスワードを指定します。
	  MYSQL_ROOT_PASSWORD: root
	  # Database名称の指定
	  MYSQL_DATABASE: test_db
	  # 作業用MySQLユーザー名称の指定
	  MYSQL_USER: test_db_docker
	  # 作業用MySQLユーザーパスワードの指定
	  MYSQL_PASSWORD: test_db_docker_pass
	image: mysql
	container_name: mysql
	restart: always

  phpmyadmin:
	image: phpmyadmin:latest
	environment:
	  # - PMA_ARBITRARY=1
	  - PMA_HOST=mysql
	  - PMA_USER=root
	  - PMA_PASSWORD=root
	ports:
	  - "8080:80"
	volumes:
	  - ./phpmyadmin/sessions:/sessions
    	#【↓2022.2.16追加:phpMyAdminでデータベースファイルのインポート可能容量を変更するiniファイル】
	  - ./phpmyadmin/phpmyadmin-misc.ini:/usr/local/etc/php/conf.d/phpmyadmin-misc.ini
	depends_on:
	  - mysql
	links:
	  - mysql
	container_name: phpmyadmin
	restart: always
  • 51行目phpmyadmin imageは、「phpmyadmin/phpmyadmin」を指定しているブログもあるが、こちらは現在Official Imageのマークが外れて、代わりに「phpmyadmin」がOfficialになっているので、最新版を表す「:latest」tagと共に「phpmyadmin:latest」を指定する。
    バージョンを固定したい場合は、「:latest」tagの代わりに「:5.1.1」「:5.1」「:5」tagなどに変更する。
  • 53行目:PMA_ARBITRARYは、「PMA_ARBITRARY=1」のとき、ログインフォームでデータベースサーバのホスト名を入力できるようにする。複数のDBサーバを設定している時に必要。
    そのときは、54行目の「PMA_HOST」に代えて「PMA_HOSTS」にし、カンマ区切りで、使用するデータベースサーバのホスト名またはIPアドレスを指定する。
    このように複数のデータベースサーバを設定している時は他の設定(PMA_USERやPMA_PASSWORDな、)にも注意
    (ここでは数のデータベースサーバを設定している時のdocker-composeの設定方法は詳述しない)。
    今回は単数のデータベースサーバなので、コメントアウトして無効にしている。
  • 54行目:PMA_HOSTは、20行目で設定したservisesの名前を(この場合はmysql。40行目のMYSQL_DATABASEの値ではないので注意)。
  • 55行目:PMA_USERは、34行目のMYSQL_ROOT_USERの値に同じ。
  • 56行目:PMA_PASSWORDも、39行目のMYSQL_ROOT_PASSWORDの値に同じ。
  • PMA_USERとPMA_PASSWORDとをdocker-composeに設定しておくと、ユーザー名とパスワードを入力せずにphpmyadminにアクセスできるようになる。
  • 57–58行目:portsは8080:80を指定。
    phpmyadmin公式imageページの解説で例として挙げられているのをそのまま使用。

以下を参考にした。

※phpmyadminの設定をdocker-composeに追加する方法

Docker Composeでphpmyadminを導入する

Docker Composeでphpmyadminを導入する方法を紹介します。Docker Composeでphpでmysqlにアクセスするで作成した環境に対して修正を行っていきます。phpmyadminのコンテナを作成します。localhost:3000でphpmyadminの管理画面にアクセスできるように設定しています。セッション情報をボリュームに設定して永続化するようにします。コンテナを起動後、localhost:3000にアクセスするとphpmyadminの管理画面が表示されることを確認できます。


※xdebugの設定をphp.iniとdocker-composeに追加する方法

Dockerで作るNginx + PHP7 + Xdebug環境

docker-composeでNginx + PHP7 + Xdebugの環境がすぐに立ち上げるように設定を作ります。また、VSCodeでXdebugを動くように設定もします。


※docker-composeでのphpmyadminの設定方法について

phpmyadmin - Official Image | Docker Hub

phpMyAdmin - A web interface for MySQL and MariaDB.


※phpMyAdminのDocker の環境変数



ImageとContainerの作成

これでようやく自動でImageとContainerの作成ができるようになった。

作成方法は、まずTerminalを起動し、TerminalにてDocker Composeのある階層に移動する。自分の場合は、Docker Composeはデスクトップ上のphp_testフォルダ内にあるので、Terminalに

$ cd ~/Desktop/php_test

と打ち込みphp_testフォルダ内に移動。

次に、

$ docker-compose up -d --build

と打ち込むと、ImageとContainerの作成に進む。
数分で作成が完了するので、ImageとContainerが作成されているかを確認する。

新規にTerminalを立ち上げて、

$ docker images

と打ち込むと、作成済みのImageの一覧が現れる。ここに指定した名前のImageがあれば作成成功。

次に、Terminalに

$ docker ps -a

と打ち込むと、作成済みのContainerの一覧が現れる。ここに指定した名前のContainerがあれば作成成功。



また、Docker Desktopがバージョンアップしたことで、Docker DesktopのDashboardにてDocker ImgeおよびContainerの閲覧と削除が簡単に出来るようにもなった。



コンテナ作成が成功したかの確認

PHP-Apacheコンテナの確認

http://localhost:8010にアクセスし、以下の画面が出れば成功している。
実際は、先に作成したindex.phpが表示されている。



mysqlコンテナの確認 その1

http://localhost:8010/db_connect_test.phpにアクセスし、以下の画面が出ればmysqlも成功している。
(db_connect_test.phpは、mysql検証用に予め作成していたファイル)

mysqlコンテナの確認 その2

または、Terminalで確認する方法もある。


コンテナにログイン

$ docker exec -it (mysqlのあるコンテナIDまたはコンテナ名) /bin/bash

MySQL にログイン

root@(コンテナID):/# mysql -p
Enter password:root

docker-composeで設定した「MYSQL_ROOT_PASSWORD: root」の「root」を入力しエンターキーを押すとmysqlに入れる。

mysql> show databases;

すると以下の表が現れる。

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test_db            |
+--------------------+
5 rows in set (0.01 sec)

表の中に、docker composeの50行目に設定したデータベース名(test_db)が表示されるので、それを以下のコマンドに追加する。

mysql> use test_db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

以下のコマンドでtest_dbを表示させる。

mysql> show tables;
+-------------------+
| Tables_in_test_db |
+-------------------+
| sample_table      |
+-------------------+
1 row in set (0.01 sec)

test_dbの中の表名(sample_table)が表示されるので、以下のコマンドでsample_tableを表示させる。(※sample_tableは、init.sqlを作成したときに命名したもの)

mysql> select * from sample_table;
+----+--------+
| id | name   |
+----+--------+
|  1 | 昭和   |
|  2 | 平成   |
|  3 | 令和   |
+----+--------+
3 rows in set (0.00 sec)

このように、sample_tableが表示される。

mysqlの中から出る。

mysql> exit;
Bye
root@(コンテナID):/#

ここまで出来たら、Terminal上でもmysqlの稼働を確認できる。



mysqlコンテナの確認 その3

もう1つ、phpMyAdminで確認する方法もある。
http://localhost:8080にアクセスし、phpMyAdminの画面左の「test_db」をクリック、「sample_table」をクリックしテーブルの中身をみる。



Xdebugの動作確認

http://localhost:8010にアクセスし、Xdebugの表が現れていれば、Xdebugのインストールは成功している。

しかし、接続できない旨のメッセージが出た場合、上手く接続できていないことがわかる。

xdebug poll success but error operation now in progress (29)
xdebug Could not connect to debugging client.

その場合、php.iniのxdebugの設定を以下のように書き換える。

  • 「zend_extension=xdebug」を追加。#追加済み
  • 「xdebug.mode=debug」「xdebug.start_with_request=yes」の順に行を差替え。#変更済み
  • 「xdebug.start_with_request=yes」を「xdebug.start_with_request=trigger」に変更。
  • phpのDockerfileの「COPY ./php.ini /usr/local/etc/php/」を「COPY ./php.ini /usr/local/etc/php/php.ini」に書き換え

以上の変更を行い、既に作成したDocker ImageとContainersを全削除し、再度作成した結果、無事インストールされ、http://localhost:8010にアクセスしてもメッセージは表出していなかった。


以下を参考にした。

Docker+WordPress+PhpStormでXdebugを使う手順 | 株式会社LIG

バックエンドエンジニアの小林が「Docker+WordPress+PhpStorm」の環境でXdebugを使う手順を紹介します。WordPressでXdebugでステップデバッグを利用すると、複雑に入り組んだフックでも簡単に調査ができるようになり、とても便利です!



phpMyAdminの動作確認

http://localhost:8080にアクセスし、phpMyAdminの画面が現れれば、phpMyAdminのインストールは成功している。



Apacheのエラーログの解決

一通り設定すると、php/logフォルダ内にapache2フォルダが自動で作成され、apache2フォルダ内にerror.logが生成されていた。

AH00558: apache2: Could not reliably determine the server's fully qualified domain name, (以下略)

この解決方法は、phpのDockerfileに以下を追加する。

RUN echo "ServerName localhost" | tee /etc/apache2/conf-available/fqdn.conf #追加済み
RUN a2enconf fqdn #追加済み

以下を参考にした。



mbstring.internal_encodingの無効化

PHP Deprecated:  PHP Startup: Use of mbstring.internal_encoding is deprecated in Unknown on line 0

mbstring.internal_encoding は PHP 8.0.0 から削除されたようなので、php.ini内のmbstring.internal_encoding の項目を「; 」でコメントアウトする。

mbstring.internal_encoding 設定は PHP 5.6.0 以降から非推奨だったらしい。

以下を参考にした。

【PHP8】PHP Deprecated: PHP Startup: Use of mbstring.internal_encoding is deprecated - Qiita

PHP 8 で、mbstring を有効にすると mbstring.internal_encoding is deprecated と表示される。
$ docker run --rm -it keinos/php8-jit /bi...



phpの試行方法

実際にphpを試すには、コンテナを稼働させ、最初に作成したsrcフォルダに試したいphpファイルを入れ、ブラウザのURL欄に、

http://localhost:8010/(試したいphpファイル名)

と入力する。
例えば、試したいphpファイル名がtest.phpとすると、URLは以下のようになる。

http://localhost:8010/test.php


Tips

xdebug.soのある場所の確認方法

http://localhost:8010/にアクセスし、以下の画面内Coreの部分のextension_dirの部分に記載されているパス(以下、「記載パス」と呼ぶ)に、xdebug.soが配置されている。
「記載パス」は「/usr/local/lib/php/extensions/no-debug-non-zts-20200930」のように結構長い。


・Terminalにて、PHPをインストールしたコンテナ内に入る

$ docker ps -a
#コンテナの一覧を表示し、該当コンテナのコンテナ名を確認できる
$ docker restart {コンテナ名またはID}
	該当コンテナが稼働していない時(Exited)に稼働させるコマンド
$ docker exec -it {コンテナ名} bash
該当コンテナ内に入る

・該当コンテナ内のファイル一覧を表示させ、xdebug.soがあることを確認する

# ls {記載パス}


全体の参照元

docker-compose を用いて Apache・PHP・MySQL の開発環境を構築してみた - Qiita

docker-compose を用いて Apache・PHP・MySQL の開発環境を構築してみた備忘録になります。

docker compose PHP Apache MySQL 環境 作成 - しすろぐ

docker compose PHP Apache MySQL 環境 作成 今回は、 docker compose で、 php apache mysql の 開発 環境 をまとめて作成した際のメモとなります。 色々とはまりどころがあったため、逐一追記したいと思います。

【Mac/Win対応】DockerでPHPローカル開発環境の最強構築方法

こんにちは、タカフです。 Dockerでローカルマシンに開発環境を構築する時の悩み・やりたいことって色々ありますよね。 例えば僕の場合はこんな感じです。 コマンド一発でローカルマシンにLAMP開発環境を作りたい おなじみ ...





コメント

よく読まれている記事

CSSボタンでテキストを天地中央に揃えるとき、なぜボタン高と行高を一緒にするのか

FullCalendarの導入からカレンダー毎の色指定まで

FacebookページのフィードURLを取得しウォールを自サイトに表示