それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

uwsgi で php を動かす

uwsgi にphp プラグインがあります。

uwsgi とはPythonのイメージですが、php-fpm の代わりに使えます。(多分使うことは殆ど無いだろうけど)

uwsgi で管理するメリット

docker のイメージを作るときに php-fpmが混ざると共通化されないけど、uwsgi だとある程度は共通化されるかなと

準備

今回は debian で行います。

sudo apt install uwsgi
sudo apt install uwsgi-plugin-php

uwsgi の設定フォルダ

debian のお作法っぽく enabled と available が作られています。

takuya@:~$ ll /etc/uwsgi/
合計 8.0K
drwxr-xr-x 2 root root 4.0K 2018-08-07 23:47 apps-available
drwxr-xr-x 2 root root 4.0K 2018-08-08 00:11 apps-enabled

phpを起動する uwsgi設定を作ります。

今回は、ざざっと /var/www/virtualhosts/sample/ に作ったindex.phpを起動します。

apps-available/phpinfo.ini

; vim: set ft=dosini expandtab shiftwidth=2 tabstop=2 :

[uwsgi]

route = .* addheader:Server: my uWSGI server
plugins = http,0:php
php-sapi-name = apache

; set master process name and socket
; '%n' refers to the name of this configuration file without extension
procname-master = uwsgi %n
master = true
socket = /run/uwsgi/%n.sock
chown-socket = www-data:www-data

; drop privileges
uid    = www-data
gid    = www-data
; umask  = 027

; run with at least 1 process but increase up to 4 when needed
processes = 4
cheaper = 1

; reload whenever this config file changes
; %p is the full path of the current config file
touch-reload = %p
php-docroot     =  /var/www/virtualhosts/sample/
php-allowed-ext = .php
php-index = index.php
# php.ini
php-set = date.timezone=Asia/Tokyo
php-set = expose_php=false
## extensions
php-set = extension=gd.so
php-set = extension=iconv.so
php-set = extension=pdo_sqlite.so
php-set = extension=pdo_mysql.so
php-set = extension=pdo_pgsql.so
php-set = extension=curl.so
php-set = extension=bz2.so
php-set = extension=intl.so
php-set = extension=ldap.so
php-set = extension=ftp.so
php-set = extension=imap.so
php-set = extension=exif.so
php-set = extension=gmp.so
php-set = extension=imagick.so

; opcache
php-set = zend_extension=opcache.so
php-set = opcache.enable=1
php-set = opcache.enable_cli=1
php-set = opcache.interned_strings_buffer=8
php-set = opcache.max_accelerated_files=10000
php-set = opcache.memory_consumption=128
php-set = opcache.save_comments=1
php-set = opcache.revalidate_freq=2
; apcu
php-set = extension=apcu.so
php-set = apc.ttl=7200
php-set = apc.enable_cli=1

設定を有効にします。

$ cd /etc/uwsgi/apps-enabled
$ sudo ln -sr ../apps-available/phpinfo.ini ./
$ ll
合計 4.0K
-rw-r--r-- 1 root root 424 2018-03-17 17:05 README
lrwxrwxrwx 1 root root  29 2018-08-08 17:07 phpinfo.ini -> ../apps-available/phpinfo.ini

systemctl で起動します

sudo systemctl  restart  uwsgi.service

uwsgiログを確認します。

takuya@:apps-enabled$ sudo systemctl  status   uwsgi.service
● uwsgi.service - LSB: Start/stop uWSGI server instance(s)
   Loaded: loaded (/etc/init.d/uwsgi; generated; vendor preset: enabled)
   Active: active (running) since Wed 2018-08-08 18:15:55 JST; 1min 24s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 11654 ExecStop=/etc/init.d/uwsgi stop (code=exited, status=0/SUCCESS)
  Process: 11694 ExecStart=/etc/init.d/uwsgi start (code=exited, status=0/SUCCESS)
    Tasks: 3 (limit: 4915)
   Memory: 31.4M
      CPU: 205ms
   CGroup: /system.slice/uwsgi.service
           ├─11806 uwsgi phpinfo
           ├─11812 uWSGI worker 1
           └─11813 uWSGI http 1

 8月 08 18:15:55 acid systemd[1]: Starting LSB: Start/stop uWSGI server instance(s)...
 8月 08 18:15:55 acid uwsgi[11694]: Starting app server(s): uwsgi -> . done.
 8月 08 18:15:55 acid systemd[1]: Started LSB: Start/stop uWSGI server instance(s).

