├── Dockerfile ├── README.md ├── circle.yml └── container-files ├── etc ├── hhvm │ ├── php-cli.ini │ └── php.ini ├── nginx │ ├── addon.d │ │ └── php-upstream.conf │ ├── conf.d │ │ └── php-location.conf │ ├── fastcgi_params │ └── hosts.d │ │ └── default.conf └── supervisor.d │ └── hhvm.conf └── usr └── local └── bin └── php /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM million12/nginx:latest 2 | MAINTAINER Marcin Ryzycki 3 | 4 | # Install: 5 | # - HHVM: https://github.com/facebook/hhvm/wiki/Building-and-Installing-HHVM 6 | # note: or maybe we should use gleez repo from https://github.com/facebook/hhvm/wiki/Prebuilt-Packages-on-Centos-6.x ??? 7 | RUN \ 8 | rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm && \ 9 | yum install -y --enablerepo=remi ImageMagick-last* && \ 10 | yum install -y \ 11 | cpp gcc-c++ cmake git psmisc {binutils,boost,jemalloc}-devel \ 12 | {sqlite,tbb,bzip2,openldap,readline,elfutils-libelf,gmp,lz4,pcre}-devel \ 13 | {unixODBC,expat,mariadb}-devel lib{edit,curl,xml2,xslt}-devel \ 14 | lib{xslt,event,yaml,vpx,png,zip,icu,mcrypt,memcached,cap,dwarf}-devel \ 15 | glog-devel oniguruma-devel inotify-tools-devel ocaml && \ 16 | 17 | git clone https://github.com/facebook/hhvm --recursive /tmp/hhvm && \ 18 | cd /tmp/hhvm && \ 19 | 20 | `# Lock dev-master version on 23rd Feb 2015` \ 21 | git checkout 4946bbe1fa50371fe8f49a7c5d38ea9ea02b4461 && \ 22 | cmake \ 23 | -DLIBMAGICKWAND_INCLUDE_DIRS="/usr/include/ImageMagick-6" \ 24 | -DLIBMAGICKCORE_LIBRARIES="/usr/lib64/libMagickCore-6.Q16.so" \ 25 | -DLIBMAGICKWAND_LIBRARIES="/usr/lib64/libMagickWand-6.Q16.so" \ 26 | . && \ 27 | make && \ 28 | ./hphp/hhvm/hhvm --version && \ 29 | make install && \ 30 | 31 | yum clean all && rm -rf /tmp/* && \ 32 | 33 | curl -sS https://getcomposer.org/installer | hhvm --php -- --install-dir=/usr/local/bin --filename=composer && \ 34 | chown www /usr/local/bin/composer 35 | 36 | ADD container-files / 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nginx + HHVM docker container 2 | [![Circle CI](https://circleci.com/gh/million12/docker-nginx-hhvm.svg?style=svg)](https://circleci.com/gh/million12/docker-nginx-hhvm) 3 | 4 | This is a [million12/nginx-hhvm](https://registry.hub.docker.com/u/million12/nginx-hhvm/) docker image with Nginx and HHVM. 5 | 6 | Things included: 7 | 8 | ##### - HHVM 9 | 10 | HHVM version 3.6-dev (the next LTS - long term support) build from the source, on CentOS-7. Note: if you want to build it on your own, it takes a while... (hour(s)). 11 | 12 | HHVM server is up & running and it's configured for default vhost. As soon as .php (or .hh) file is requested, the request will be redirected to HHVM upstream. See [/etc/nginx/conf.d/php-location.conf](container-files/etc/nginx/conf.d/php-location.conf). 13 | 14 | File [/etc/nginx/fastcgi_params](container-files/etc/nginx/fastcgi_params) has improved configuration to avoid repeating same config options for each vhost. This config works well with most PHP applications (e.g. Symfony2, TYPO3, Flow, Neos, Wordpress, Drupal etc). 15 | 16 | Custom PHP.ini settings are inside [/etc/hhvm/php.ini](container-files/etc/hhvm/php.ini). 17 | 18 | ##### - HHVM as PHP CLI 19 | 20 | There's a handy script ([/usr/local/bin/php](container-files/usr/local/bin/php)) which gives you `php` command. 21 | 22 | Custom PHP.ini settings for CLI mode are inside [/etc/hhvm/php-cli.ini](container-files/etc/hhvm/php-cli.ini). 23 | 24 | ##### - directory structure 25 | ``` 26 | /data/www # meant to contain web content 27 | /data/www/default # default vhost directory 28 | /data/logs/ # Nginx, PHP logs 29 | ``` 30 | 31 | ##### - default vhost 32 | 33 | Default vhost is configured and served from `/data/www/default`. Add .php|.hh file to that location to have it executed with HHVM. 34 | 35 | ##### - error logging 36 | 37 | See `/data/logs/`. 38 | 39 | 40 | ## Usage 41 | 42 | ``` 43 | docker run -d -v /data --name=web-data busybox 44 | docker run -d --volumes-from=web-data -p=80:80 --name=hhvm million12/nginx-hhvm 45 | ``` 46 | 47 | After that you can see the default vhost content (something like: '*default vhost created on [timestamp]*') when you open http://CONTAINER_IP:PORT/ in the browser. 48 | 49 | Currently HHVM doesn't output anything useful for phpinfo(). To see **HHVM configuration**, you can use [hhvminfo script](http://tiny.cc/hhvminfo). Enter to the running HHVM container (`docker exec -ti CONTAINER_NAME /bin/bash`), run `curl -sSL http://tiny.cc/hhvminfo -o /data/www/default/hhvminfo.php` and then browse http://CONTAINER_IP:PORT/hhvminfo.php . 50 | 51 | 52 | ## Customise 53 | 54 | There are several ways to customise this container, both in a runtime or when building new image on top of it: 55 | 56 | * See [million12:nginx](https://github.com/million12/docker-nginx) for info regarding Nginx customisation, adding new vhosts etc. 57 | * Override `/etc/nginx/fastcgi_params` if needed. 58 | * Add custom PHP config values to `/etc/hhvm/php.ini` or `/etc/hhvm/php-cli.ini`. 59 | 60 | 61 | ## Authors 62 | 63 | Author: ryzy () 64 | Author: pozgo () 65 | 66 | --- 67 | 68 | **Sponsored by** [Typostrap.io - the new prototyping tool](http://typostrap.io/) for building highly-interactive prototypes of your website or web app. Built on top of TYPO3 Neos CMS and Zurb Foundation framework. 69 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | services: 3 | - docker 4 | 5 | dependencies: 6 | pre: 7 | - docker info && docker version 8 | - docker login --username=$DOCKER_HUB_USERNAME --password=$DOCKER_HUB_PASSWORD --email=$DOCKER_HUB_EMAIL 9 | 10 | override: 11 | - docker pull million12/nginx:latest 12 | 13 | # Run tests 14 | test: 15 | pre: 16 | - docker build -t million12/nginx-hhvm . 17 | 18 | override: 19 | # Launch it 20 | - docker run -d -p 8080:80 --name nginx million12/nginx-hhvm 21 | - while true; do if docker logs nginx | grep "nginx entered RUNNING state"; then break; else sleep 1; fi done 22 | # Add phpinfo 23 | - docker run -ti --volumes-from nginx million12/nginx-hhvm "echo '> /data/www/default/index.php" 24 | - docker run -ti --volumes-from nginx million12/nginx-hhvm "curl -sSL http://tiny.cc/hhvminfo -o /data/www/default/hhvminfo.php" 25 | # Check phpinfo page 26 | - curl -s --show-error http://localhost:8080 | grep 'HipHop' 27 | - curl -s --show-error http://localhost:8080/hhvminfo.php | grep 'HHVMinfo' 28 | - curl -s --show-error http://localhost:8080/hhvminfo.php | grep 'HHVM Version' 29 | 30 | # Check if we have modules installed / loaded 31 | - curl -s --show-error http://localhost:8080/hhvminfo.php?EXTENSIONS | grep 'hhvm' 32 | - curl -s --show-error http://localhost:8080/hhvminfo.php?EXTENSIONS | grep 'imagick' 33 | - curl -s --show-error http://localhost:8080/hhvminfo.php?EXTENSIONS | grep 'memcached' 34 | - curl -s --show-error http://localhost:8080/hhvminfo.php?EXTENSIONS | grep 'pdo_mysql' 35 | - curl -s --show-error http://localhost:8080/hhvminfo.php?EXTENSIONS | grep 'redis' 36 | - curl -s --show-error http://localhost:8080/hhvminfo.php?EXTENSIONS | grep 'zlib' 37 | 38 | # Check if php command works as expected 39 | - docker run -ti million12/nginx-hhvm "php -v" 40 | - docker run -ti million12/nginx-hhvm "php -v" | grep "HipHop VM" 41 | - docker run -ti million12/nginx-hhvm "php -r \"var_dump(ini_get('date.timezone'));\"" | grep GMT 42 | 43 | 44 | # Due to timeouts when building this image Docker Hub, it cannot be build there. 45 | # Therefore we have to push it manually from here... 46 | deployment: 47 | push_built_image_to_docker_hub: 48 | branch: master 49 | commands: 50 | - docker push million12/nginx-hhvm 51 | -------------------------------------------------------------------------------- /container-files/etc/hhvm/php-cli.ini: -------------------------------------------------------------------------------- 1 | ; HHVM tuning 2 | ; Disable JIT for CLI as it's not beneficial for on-time processes 3 | hhvm.jit = 0 4 | hhvm.mysql.typed_results = 0 5 | hhvm.http.slow_query_threshold = 30000 6 | 7 | ; PHP settings 8 | date.timezone = GMT 9 | error_reporting = -1 10 | -------------------------------------------------------------------------------- /container-files/etc/hhvm/php.ini: -------------------------------------------------------------------------------- 1 | ; HHVM server settings 2 | hhvm.pid_file = /run/hhvm.pid 3 | hhvm.repo.central.path = /run/.hhvm.hhbc 4 | 5 | hhvm.server.type = fastcgi 6 | hhvm.server.port = 9000 7 | hhvm.server.user = www 8 | hhvm.admin_server.port = 9001 9 | 10 | hhvm.log.header = 1 11 | hhvm.log.natives_stack_trace = 1 12 | hhvm.log.always_log_unhandled_exceptions = 1 13 | hhvm.log.use_log_file = 1 14 | hhvm.log.file = /data/logs/hhvm.log 15 | 16 | ; HHVM tuning 17 | hhvm.mysql.typed_results = 0 18 | hhvm.http.slow_query_threshold = 30000 19 | 20 | ; PHP settings 21 | expose_php = 0 22 | date.timezone = GMT 23 | error_reporting = -1 24 | memory_limit = 512M 25 | -------------------------------------------------------------------------------- /container-files/etc/nginx/addon.d/php-upstream.conf: -------------------------------------------------------------------------------- 1 | upstream php-upstream { 2 | server 127.0.0.1:9000; 3 | } 4 | -------------------------------------------------------------------------------- /container-files/etc/nginx/conf.d/php-location.conf: -------------------------------------------------------------------------------- 1 | location ~ \.(php|hh)$ { 2 | include fastcgi_params; 3 | fastcgi_pass php-upstream; 4 | } 5 | -------------------------------------------------------------------------------- /container-files/etc/nginx/fastcgi_params: -------------------------------------------------------------------------------- 1 | fastcgi_param QUERY_STRING $query_string; 2 | fastcgi_param REQUEST_METHOD $request_method; 3 | fastcgi_param CONTENT_TYPE $content_type; 4 | fastcgi_param CONTENT_LENGTH $content_length; 5 | 6 | fastcgi_param PATH_INFO $fastcgi_script_name; 7 | fastcgi_param SCRIPT_NAME $fastcgi_script_name; 8 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 9 | fastcgi_param REQUEST_URI $request_uri; 10 | fastcgi_param DOCUMENT_URI $document_uri; 11 | fastcgi_param DOCUMENT_ROOT $document_root; 12 | fastcgi_param SERVER_PROTOCOL $server_protocol; 13 | fastcgi_param HTTPS $https if_not_empty; 14 | 15 | fastcgi_param GATEWAY_INTERFACE CGI/1.1; 16 | fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 17 | 18 | fastcgi_param REMOTE_ADDR $remote_addr; 19 | fastcgi_param REMOTE_PORT $remote_port; 20 | fastcgi_param SERVER_ADDR $server_addr; 21 | 22 | # SERVER_PORT needs to be commented out and has to be determined from other fields (e.g. HTTP_HOST) 23 | # Otherwise it points invalid port when container port is mapped to different port on host machine, 24 | # which might result with invalid links generated in a PHP app. 25 | #fastcgi_param SERVER_PORT $server_port; 26 | 27 | # Using $http_host instead of $server_name - $server_name doesn't work correctly when using regexps in vhosts' server_name declaration. 28 | #fastcgi_param SERVER_NAME $server_name; 29 | fastcgi_param SERVER_NAME $http_host; 30 | 31 | # PHP only, required if PHP was built with --enable-force-cgi-redirect 32 | fastcgi_param REDIRECT_STATUS 200; 33 | 34 | fastcgi_index index.php; 35 | fastcgi_connect_timeout 10; 36 | fastcgi_send_timeout 600; 37 | fastcgi_read_timeout 600; 38 | fastcgi_buffer_size 32k; 39 | fastcgi_buffers 32 4k; 40 | fastcgi_busy_buffers_size 64k; 41 | fastcgi_temp_file_write_size 256k; 42 | fastcgi_intercept_errors on; 43 | fastcgi_pass_header on; 44 | fastcgi_keep_conn on; 45 | -------------------------------------------------------------------------------- /container-files/etc/nginx/hosts.d/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default; 3 | root /data/www/default; 4 | index index.php index.html; 5 | 6 | include /etc/nginx/conf.d/default-*.conf; 7 | include /data/conf/nginx/conf.d/default-*.conf; 8 | 9 | # PHP backend is not in the default-*.conf file set, 10 | # as some vhost might not want to include it. 11 | include /etc/nginx/conf.d/php-location.conf; 12 | } 13 | -------------------------------------------------------------------------------- /container-files/etc/supervisor.d/hhvm.conf: -------------------------------------------------------------------------------- 1 | [program:hhvm] 2 | command = hhvm --mode server --config /etc/hhvm/php.ini 3 | autorestart = true 4 | stdout_logfile = /data/logs/hhvm.log 5 | stderr_logfile = /data/logs/hhvm.log 6 | -------------------------------------------------------------------------------- /container-files/usr/local/bin/php: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | hhvm --php -c /etc/hhvm/php-cli.ini $@ 4 | --------------------------------------------------------------------------------