├── .env-dist
├── .gitignore
├── .gitlab-ci.yml
├── Makefile
├── README.md
├── docker-compose.yml
├── nginx
├── Dockerfile-fpm-nginx
└── image-files
│ ├── etc
│ ├── nginx
│ │ ├── conf.d
│ │ │ └── default.conf
│ │ ├── nginx.conf
│ │ └── ssl
│ │ │ ├── nginx-selfsigned.crt
│ │ │ └── nginx-selfsigned.key
│ └── supervisor
│ │ ├── conf.d
│ │ ├── fpm.conf
│ │ └── nginx.conf
│ │ └── supervisord.conf
│ ├── root
│ └── .bashrc
│ └── usr
│ └── local
│ ├── bin
│ ├── composer
│ ├── docker-entrypoint.sh
│ └── docker-run.sh
│ └── etc
│ └── php
│ ├── conf.d
│ └── base.ini
│ ├── php-fpm.conf
│ └── pool.d
│ └── www.conf
└── test
├── app
└── web
│ └── index.php
├── debug.sh
├── dev.sh
├── prod.sh
├── requirements.php
└── requirements
├── YiiRequirementChecker.php
├── requirements.php
└── views
├── console
└── index.php
└── web
├── css.php
└── index.php
/.env-dist:
--------------------------------------------------------------------------------
1 | PHP_IMAGE_NAME=local/dmstr/php-yii2
2 | GITHUB_API_TOKEN=0000000000000000000000000000000000000000
3 |
4 | PHP_BASE_IMAGE_VERSION=8.0
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | stages:
2 | - build
3 | - test
4 | - release
5 | - cleanup
6 |
7 | variables:
8 | PHP_IMAGE_NAME: dmstr/php-yii2
9 |
10 | before_script:
11 | - export ISOLATION=buildpipeline${CI_PIPELINE_ID}
12 | - export COMPOSE_PROJECT_NAME=${ISOLATION}${CI_BUILD_NAME}
13 | - export PHP_BASE_IMAGE_VERSION=8.1
14 | - export STACK_PHP_IMAGE=${PHP_IMAGE_NAME}:${PHP_BASE_IMAGE_VERSION}
15 | - export REGISTRY_PHP_IMAGE=${PHP_IMAGE_NAME}:${CI_BUILD_REF_NAME}
16 | - export REGISTRY_PHP_IMAGE_LATEST=${PHP_IMAGE_NAME}:latest
17 | - echo "Build-environment information"
18 | # Docker >= 17.05 required for dynamic FROM references
19 | - docker version
20 | - docker-compose config
21 | - docker images ${PHP_IMAGE_NAME}
22 |
23 | after_script:
24 | - export ISOLATION=buildpipeline${CI_PIPELINE_ID}
25 | - export COMPOSE_PROJECT_NAME=${ISOLATION}${CI_BUILD_NAME}
26 | - docker-compose down -v
27 |
28 |
29 | test:php:
30 | stage: test
31 | script:
32 | - export PHP_SERVICE=php-nginx
33 | - sh test/prod.sh
34 | - sh test/dev.sh
35 | - sh test/debug.sh
36 | - docker-compose run --rm php-nginx php /test/requirements.php
37 |
38 | test:php:allow-fail:
39 | stage: test
40 | script:
41 | - docker-compose run --rm php-nginx sh -c 'composer diagnose'
42 | allow_failure: true
43 | except:
44 | - tags
45 |
46 |
47 | build:php-nginx:
48 | stage: build
49 | script:
50 | - cd nginx
51 | # use locally built image
52 | - docker-compose build php-nginx
53 |
54 | test:php-nginx:
55 | stage: test
56 | script:
57 | - docker-compose run --rm php-nginx nginx -v
58 |
59 | release:nginx:latest:
60 | stage: release
61 | only:
62 | - master
63 | script:
64 | - docker login --username ${REGISTRY_USER} --password ${REGISTRY_PASS} ${REGISTRY_HOST}
65 | - docker tag ${STACK_PHP_IMAGE}-nginx ${REGISTRY_PHP_IMAGE_LATEST}-nginx
66 | - docker push ${REGISTRY_PHP_IMAGE_LATEST}-nginx
67 | - docker logout ${REGISTRY_HOST}
68 |
69 | release:nginx:tags:
70 | stage: release
71 | only:
72 | - tags
73 | script:
74 | - docker login --username ${REGISTRY_USER} --password ${REGISTRY_PASS} ${REGISTRY_HOST}
75 | - docker tag ${STACK_PHP_IMAGE}-nginx ${REGISTRY_PHP_IMAGE}-nginx
76 | - docker push ${REGISTRY_PHP_IMAGE}-nginx
77 | - docker logout ${REGISTRY_HOST}
78 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | build:
2 | docker-compose build --pull php-nginx
3 |
4 | push-all:
5 | git remote | xargs -L1 git push --all
6 |
7 | lint:
8 | docker run -it --rm -v "$(PWD)/php/Dockerfile-fpm":/Dockerfile:ro redcoolbeans/dockerlint
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > :rotating_light: This repository is abandoned, please use https://github.com/yiisoft/yii2-docker
2 |
3 |
4 | Supported tags and respective `Dockerfile` links
5 | ================================================
6 |
7 | - `7.x-fpm-x.x`, `latest` ([Dockerfile](php/Dockerfile-fpm))
8 | - `7.x-fpm-x.x-nginx`, `latest-nginx` ([Dockerfile](nginx/Dockerfile-fpm-nginx))
9 |
10 | :information_source: See repository tags for full version numbers
11 |
12 | See all available [image tags](https://hub.docker.com/r/dmstr/php-yii2/tags/)
13 |
14 | [](https://git.hrzg.de/dmstr/docker-php-yii2/commits/master)
15 |
16 |
17 | Changelog
18 | ---------
19 |
20 | ### 8.x
21 |
22 | - using updated yii2 images
23 | - different system package installation
24 | - composer 2
25 | - removed standalone `fpm` image
26 |
27 | ### 7.x
28 |
29 | - switched to PHP 7.4
30 |
31 | ### 6.x
32 |
33 | - Alpine support has been dropped
34 | - Forego has been replace with supervisord
35 | - Removed Linkchecker
36 |
37 | ### 5.x
38 |
39 | *no stable release*
40 |
41 | ### 4.x
42 |
43 | - added bash-autocompletion
44 | - removed separate xdebug flavour
45 |
46 |
47 | Introduction
48 | ------------
49 |
50 | This is a Docker PHP image containing PHP extensions and composer packages and libraries for *Yii 2.0 Framework*.
51 | It is primarily intended to build Yii 2.0 applications `FROM` this image, see below for available application templates.
52 |
53 | There is also an `nginx` flavour available for this image, in which PHP and nginx are managed with [supervisor](http://supervisord.org/).
54 |
55 | In older versions of the `nginx` images, forego was used for process control.
56 | However, since forego is no longer actively maintained and problems can arise if one of the started processes terminates unsuspectedly,
57 | we decided to switch to supervisor.
58 |
59 |
60 | Features
61 | --------
62 |
63 | ### CLI commands
64 |
65 | - `composer`
66 | - `codecept`
67 | - `phpunit`
68 | - `npm`
69 |
70 | #### Extensions
71 |
72 | - soap
73 | - zip
74 | - curl
75 | - bcmath
76 | - exif
77 | - gd
78 | - iconv
79 | - intl
80 | - mbstring
81 | - opcache
82 | - pdo_mysql
83 | - pdo_pgsql
84 | - memcache
85 | - xdebug - *installed, but not loaded by default*
86 |
87 |
88 | Configuration
89 | -------------
90 |
91 | ### ENV variables
92 |
93 | - `GITHUB_API_TOKEN`
94 | - `PHP_ENABLE_XDEBUG`
95 | - `PHP_USER_ID` (debian only)
96 |
97 |
98 | Development
99 | -----------
100 |
101 | Building the images
102 |
103 | docker-compose build
104 |
105 | Development bash
106 |
107 | docker run -it dmstr/php-yii2 bash
108 |
109 |
110 | Resources
111 | ---------
112 |
113 | - [GitHub project](https://github.com/dmstr/docker-php-yii2)
114 | - [GitLab build](https://git.hrzg.de/dmstr/docker-php-yii2/builds)
115 | - [DockerHub image](https://hub.docker.com/r/dmstr/php-yii2/)
116 | - [yii2-app](https://github.com/dmstr/docker-yii2-app) minimal application tempplate
117 | - [phd5](https://github.com/dmstr/phd5-app) standard application template
118 | - [phd5](https://github.com/dmstr/docs-phd5) documentation
119 |
120 | ---
121 |
122 | ####  Built by [dmstr](http://diemeisterei.de)
123 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '2'
2 | services:
3 |
4 | php-nginx:
5 | build:
6 | dockerfile: Dockerfile-fpm-nginx
7 | context: 'nginx'
8 | args:
9 | - PHP_BASE_IMAGE_VERSION=${PHP_BASE_IMAGE_VERSION}
10 | image: ${PHP_IMAGE_NAME}:${PHP_BASE_IMAGE_VERSION}-nginx
11 | environment:
12 | - GITHUB_API_TOKEN=${GITHUB_API_TOKEN}
13 | - PHP_ENABLE_XDEBUG=${PHP_ENABLE_XDEBUG}
14 | volumes:
15 | - ./test:/test
16 | - ./test/app/web:/app/web
17 | ports:
18 | - 80
19 | - 443
20 |
--------------------------------------------------------------------------------
/nginx/Dockerfile-fpm-nginx:
--------------------------------------------------------------------------------
1 | # PHP Docker image for Yii 2.0 Framework runtime
2 | # ==============================================
3 |
4 | ARG PHP_BASE_IMAGE_VERSION
5 | FROM yiisoftware/yii2-php:${PHP_BASE_IMAGE_VERSION}-fpm
6 |
7 | # Install system packages for PHP extensions recommended for Yii 2.0 Framework
8 | ENV DEBIAN_FRONTEND=noninteractive
9 | RUN apt-get update && \
10 | apt-get -y install \
11 | gnupg2 && \
12 | apt-key update && \
13 | apt-get update && \
14 | apt-get -y install \
15 | git \
16 | nano \
17 | npm \
18 | default-mysql-client \
19 | nginx-full \
20 | cron \
21 | supervisor \
22 | procps \
23 | --no-install-recommends && \
24 | apt-get clean && \
25 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
26 |
27 | # Install less-compiler
28 | RUN npm -g install \
29 | less \
30 | lesshint \
31 | uglify-js \
32 | uglifycss
33 |
34 | # Install Yii framework bash autocompletion
35 | RUN curl -L https://raw.githubusercontent.com/yiisoft/yii2/master/contrib/completion/bash/yii \
36 | -o /etc/bash_completion.d/yii
37 |
38 | # Add configuration files
39 | COPY image-files/ /
40 |
41 | # Add GITHUB_API_TOKEN support for composer
42 | RUN chmod 700 \
43 | /usr/local/bin/docker-entrypoint.sh \
44 | /usr/local/bin/docker-run.sh \
45 | /usr/local/bin/composer
46 |
47 | WORKDIR /app
48 |
49 | # Startup script for FPM
50 | ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
51 |
52 | # forward request and error logs to docker log collector
53 | RUN ln -sf /dev/stdout /var/log/nginx/access.log \
54 | && ln -sf /dev/stderr /var/log/nginx/error.log \
55 | && ln -sf /usr/sbin/cron /usr/sbin/crond
56 |
57 | CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
58 |
59 | EXPOSE 80 443
60 |
--------------------------------------------------------------------------------
/nginx/image-files/etc/nginx/conf.d/default.conf:
--------------------------------------------------------------------------------
1 | server {
2 | charset utf-8;
3 | client_max_body_size 512M;
4 | server_name app;
5 |
6 | listen 80;
7 | listen 443 ssl http2 default_server;
8 |
9 | ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt;
10 | ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key;
11 |
12 | root /app/web;
13 | index index.php index.html index.htm;
14 |
15 | location / {
16 | # Redirect everything that isn't a real file to index.php
17 | try_files $uri $uri/ /index.php?$args;
18 | }
19 |
20 | # define suffixes for static files
21 | # set caching header and avoid processing of non-existing files by Yii
22 | location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar|svg|woff|woff2|eot|ttf|otf)$ {
23 |
24 | # set expire Header
25 | expires 6M;
26 | #add_header Cache-Control "public";
27 | add_header Last-Modified "";
28 |
29 | # keep logs clean
30 | log_not_found off;
31 |
32 | try_files $uri =404;
33 | }
34 |
35 | location ~ \.php$ {
36 | include /etc/nginx/fastcgi_params;
37 | fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
38 | fastcgi_pass 127.0.0.1:9000;
39 | try_files $uri =404;
40 | }
41 |
42 | location ~ /\.(ht|svn|git) {
43 | deny all;
44 | }
45 | }
--------------------------------------------------------------------------------
/nginx/image-files/etc/nginx/nginx.conf:
--------------------------------------------------------------------------------
1 |
2 | user www-data;
3 | worker_processes 1;
4 |
5 | error_log /var/log/nginx/error.log warn;
6 | pid /var/run/nginx.pid;
7 |
8 | events {
9 | worker_connections 1024;
10 | }
11 |
12 |
13 | http {
14 | include /etc/nginx/mime.types;
15 | default_type application/octet-stream;
16 |
17 | log_format main '$remote_addr - $remote_user [$time_local] "$request" '
18 | '$status $body_bytes_sent "$http_referer" '
19 | '"$http_user_agent" "$http_x_forwarded_for"';
20 |
21 | log_format extended '$remote_addr - $remote_user [$time_local] "$request" '
22 | '$status $body_bytes_sent "$http_referer" '
23 | '"$http_user_agent" "$http_x_forwarded_for" '
24 | '$request_time $request_method';
25 |
26 | log_format logstash_json '{ "@timestamp": "$time_iso8601", '
27 | '"@fields": { '
28 | '"remote_addr": "$remote_addr", '
29 | '"remote_user": "$remote_user", '
30 | '"body_bytes_sent": "$body_bytes_sent", '
31 | '"request_time": "$request_time", '
32 | '"status": "$status", '
33 | '"request": "$request", '
34 | '"request_method": "$request_method", '
35 | '"http_x_forwarded_for": "$http_x_forwarded_for", '
36 | '"http_referrer": "$http_referer", '
37 | '"http_user_agent": "$http_user_agent" } }';
38 |
39 | access_log /var/log/nginx/access.log extended;
40 |
41 | sendfile off;
42 | keepalive_timeout 10;
43 | fastcgi_temp_path /tmp/nginx_fastcgi_temp 1 2;
44 | client_body_temp_path /tmp/nginx_client_temp 1 2;
45 |
46 | # disable version in error messages and response header
47 | server_tokens off;
48 |
49 | gzip on;
50 | gzip_disable "msie6";
51 | gzip_comp_level 6;
52 | gzip_min_length 1100;
53 | gzip_buffers 16 8k;
54 | gzip_proxied any;
55 | gzip_types
56 | text/plain
57 | text/css
58 | text/js
59 | text/xml
60 | text/javascript
61 | application/javascript
62 | application/x-javascript
63 | application/json
64 | application/xml
65 | application/rss+xml
66 | image/svg+xml;
67 |
68 | # don't use etag with expire
69 | etag off;
70 |
71 | include /etc/nginx/conf.d/*.conf;
72 | }
73 |
--------------------------------------------------------------------------------
/nginx/image-files/etc/nginx/ssl/nginx-selfsigned.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIID3zCCAsegAwIBAgIJAMoMt2gdriBpMA0GCSqGSIb3DQEBCwUAMIGFMQswCQYD
3 | VQQGEwJERTELMAkGA1UECAwCQlcxEjAQBgNVBAcMCVN0dXR0Z2FydDEOMAwGA1UE
4 | CgwFZG1zdHIxNzA1BgNVBAsMLnBocC15aWkyIC0gc2VsZiBzaWduZWQgY2VydGlm
5 | aWNhdGUgZm9yIHRlc3RpbmcxDDAKBgNVBAMMA2FwcDAeFw0xNzEwMDkwOTUxMjRa
6 | Fw0xODEwMDkwOTUxMjRaMIGFMQswCQYDVQQGEwJERTELMAkGA1UECAwCQlcxEjAQ
7 | BgNVBAcMCVN0dXR0Z2FydDEOMAwGA1UECgwFZG1zdHIxNzA1BgNVBAsMLnBocC15
8 | aWkyIC0gc2VsZiBzaWduZWQgY2VydGlmaWNhdGUgZm9yIHRlc3RpbmcxDDAKBgNV
9 | BAMMA2FwcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALEel8/pjWaB
10 | n8y4wt6dK9Rd0QtOGHpYcjMbC1ALSbl7UN2GByXGtEAlgsCkH6XSt4qBoJSeuyhD
11 | zzVFir55kimk57DrBaDzQoXTF9wtoeJdpUjszwphfm8mbo+QYUTBeUQdIrZ/0Kjn
12 | 2mU85xVPPoDMMXWeCWHCob0Fhnv59II5pL5PeUbnz0mmOftM06wSI5THw5dx/cHM
13 | rt3DSenecQQK6SXRxuiOLyy1fWQ5nTTbG4IzW1gTfuD+PFXzQlDQNg94sPqDw2V9
14 | DGh/viP6bqm7C5HglnCaKvy3PAqWuSdWpxflfETKNeuyaflk3bOEoDx/AbmhgK5W
15 | 8RGw00VLYvkCAwEAAaNQME4wHQYDVR0OBBYEFK4tI2XnhxAPBSxkdUm+LJEq6Bdh
16 | MB8GA1UdIwQYMBaAFK4tI2XnhxAPBSxkdUm+LJEq6BdhMAwGA1UdEwQFMAMBAf8w
17 | DQYJKoZIhvcNAQELBQADggEBAABLbPdM2bt3n9eJUGdyvqmxT0YPZESl1OfR2CYV
18 | zyv+qBPeqxlrpuMzZwqBnRHKP4r+tinO6bIKRGuL65w1psr2gzVpe3365lZVABPT
19 | CqWiMP/6cR8rYPKRKhdvI7MVyDn2VItzVFAIc80RbMm7Gu4cTElOsiFeUmdoOEms
20 | o9qvhOuXSfDtlexzXqpxBMMjRw6PFhIfxAcGGZARWpyrNpBfUJGDJkWtu/qki8eE
21 | o5NTyQskkaT/DzmOFN3UwBA71DtSYfy2qWkHprI8kMOfEDRfAjU7p2W0lWKdZK9f
22 | 4SEY2g/oTgvmbI3Qbf6avaRRFJwLPzmMDMB7RDl0zqmptPQ=
23 | -----END CERTIFICATE-----
24 |
--------------------------------------------------------------------------------
/nginx/image-files/etc/nginx/ssl/nginx-selfsigned.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCxHpfP6Y1mgZ/M
3 | uMLenSvUXdELThh6WHIzGwtQC0m5e1DdhgclxrRAJYLApB+l0reKgaCUnrsoQ881
4 | RYq+eZIppOew6wWg80KF0xfcLaHiXaVI7M8KYX5vJm6PkGFEwXlEHSK2f9Co59pl
5 | POcVTz6AzDF1nglhwqG9BYZ7+fSCOaS+T3lG589Jpjn7TNOsEiOUx8OXcf3BzK7d
6 | w0np3nEECukl0cboji8stX1kOZ002xuCM1tYE37g/jxV80JQ0DYPeLD6g8NlfQxo
7 | f74j+m6puwuR4JZwmir8tzwKlrknVqcX5XxEyjXrsmn5ZN2zhKA8fwG5oYCuVvER
8 | sNNFS2L5AgMBAAECggEAdMVNoyZAMe+NsgOxfeCzD7yWYFSpcKe1Cppu1+PJRD7X
9 | rmR5e99H4O6aCHVr5ABLP0Z83t7TVxV1m5JwiWlPAqOUmKApwtX96oqkNWXkT4Ab
10 | wztUuGxUVeVJiN7QMes4Dr8Crr0PjPvmkU4Yr4TiGToF9ZwuZURTK3JkGoJNQDi1
11 | 09pNZ6VUc/kPXGByFROiRdhxMygyRQAXWgPl9vYJ04aOIaBG4MSS0Pety5Bo1V6o
12 | moXv6CzOYEq0deM84V/O14ajSNadv5W99oMErnwIYY+GJprlV1kFfuDkJnfb5MyL
13 | m/tPUv5Sw53X9pZjC+z9LhJSaFIMHfRLiFhPBEFvrQKBgQDapfI40guVlvD6bqe4
14 | P84Z2ILNS+xA3DYBE8OWHkIOI/MMOiyzu2vBlVYORma4qGzaBpNzgpqgy5YQbNLg
15 | LlGbVy3J3Chpba7VQL1JZsxq2N8vu20UpVonhxDt0/PqGnCZ+nCWtFmM98iWGrSB
16 | lC5dGBNiD8v/z+T4k3OQFsEpXwKBgQDPYHz0anCXhKNrBK4TJghsxLVOGvoQ7fDO
17 | rw/9fCg19HF2W7aP+sH75Ng+2axzAPpPb2RtoXt1milGB8Km2U+r43J7kls9xpuN
18 | wk/8CdzCvo6iawgCu0q+myuOziYuUGMnixAkEJxsVzrgseNeu8SH++0caOZMTvzL
19 | sM9RDgJapwKBgHtKlfJ6ZrPcYFgm64ZW3EXws5lGFZthUUZ8OY690yucE+IyL6DN
20 | r26CYfs8sZGwz2iFysGYxM6k3iK26pYlKDk7CIPKFDOW+L4helsYj240im2k91Zs
21 | AxFE9UPWf7TjYdlBwhkI63I1CrOxrVVgFGDEQbHLDJJcTVXp94Epg5RrAoGBALM1
22 | Y+ZoUVJvGjXyfmgn1uH//9o2b+HPbel+2aep8qnly2OIEDVOcvK2qbVusJtVvfqF
23 | fdlL0oAnsAFH1YwQgcw+KwHk0ZqKFoUj5bEd6LwWpvZu3iZWKlqbh8HKHq6pY3aZ
24 | s2InRLZPj577u0xzoXwOVrLVaCeLnuR7sD0QiTJDAoGAUewb/2gQNJPKKZCfy4mD
25 | OLXpT/IvV1YElXu8hL2OTElY/l+PCUFQLkmwNP0FXw0Gu4Q0ua05D+BloBWkEPl3
26 | WDheXYwIYiDoZuPAvFGx3WlftXyc7IusJarxY5LQ2q1tl1OwjRV2EeDm+YSTXlSg
27 | Dl+Wm2rCjL43qFrClv7Zjdc=
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/nginx/image-files/etc/supervisor/conf.d/fpm.conf:
--------------------------------------------------------------------------------
1 | [program:php-fpm]
2 | command = php-fpm
3 | autostart = true
4 | autorestart = true
5 | priority=40
6 | stdout_logfile = /dev/stdout
7 | stdout_logfile_maxbytes = 0
8 | stderr_logfile = /dev/stderr
9 | stderr_logfile_maxbytes = 0
10 |
--------------------------------------------------------------------------------
/nginx/image-files/etc/supervisor/conf.d/nginx.conf:
--------------------------------------------------------------------------------
1 | [program:nginx]
2 | command=/usr/sbin/nginx -g 'daemon off;'
3 | autostart=true
4 | autorestart=true
5 | priority=50
6 | stdout_events_enabled=true
7 | stderr_events_enabled=true
8 | stdout_logfile = /dev/stdout
9 | stdout_logfile_maxbytes = 0
10 | stderr_logfile = /dev/stderr
11 | stderr_logfile_maxbytes = 0
12 |
--------------------------------------------------------------------------------
/nginx/image-files/etc/supervisor/supervisord.conf:
--------------------------------------------------------------------------------
1 | [supervisord]
2 | logfile = /dev/null
3 | loglevel = info
4 | pidfile = /var/run/supervisord.pid
5 | nodaemon = true
6 |
7 | [include]
8 | files = /etc/supervisor/conf.d/*.conf
9 |
10 |
--------------------------------------------------------------------------------
/nginx/image-files/root/.bashrc:
--------------------------------------------------------------------------------
1 | PS1="\e[0;35m[$APP_NAME] $APP_VERSION \e[0;0m\w \e[0;37m\u \h \e[0;0m\n$ "
2 |
3 | cat <<'MSG'
4 | ___________
5 | | |
6 | | _ | _ _
7 | | /\| |/\ | | | | |
8 | | \ ` ' / | __| |_ __ ___ ___| |_ _ __
9 | | |_ _| | / _` | '_ ` _ \/ __| __| '__|
10 | | / , . \ | | (_| | | | | | \__ \ |_| |
11 | | \/|_|\/ | \__,_|_| |_| |_|___/\__|_|
12 | \ /
13 | \_______/
14 |
15 | Docker image dmstr/php-yii2
16 |
17 | Console commands: composer, codecept, phpunit, yii
18 |
19 | MSG
20 |
21 | echo "PHP version: ${PHP_VERSION}"
22 |
23 | if ! shopt -oq posix; then
24 | if [ -f /usr/share/bash-completion/bash_completion ]; then
25 | . /usr/share/bash-completion/bash_completion
26 | elif [ -f /etc/bash_completion.d/yii ]; then
27 | . /etc/bash_completion.d/yii
28 | fi
29 | fi
--------------------------------------------------------------------------------
/nginx/image-files/usr/local/bin/composer:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | if [ -n "${GITHUB_API_TOKEN}" ]
6 | then
7 | composer.phar config -g github-oauth.github.com ${GITHUB_API_TOKEN}
8 | fi
9 |
10 | composer.phar "$@"
--------------------------------------------------------------------------------
/nginx/image-files/usr/local/bin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This script is run within the php containers on start
4 |
5 | # Fail on any error
6 | set -o errexit
7 |
8 | # Set permissions based on ENV variable (debian only)
9 | if [ -x "usermod" ] ; then
10 | usermod -u ${PHP_USER_ID} www-data
11 | fi
12 |
13 | # Enable xdebug by ENV variable
14 | if [ 0 -ne "${PHP_ENABLE_XDEBUG:-0}" ] ; then
15 | docker-php-ext-enable xdebug
16 | echo "Enabled xdebug"
17 | fi
18 |
19 | # Execute CMD
20 | exec "$@"
--------------------------------------------------------------------------------
/nginx/image-files/usr/local/bin/docker-run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This script is run within the php containers on start
4 | # docker-run.sh is available for legacy setups
5 |
6 | # Fail on any error
7 | set -o errexit
8 |
9 | # Run the command sent as command line arguments
10 | php-fpm
11 |
--------------------------------------------------------------------------------
/nginx/image-files/usr/local/etc/php/conf.d/base.ini:
--------------------------------------------------------------------------------
1 | ; Required timezone
2 | date.timezone = UTC
3 |
4 | ; General settings
5 | memory_limit=128M
6 | max_execution_time=30
7 | sys_temp_dir=/tmp
8 | upload_max_filesize=512M
9 | upload_tmp_dir=/tmp
10 | post_max_size=512M
11 |
12 | ; Security, Debug & Logs
13 | expose_php=off
14 | cgi.fix_pathinfo=0
15 | log_errors=on
16 | error_reporting=E_ALL
17 | html_errors=on
18 | xdebug.default_enable=off
19 |
20 | ; Opcache
21 | opcache.memory_consumption=128
22 | opcache.interned_strings_buffer=8
23 | opcache.max_accelerated_files=4000
24 | ;opcache.validate_timestamps=off
25 | opcache.fast_shutdown=0
26 | opcache.enable_cli=1
27 |
28 | ; PHP language options
29 | short_open_tag=0
--------------------------------------------------------------------------------
/nginx/image-files/usr/local/etc/php/php-fpm.conf:
--------------------------------------------------------------------------------
1 | ; This file was initially adapated from the output of: (on PHP 5.6)
2 | ; grep -vE '^;|^ *$' php-fpm.conf.default
3 |
4 | [global]
5 |
6 | error_log = /proc/self/fd/2
7 | daemonize = no
8 |
9 | include=/usr/local/etc/php/pool.d/*.conf
10 |
--------------------------------------------------------------------------------
/nginx/image-files/usr/local/etc/php/pool.d/www.conf:
--------------------------------------------------------------------------------
1 | [www]
2 |
3 | ; if we send this to /proc/self/fd/1, it never appears
4 | access.log = /proc/self/fd/2
5 |
6 | user = www-data
7 | group = www-data
8 |
9 | listen = [::]:9000
10 |
11 | pm = dynamic
12 | pm.max_children = 10
13 | pm.start_servers = 2
14 | pm.min_spare_servers = 1
15 | pm.max_spare_servers = 2
16 | pm.max_requests = 500
17 |
18 | ; send worker output to stdout/stderr
19 | catch_workers_output = yes
20 |
21 | ; make all environment variables available to php-fpm at runtime
22 | clear_env = no
23 |
--------------------------------------------------------------------------------
/test/app/web/index.php:
--------------------------------------------------------------------------------
1 | /dev/null || exit 1
11 |
12 | echo "Checking opcache..."
13 | docker-compose run --rm ${PHP_SERVICE} php -m | grep -i opcache 1>/dev/null || exit 1
14 |
15 | echo "Checking composer auth..."
16 | docker-compose run -e GITHUB_API_TOKEN=abcd12345 --rm ${PHP_SERVICE} sh -c '\
17 | composer && \
18 | [ -f ~/.composer/auth.json ] || exit 1 \
19 | '
20 |
21 | echo "Done."
22 |
--------------------------------------------------------------------------------
/test/requirements.php:
--------------------------------------------------------------------------------
1 | Error';
18 | echo '
The path to yii framework seems to be incorrect.
';
19 | echo 'You need to install Yii framework via composer or adjust the framework path in file ' . basename(__FILE__) . '.
';
20 | echo 'Please refer to the README on how to install Yii.
';
21 | }
22 |
23 | require_once($frameworkPath . '/requirements/YiiRequirementChecker.php');
24 | $requirementsChecker = new YiiRequirementChecker();
25 |
26 | $gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.';
27 | $gdOK = $imagickOK = false;
28 |
29 | if (extension_loaded('imagick')) {
30 | $imagick = new Imagick();
31 | $imagickFormats = $imagick->queryFormats('PNG');
32 | if (in_array('PNG', $imagickFormats)) {
33 | $imagickOK = true;
34 | } else {
35 | $imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.';
36 | }
37 | }
38 |
39 | if (extension_loaded('gd')) {
40 | $gdInfo = gd_info();
41 | if (!empty($gdInfo['FreeType Support'])) {
42 | $gdOK = true;
43 | } else {
44 | $gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.';
45 | }
46 | }
47 |
48 | /**
49 | * Adjust requirements according to your application specifics.
50 | */
51 | $requirements = array(
52 | // Database :
53 | array(
54 | 'name' => 'PDO extension',
55 | 'mandatory' => true,
56 | 'condition' => extension_loaded('pdo'),
57 | 'by' => 'All DB-related classes',
58 | ),
59 | array(
60 | 'name' => 'PDO SQLite extension',
61 | 'mandatory' => false,
62 | 'condition' => extension_loaded('pdo_sqlite'),
63 | 'by' => 'All DB-related classes',
64 | 'memo' => 'Required for SQLite database.',
65 | ),
66 | array(
67 | 'name' => 'PDO MySQL extension',
68 | 'mandatory' => false,
69 | 'condition' => extension_loaded('pdo_mysql'),
70 | 'by' => 'All DB-related classes',
71 | 'memo' => 'Required for MySQL database.',
72 | ),
73 | array(
74 | 'name' => 'PDO PostgreSQL extension',
75 | 'mandatory' => false,
76 | 'condition' => extension_loaded('pdo_pgsql'),
77 | 'by' => 'All DB-related classes',
78 | 'memo' => 'Required for PostgreSQL database.',
79 | ),
80 | // Cache :
81 | array(
82 | 'name' => 'Memcache extension',
83 | 'mandatory' => false,
84 | 'condition' => extension_loaded('memcache') || extension_loaded('memcached'),
85 | 'by' => 'MemCache',
86 | 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true
.' : ''
87 | ),
88 | // CAPTCHA:
89 | array(
90 | 'name' => 'GD PHP extension with FreeType support',
91 | 'mandatory' => false,
92 | 'condition' => $gdOK,
93 | 'by' => 'Captcha',
94 | 'memo' => $gdMemo,
95 | ),
96 | array(
97 | 'name' => 'ImageMagick PHP extension with PNG support',
98 | 'mandatory' => false,
99 | 'condition' => $imagickOK,
100 | 'by' => 'Captcha',
101 | 'memo' => $imagickMemo,
102 | ),
103 | // PHP ini :
104 | 'phpExposePhp' => array(
105 | 'name' => 'Expose PHP',
106 | 'mandatory' => false,
107 | 'condition' => $requirementsChecker->checkPhpIniOff("expose_php"),
108 | 'by' => 'Security reasons',
109 | 'memo' => '"expose_php" should be disabled at php.ini',
110 | ),
111 | 'phpAllowUrlInclude' => array(
112 | 'name' => 'PHP allow url include',
113 | 'mandatory' => false,
114 | 'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"),
115 | 'by' => 'Security reasons',
116 | 'memo' => '"allow_url_include" should be disabled at php.ini',
117 | ),
118 | 'phpSmtp' => array(
119 | 'name' => 'PHP mail SMTP',
120 | 'mandatory' => false,
121 | 'condition' => strlen(ini_get('SMTP')) > 0,
122 | 'by' => 'Email sending',
123 | 'memo' => 'PHP mail SMTP server required',
124 | ),
125 | );
126 |
127 | // OPcache check
128 | if (!version_compare(phpversion(), '5.5', '>=')) {
129 | $requirements[] = array(
130 | 'name' => 'APC extension',
131 | 'mandatory' => false,
132 | 'condition' => extension_loaded('apc'),
133 | 'by' => 'ApcCache',
134 | );
135 | }
136 |
137 | $requirementsChecker->checkYii()->check($requirements)->render();
--------------------------------------------------------------------------------
/test/requirements/YiiRequirementChecker.php:
--------------------------------------------------------------------------------
1 | 'PHP Some Extension',
25 | * 'mandatory' => true,
26 | * 'condition' => extension_loaded('some_extension'),
27 | * 'by' => 'Some application feature',
28 | * 'memo' => 'PHP extension "some_extension" required',
29 | * ),
30 | * );
31 | * $requirementsChecker->checkYii()->check($requirements)->render();
32 | * ```
33 | *
34 | * If you wish to render the report with your own representation, use [[getResult()]] instead of [[render()]]
35 | *
36 | * Requirement condition could be in format "eval:PHP expression".
37 | * In this case specified PHP expression will be evaluated in the context of this class instance.
38 | * For example:
39 | *
40 | * ```php
41 | * $requirements = array(
42 | * array(
43 | * 'name' => 'Upload max file size',
44 | * 'condition' => 'eval:$this->checkUploadMaxFileSize("5M")',
45 | * ),
46 | * );
47 | * ```
48 | *
49 | * Note: this class definition does not match ordinary Yii style, because it should match PHP 4.3
50 | * and should not use features from newer PHP versions!
51 | *
52 | * @property array|null $result the check results, this property is for internal usage only.
53 | *
54 | * @author Paul Klimov
55 | * @since 2.0
56 | */
57 | class YiiRequirementChecker
58 | {
59 | /**
60 | * Check the given requirements, collecting results into internal field.
61 | * This method can be invoked several times checking different requirement sets.
62 | * Use [[getResult()]] or [[render()]] to get the results.
63 | * @param array|string $requirements requirements to be checked.
64 | * If an array, it is treated as the set of requirements;
65 | * If a string, it is treated as the path of the file, which contains the requirements;
66 | * @return $this self instance.
67 | */
68 | function check($requirements)
69 | {
70 | if (is_string($requirements)) {
71 | $requirements = require($requirements);
72 | }
73 | if (!is_array($requirements)) {
74 | $this->usageError('Requirements must be an array, "' . gettype($requirements) . '" has been given!');
75 | }
76 | if (!isset($this->result) || !is_array($this->result)) {
77 | $this->result = array(
78 | 'summary' => array(
79 | 'total' => 0,
80 | 'errors' => 0,
81 | 'warnings' => 0,
82 | ),
83 | 'requirements' => array(),
84 | );
85 | }
86 | foreach ($requirements as $key => $rawRequirement) {
87 | $requirement = $this->normalizeRequirement($rawRequirement, $key);
88 | $this->result['summary']['total']++;
89 | if (!$requirement['condition']) {
90 | if ($requirement['mandatory']) {
91 | $requirement['error'] = true;
92 | $requirement['warning'] = true;
93 | $this->result['summary']['errors']++;
94 | } else {
95 | $requirement['error'] = false;
96 | $requirement['warning'] = true;
97 | $this->result['summary']['warnings']++;
98 | }
99 | } else {
100 | $requirement['error'] = false;
101 | $requirement['warning'] = false;
102 | }
103 | $this->result['requirements'][] = $requirement;
104 | }
105 |
106 | return $this;
107 | }
108 |
109 | /**
110 | * Performs the check for the Yii core requirements.
111 | * @return YiiRequirementChecker self instance.
112 | */
113 | function checkYii()
114 | {
115 | return $this->check(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'requirements.php');
116 | }
117 |
118 | /**
119 | * Return the check results.
120 | * @return array|null check results in format:
121 | *
122 | * ```php
123 | * array(
124 | * 'summary' => array(
125 | * 'total' => total number of checks,
126 | * 'errors' => number of errors,
127 | * 'warnings' => number of warnings,
128 | * ),
129 | * 'requirements' => array(
130 | * array(
131 | * ...
132 | * 'error' => is there an error,
133 | * 'warning' => is there a warning,
134 | * ),
135 | * ...
136 | * ),
137 | * )
138 | * ```
139 | */
140 | function getResult()
141 | {
142 | if (isset($this->result)) {
143 | return $this->result;
144 | } else {
145 | return null;
146 | }
147 | }
148 |
149 | /**
150 | * Renders the requirements check result.
151 | * The output will vary depending is a script running from web or from console.
152 | */
153 | function render()
154 | {
155 | if (!isset($this->result)) {
156 | $this->usageError('Nothing to render!');
157 | }
158 | $baseViewFilePath = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'views';
159 | if (!empty($_SERVER['argv'])) {
160 | $viewFileName = $baseViewFilePath . DIRECTORY_SEPARATOR . 'console' . DIRECTORY_SEPARATOR . 'index.php';
161 | } else {
162 | $viewFileName = $baseViewFilePath . DIRECTORY_SEPARATOR . 'web' . DIRECTORY_SEPARATOR . 'index.php';
163 | }
164 | $this->renderViewFile($viewFileName, $this->result);
165 | }
166 |
167 | /**
168 | * Checks if the given PHP extension is available and its version matches the given one.
169 | * @param string $extensionName PHP extension name.
170 | * @param string $version required PHP extension version.
171 | * @param string $compare comparison operator, by default '>='
172 | * @return boolean if PHP extension version matches.
173 | */
174 | function checkPhpExtensionVersion($extensionName, $version, $compare = '>=')
175 | {
176 | if (!extension_loaded($extensionName)) {
177 | return false;
178 | }
179 | $extensionVersion = phpversion($extensionName);
180 | if (empty($extensionVersion)) {
181 | return false;
182 | }
183 | if (strncasecmp($extensionVersion, 'PECL-', 5) === 0) {
184 | $extensionVersion = substr($extensionVersion, 5);
185 | }
186 |
187 | return version_compare($extensionVersion, $version, $compare);
188 | }
189 |
190 | /**
191 | * Checks if PHP configuration option (from php.ini) is on.
192 | * @param string $name configuration option name.
193 | * @return boolean option is on.
194 | */
195 | function checkPhpIniOn($name)
196 | {
197 | $value = ini_get($name);
198 | if (empty($value)) {
199 | return false;
200 | }
201 |
202 | return ((int) $value === 1 || strtolower($value) === 'on');
203 | }
204 |
205 | /**
206 | * Checks if PHP configuration option (from php.ini) is off.
207 | * @param string $name configuration option name.
208 | * @return boolean option is off.
209 | */
210 | function checkPhpIniOff($name)
211 | {
212 | $value = ini_get($name);
213 | if (empty($value)) {
214 | return true;
215 | }
216 |
217 | return (strtolower($value) === 'off');
218 | }
219 |
220 | /**
221 | * Compare byte sizes of values given in the verbose representation,
222 | * like '5M', '15K' etc.
223 | * @param string $a first value.
224 | * @param string $b second value.
225 | * @param string $compare comparison operator, by default '>='.
226 | * @return boolean comparison result.
227 | */
228 | function compareByteSize($a, $b, $compare = '>=')
229 | {
230 | $compareExpression = '(' . $this->getByteSize($a) . $compare . $this->getByteSize($b) . ')';
231 |
232 | return $this->evaluateExpression($compareExpression);
233 | }
234 |
235 | /**
236 | * Gets the size in bytes from verbose size representation.
237 | * For example: '5K' => 5*1024
238 | * @param string $verboseSize verbose size representation.
239 | * @return integer actual size in bytes.
240 | */
241 | function getByteSize($verboseSize)
242 | {
243 | if (empty($verboseSize)) {
244 | return 0;
245 | }
246 | if (is_numeric($verboseSize)) {
247 | return (int) $verboseSize;
248 | }
249 | $sizeUnit = trim($verboseSize, '0123456789');
250 | $size = str_replace($sizeUnit, '', $verboseSize);
251 | $size = trim($size);
252 | if (!is_numeric($size)) {
253 | return 0;
254 | }
255 | switch (strtolower($sizeUnit)) {
256 | case 'kb':
257 | case 'k':
258 | return $size * 1024;
259 | case 'mb':
260 | case 'm':
261 | return $size * 1024 * 1024;
262 | case 'gb':
263 | case 'g':
264 | return $size * 1024 * 1024 * 1024;
265 | default:
266 | return 0;
267 | }
268 | }
269 |
270 | /**
271 | * Checks if upload max file size matches the given range.
272 | * @param string|null $min verbose file size minimum required value, pass null to skip minimum check.
273 | * @param string|null $max verbose file size maximum required value, pass null to skip maximum check.
274 | * @return boolean success.
275 | */
276 | function checkUploadMaxFileSize($min = null, $max = null)
277 | {
278 | $postMaxSize = ini_get('post_max_size');
279 | $uploadMaxFileSize = ini_get('upload_max_filesize');
280 | if ($min !== null) {
281 | $minCheckResult = $this->compareByteSize($postMaxSize, $min, '>=') && $this->compareByteSize($uploadMaxFileSize, $min, '>=');
282 | } else {
283 | $minCheckResult = true;
284 | }
285 | if ($max !== null) {
286 | $maxCheckResult = $this->compareByteSize($postMaxSize, $max, '<=') && $this->compareByteSize($uploadMaxFileSize, $max, '<=');
287 | } else {
288 | $maxCheckResult = true;
289 | }
290 |
291 | return ($minCheckResult && $maxCheckResult);
292 | }
293 |
294 | /**
295 | * Renders a view file.
296 | * This method includes the view file as a PHP script
297 | * and captures the display result if required.
298 | * @param string $_viewFile_ view file
299 | * @param array $_data_ data to be extracted and made available to the view file
300 | * @param boolean $_return_ whether the rendering result should be returned as a string
301 | * @return string the rendering result. Null if the rendering result is not required.
302 | */
303 | function renderViewFile($_viewFile_, $_data_ = null, $_return_ = false)
304 | {
305 | // we use special variable names here to avoid conflict when extracting data
306 | if (is_array($_data_)) {
307 | extract($_data_, EXTR_PREFIX_SAME, 'data');
308 | } else {
309 | $data = $_data_;
310 | }
311 | if ($_return_) {
312 | ob_start();
313 | ob_implicit_flush(false);
314 | require($_viewFile_);
315 |
316 | return ob_get_clean();
317 | } else {
318 | require($_viewFile_);
319 | }
320 | }
321 |
322 | /**
323 | * Normalizes requirement ensuring it has correct format.
324 | * @param array $requirement raw requirement.
325 | * @param integer $requirementKey requirement key in the list.
326 | * @return array normalized requirement.
327 | */
328 | function normalizeRequirement($requirement, $requirementKey = 0)
329 | {
330 | if (!is_array($requirement)) {
331 | $this->usageError('Requirement must be an array!');
332 | }
333 | if (!array_key_exists('condition', $requirement)) {
334 | $this->usageError("Requirement '{$requirementKey}' has no condition!");
335 | } else {
336 | $evalPrefix = 'eval:';
337 | if (is_string($requirement['condition']) && strpos($requirement['condition'], $evalPrefix) === 0) {
338 | $expression = substr($requirement['condition'], strlen($evalPrefix));
339 | $requirement['condition'] = $this->evaluateExpression($expression);
340 | }
341 | }
342 | if (!array_key_exists('name', $requirement)) {
343 | $requirement['name'] = is_numeric($requirementKey) ? 'Requirement #' . $requirementKey : $requirementKey;
344 | }
345 | if (!array_key_exists('mandatory', $requirement)) {
346 | if (array_key_exists('required', $requirement)) {
347 | $requirement['mandatory'] = $requirement['required'];
348 | } else {
349 | $requirement['mandatory'] = false;
350 | }
351 | }
352 | if (!array_key_exists('by', $requirement)) {
353 | $requirement['by'] = 'Unknown';
354 | }
355 | if (!array_key_exists('memo', $requirement)) {
356 | $requirement['memo'] = '';
357 | }
358 |
359 | return $requirement;
360 | }
361 |
362 | /**
363 | * Displays a usage error.
364 | * This method will then terminate the execution of the current application.
365 | * @param string $message the error message
366 | */
367 | function usageError($message)
368 | {
369 | echo "Error: $message\n\n";
370 | exit(1);
371 | }
372 |
373 | /**
374 | * Evaluates a PHP expression under the context of this class.
375 | * @param string $expression a PHP expression to be evaluated.
376 | * @return mixed the expression result.
377 | */
378 | function evaluateExpression($expression)
379 | {
380 | return eval('return ' . $expression . ';');
381 | }
382 |
383 | /**
384 | * Returns the server information.
385 | * @return string server information.
386 | */
387 | function getServerInfo()
388 | {
389 | return isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '';;
390 | }
391 |
392 | /**
393 | * Returns the now date if possible in string representation.
394 | * @return string now date.
395 | */
396 | function getNowDate()
397 | {
398 | return @strftime('%Y-%m-%d %H:%M', time());;
399 | }
400 | }
401 |
--------------------------------------------------------------------------------
/test/requirements/requirements.php:
--------------------------------------------------------------------------------
1 | 'PHP version',
11 | 'mandatory' => true,
12 | 'condition' => version_compare(PHP_VERSION, '5.4.0', '>='),
13 | 'by' => 'Yii Framework',
14 | 'memo' => 'PHP 5.4.0 or higher is required.',
15 | ),
16 | array(
17 | 'name' => 'Reflection extension',
18 | 'mandatory' => true,
19 | 'condition' => class_exists('Reflection', false),
20 | 'by' => 'Yii Framework',
21 | ),
22 | array(
23 | 'name' => 'PCRE extension',
24 | 'mandatory' => true,
25 | 'condition' => extension_loaded('pcre'),
26 | 'by' => 'Yii Framework',
27 | ),
28 | array(
29 | 'name' => 'SPL extension',
30 | 'mandatory' => true,
31 | 'condition' => extension_loaded('SPL'),
32 | 'by' => 'Yii Framework',
33 | ),
34 | array(
35 | 'name' => 'Ctype extension',
36 | 'mandatory' => true,
37 | 'condition' => extension_loaded('ctype'),
38 | 'by' => 'Yii Framework'
39 | ),
40 | array(
41 | 'name' => 'MBString extension',
42 | 'mandatory' => true,
43 | 'condition' => extension_loaded('mbstring'),
44 | 'by' => 'Multibyte string processing',
45 | 'memo' => 'Required for multibyte encoding string processing.'
46 | ),
47 | array(
48 | 'name' => 'OpenSSL extension',
49 | 'mandatory' => false,
50 | 'condition' => extension_loaded('openssl'),
51 | 'by' => 'Security Component',
52 | 'memo' => 'Required by encrypt and decrypt methods.'
53 | ),
54 | array(
55 | 'name' => 'Intl extension',
56 | 'mandatory' => false,
57 | 'condition' => $this->checkPhpExtensionVersion('intl', '1.0.2', '>='),
58 | 'by' => 'Internationalization support',
59 | 'memo' => 'PHP Intl extension 1.0.2 or higher is required when you want to use advanced parameters formatting
60 | in Yii::t()
, non-latin languages with Inflector::slug()
,
61 | IDN-feature of
62 | EmailValidator
or UrlValidator
or the yii\i18n\Formatter
class.'
63 | ),
64 | array(
65 | 'name' => 'ICU version',
66 | 'mandatory' => false,
67 | 'condition' => defined('INTL_ICU_VERSION') && version_compare(INTL_ICU_VERSION, '49', '>='),
68 | 'by' => 'Internationalization support',
69 | 'memo' => 'ICU 49.0 or higher is required when you want to use #
placeholder in plural rules
70 | (for example, plural in
71 |
72 | Formatter::asRelativeTime()) in the yii\i18n\Formatter
class. Your current ICU version is ' .
73 | (defined('INTL_ICU_VERSION') ? INTL_ICU_VERSION : '(ICU is missing)') . '.'
74 | ),
75 | array(
76 | 'name' => 'ICU Data version',
77 | 'mandatory' => false,
78 | 'condition' => defined('INTL_ICU_DATA_VERSION') && version_compare(INTL_ICU_DATA_VERSION, '49.1', '>='),
79 | 'by' => 'Internationalization support',
80 | 'memo' => 'ICU Data 49.1 or higher is required when you want to use #
placeholder in plural rules
81 | (for example, plural in
82 |
83 | Formatter::asRelativeTime()) in the yii\i18n\Formatter
class. Your current ICU Data version is ' .
84 | (defined('INTL_ICU_DATA_VERSION') ? INTL_ICU_DATA_VERSION : '(ICU Data is missing)') . '.'
85 | ),
86 | array(
87 | 'name' => 'Fileinfo extension',
88 | 'mandatory' => false,
89 | 'condition' => extension_loaded('fileinfo'),
90 | 'by' => 'File Information',
91 | 'memo' => 'Required for files upload to detect correct file mime-types.'
92 | ),
93 | array(
94 | 'name' => 'DOM extension',
95 | 'mandatory' => false,
96 | 'condition' => extension_loaded('dom'),
97 | 'by' => 'Document Object Model',
98 | 'memo' => 'Required for REST API to send XML responses via yii\web\XmlResponseFormatter
.'
99 | ),
100 | );
101 |
--------------------------------------------------------------------------------
/test/requirements/views/console/index.php:
--------------------------------------------------------------------------------
1 | $requirement) {
18 | if ($requirement['condition']) {
19 | echo $requirement['name'].": OK\n";
20 | echo "\n";
21 | } else {
22 | echo $requirement['name'].': '.($requirement['mandatory'] ? 'FAILED!!!' : 'WARNING!!!')."\n";
23 | echo 'Required by: '.strip_tags($requirement['by'])."\n";
24 | $memo = strip_tags($requirement['memo']);
25 | if (!empty($memo)) {
26 | echo 'Memo: '.strip_tags($requirement['memo'])."\n";
27 | }
28 | echo "\n";
29 | }
30 | }
31 |
32 | $summaryString = 'Errors: '.$summary['errors'].' Warnings: '.$summary['warnings'].' Total checks: '.$summary['total'];
33 | echo str_pad('', strlen($summaryString), '-')."\n";
34 | echo $summaryString;
35 |
36 | echo "\n\n";
37 |
--------------------------------------------------------------------------------
/test/requirements/views/web/css.php:
--------------------------------------------------------------------------------
1 |
64 |
--------------------------------------------------------------------------------
/test/requirements/views/web/index.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 | Yii Application Requirement Checker
10 | renderViewFile(dirname(__FILE__) . '/css.php'); ?>
11 |
12 |
13 |
14 |
15 | Yii Application Requirement Checker
16 |
17 |
18 |
19 | Description
20 |
21 | This script checks if your server configuration meets the requirements
22 | for running Yii application.
23 | It checks if the server is running the right version of PHP,
24 | if appropriate PHP extensions have been loaded, and if php.ini file settings are correct.
25 |
26 |
27 | There are two kinds of requirements being checked. Mandatory requirements are those that have to be met
28 | to allow Yii to work as expected. There are also some optional requirements being checked which will
29 | show you a warning when they do not meet. You can use Yii framework without them but some specific
30 | functionality may be not available in this case.
31 |
32 |
33 | Conclusion
34 | 0): ?>
35 |
36 | Unfortunately your server configuration does not satisfy the requirements by this application.
Please refer to the table below for detailed explanation.
37 |
38 | 0): ?>
39 |
40 | Your server configuration satisfies the minimum requirements by this application.
Please pay attention to the warnings listed below and check if your application will use the corresponding features.
41 |
42 |
43 |
44 | Congratulations! Your server configuration satisfies all requirements.
45 |
46 |
47 |
48 | Details
49 |
50 |
51 | Name | Result | Required By | Memo |
52 |
53 |
54 |
55 |
56 | |
57 |
58 |
59 | |
60 |
61 |
62 | |
63 |
64 |
65 | |
66 |
67 |
68 |
69 |
70 |
71 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------