設定したphpのログを確認します

ログファイルの場所は /var/log/uwsgi/app/%n.logです。

takuya@:~$ sudo tail -f  /var/log/uwsgi/app/phpinfo.log
Wed Aug  8 18:15:55 2018 - PHP document root set to /var/www/virtualhosts/sample
Wed Aug  8 18:15:55 2018 - PHP 7.0.27-0+deb9u1 initialized
Wed Aug  8 18:15:55 2018 - your server socket listen backlog is limited to 100 connections
Wed Aug  8 18:15:55 2018 - your mercy for graceful operations on workers is 60 seconds
Wed Aug  8 18:15:55 2018 - mapped 363840 bytes (355 KB) for 4 cores
Wed Aug  8 18:15:55 2018 - *** Operational MODE: preforking ***
Wed Aug  8 18:15:55 2018 - *** no app loaded. going in full dynamic mode ***
Wed Aug  8 18:15:55 2018 - *** uWSGI is running in multiple interpreter mode ***
Wed Aug  8 18:15:55 2018 - spawned uWSGI master process (pid: 11806)
Wed Aug  8 18:15:55 2018 - spawned uWSGI worker 1 (pid: 11812, cores: 1)
Wed Aug  8 18:15:55 2018 - spawned uWSGI http 1 (pid: 11813)
[pid: 11812|app: -1|req: -1/1] 192.168.2.107 () {40 vars in 969 bytes} [Wed Aug  8 18:16:11 2018] GET / => generated 107674 bytes in 116 msecs (HTTP/1.1 200) 2 headers in 84 bytes (0 switches on core 0)
[pid: 11812|app: -1|req: -1/2] 192.168.2.107 () {40 vars in 950 bytes} [Wed Aug  8 18:16:12 2018] GET /favicon.ico => generated 9 bytes in 0 msecs (HTTP/1.1 404) 3 headers in 96 bytes (0 switches on core 0)
[pid: 11812|app: -1|req: -1/3] 192.168.2.107 () {42 vars in 1000 bytes} [Wed Aug  8 18:16:13 2018] GET / => generated 107761 bytes in 6 msecs (HTTP/1.1 200) 2 headers in 84 bytes (0 switches on core 0)

ブラウザでチェックします。

Server API uWSGI/php になっているはずです。

f:id:takuya_1st:20180808181938p:plain

index.php に全部渡す

uwsgi はプラグイン構成なので、プラグインrewrite で /aaa を index.php に渡してあげる。

[uwsgi]
plugins = router_rewrite,http,0:php
route = ^ rewrite:/index.php

もちろん PATH_INFOしてもいいんだけど、rewriteが楽かな。

f:id:takuya_1st:20180808184221p:plain

フロントサーバーと連携する

これだけだと、何の役に立つのかわからないんので nginx と連携させてみる。

uwsgi を使うメリットの一つは、UNIXドメインソケットをListenできるところ。

uwsgi/app-enabled/phpinfo.php

[uwsgi]
plugins = router_rewrite,php
php-sapi-name = apache

route = ^ rewrite:/index.php
route = .* addheader:Server: my uWSGI server
master = true
socket = /run/uwsgi/%n.sock
chown-socket = www-data:www-data

nginx

 location ~ {
      include uwsgi_params;
      uwsgi_modifier1 14;
      uwsgi_pass unix:/run/uwsgi/phpinfo.sock;
  }

これで、ngix -----unix:sock ---> uwsgi が完成する

php-plugin を使うと

uwsgi 単独で実行環境が作成されます。

uWSGI というアプリケーションのコンテナとして統一感があるのが魅力だと思います。

  • docker php の配布アプリに nginx を含めなくて良くなる。
  • phpアプリケーションの起動を ugwsgi に任せられる。
  • phpのバージョンを変えられる。
  • httpdの実行ユーザーを変えられる。

などあります。

要は、phpが多数起動できるのでアプリケーション独立には本当に便利だと思います。

Dockerfileでちまちまやってられるか、とかdocker-compose で複数イメージを連携させるよりずっと管理が楽です。

php-fpm で2つ設定書いて2つ起動すればいいだろ?」といわれた何もいえねー。

phpにはいろいろな実行環境があります。

ほんとカオスですね。

uwsgiを使っておけば rubypython とかjs とかすべて同じように扱えるしノウハウも流用しやすいのでいいんじゃないかって思ったり。

参考資料