├── .gitignore ├── build.sh ├── conf ├── modules.ini ├── php-fpm.conf ├── php7-fpm.init └── www.conf ├── extensions ├── imagick-build.sh ├── imagick-install.sh ├── memcached-build.sh ├── memcached-install.sh ├── redis-build.sh └── redis-install.sh ├── install.sh ├── readme.md └── remove.sh /.gitignore: -------------------------------------------------------------------------------- 1 | php-src 2 | extensions/imagick/ 3 | extensions/phpredis/ 4 | extensions/php-memcached/ 5 | 6 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$(dirname "$0")" 3 | 4 | # Use all cores for the build process 5 | CORE_COUNT=$(cat /proc/cpuinfo | grep -c processor) 6 | 7 | # Allow JOB_COUNT environment variable to override the job count 8 | JOB_COUNT=${JOB_COUNT:-$CORE_COUNT} 9 | 10 | # Dependencies 11 | sudo apt-get update 12 | sudo apt-get install -y \ 13 | build-essential \ 14 | pkg-config \ 15 | git-core \ 16 | autoconf \ 17 | bison \ 18 | re2c \ 19 | libonig-dev \ 20 | libsqlite3-dev \ 21 | libxml2-dev \ 22 | libbz2-dev \ 23 | libicu-dev \ 24 | libssl-dev \ 25 | libcurl4-openssl-dev \ 26 | libltdl-dev \ 27 | libjpeg-dev \ 28 | libpng-dev \ 29 | libpspell-dev \ 30 | libreadline-dev 31 | 32 | sudo mkdir /usr/local/php7 33 | 34 | git clone https://github.com/php/php-src.git 35 | cd php-src 36 | git fetch --tags --prune 37 | git checkout tags/php-7.4.5 38 | ./buildconf --force 39 | 40 | CONFIGURE_STRING="--prefix=/usr/local/php7 \ 41 | --enable-huge-code-pages \ 42 | --with-config-file-scan-dir=/usr/local/php7/etc/conf.d \ 43 | --enable-bcmath \ 44 | --with-bz2 \ 45 | --enable-calendar \ 46 | --enable-intl \ 47 | --enable-exif \ 48 | --enable-dba \ 49 | --enable-ftp \ 50 | --with-gettext \ 51 | --with-gd \ 52 | --with-jpeg-dir \ 53 | --enable-mbstring \ 54 | --with-mhash \ 55 | --enable-mysqlnd \ 56 | --with-mysqli \ 57 | --with-mysql-sock=yes \ 58 | --with-pdo-mysql \ 59 | --with-openssl \ 60 | --enable-pcntl \ 61 | --with-pspell \ 62 | --enable-shmop \ 63 | --enable-soap \ 64 | --enable-sockets \ 65 | --enable-sysvmsg \ 66 | --enable-sysvsem \ 67 | --enable-sysvshm \ 68 | --enable-wddx \ 69 | --with-zlib \ 70 | --enable-zip \ 71 | --without-libzip \ 72 | --with-readline \ 73 | --with-curl \ 74 | --enable-fpm \ 75 | --with-fpm-user=www-data \ 76 | --with-fpm-group=www-data" 77 | 78 | ./configure $CONFIGURE_STRING 79 | 80 | make -j "$JOB_COUNT" 81 | sudo make install 82 | -------------------------------------------------------------------------------- /conf/modules.ini: -------------------------------------------------------------------------------- 1 | # Zend OPcache 2 | zend_extension=opcache.so 3 | -------------------------------------------------------------------------------- /conf/php-fpm.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | 3 | pid = /var/run/php7-fpm.pid 4 | error_log = /var/log/php7-fpm.log 5 | 6 | include=/usr/local/php7/etc/php-fpm.d/*.conf 7 | -------------------------------------------------------------------------------- /conf/php7-fpm.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: php7-fpm 4 | # Required-Start: $remote_fs $network 5 | # Required-Stop: $remote_fs $network 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: starts php7-fpm 9 | # Description: Starts The PHP FastCGI Process Manager Daemon 10 | ### END INIT INFO 11 | 12 | # Author: Ondrej Sury 13 | # Adjusted for PHP7 by Kaspars Dambis 14 | 15 | PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/php7/sbin 16 | DESC="PHP7 FastCGI Process Manager" 17 | NAME=php7-fpm 18 | DAEMON=/usr/local/php7/sbin/$NAME 19 | CONFFILE=/usr/local/php7/etc/php-fpm.conf 20 | DAEMON_ARGS="--daemonize --fpm-config $CONFFILE" 21 | CONF_PIDFILE=$(sed -n 's/^pid[ =]*//p' $CONFFILE) 22 | PIDFILE=${CONF_PIDFILE:-/var/run/php7-fpm.pid} 23 | TIMEOUT=30 24 | SCRIPTNAME=/etc/init.d/$NAME 25 | 26 | # Exit if the package is not installed 27 | [ -x "$DAEMON" ] || exit 0 28 | 29 | # Read configuration variable file if it is present 30 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 31 | 32 | # Load the VERBOSE setting and other rcS variables 33 | . /lib/init/vars.sh 34 | 35 | # Define LSB log_* functions. 36 | # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. 37 | . /lib/lsb/init-functions 38 | 39 | # Don't run if we are running upstart 40 | if init_is_upstart; then 41 | exit 1 42 | fi 43 | 44 | # 45 | # Function to check the correctness of the config file 46 | # 47 | do_check() 48 | { 49 | # Run php-fpm with -t option to check the configuration file syntax 50 | errors=$($DAEMON --fpm-config $CONFFILE -t 2>&1 | grep -i "error" || true); 51 | if [ -n "$errors" ]; then 52 | echo "Please fix your configuration file..." 53 | echo $errors 54 | return 1 55 | fi 56 | return 0 57 | } 58 | 59 | # 60 | # Function that starts the daemon/service 61 | # 62 | do_start() 63 | { 64 | # Return 65 | # 0 if daemon has been started 66 | # 1 if daemon was already running 67 | # 2 if daemon could not be started 68 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ 69 | || return 1 70 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ 71 | $DAEMON_ARGS 2>/dev/null \ 72 | || return 2 73 | # Add code here, if necessary, that waits for the process to be ready 74 | # to handle requests from services started subsequently which depend 75 | # on this one. As a last resort, sleep for some time. 76 | } 77 | 78 | # 79 | # Function that stops the daemon/service 80 | # 81 | do_stop() 82 | { 83 | # Return 84 | # 0 if daemon has been stopped 85 | # 1 if daemon was already stopped 86 | # 2 if daemon could not be stopped 87 | # other if a failure occurred 88 | start-stop-daemon --stop --quiet --retry=QUIT/$TIMEOUT/TERM/5/KILL/5 --pidfile $PIDFILE --name $NAME 89 | RETVAL="$?" 90 | [ "$RETVAL" = 2 ] && return 2 91 | # Wait for children to finish too if this is a daemon that forks 92 | # and if the daemon is only ever run from this initscript. 93 | # If the above conditions are not satisfied then add some other code 94 | # that waits for the process to drop all resources that could be 95 | # needed by services started subsequently. A last resort is to 96 | # sleep for some time. 97 | start-stop-daemon --stop --quiet --oknodo --retry=0/30/TERM/5/KILL/5 --exec $DAEMON 98 | [ "$?" = 2 ] && return 2 99 | # Many daemons don't delete their pidfiles when they exit. 100 | rm -f $PIDFILE 101 | return "$RETVAL" 102 | } 103 | 104 | # 105 | # Function that sends a SIGHUP to the daemon/service 106 | # 107 | do_reload() { 108 | # 109 | # If the daemon can reload its configuration without 110 | # restarting (for example, when it is sent a SIGHUP), 111 | # then implement that here. 112 | # 113 | start-stop-daemon --stop --signal USR2 --quiet --pidfile $PIDFILE --name $NAME 114 | return 0 115 | } 116 | 117 | case "$1" in 118 | start) 119 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 120 | do_check $VERBOSE 121 | case "$?" in 122 | 0) 123 | do_start 124 | case "$?" in 125 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 126 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 127 | esac 128 | ;; 129 | 1) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 130 | esac 131 | ;; 132 | stop) 133 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 134 | do_stop 135 | case "$?" in 136 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 137 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 138 | esac 139 | ;; 140 | status) 141 | status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? 142 | ;; 143 | check) 144 | do_check yes 145 | ;; 146 | reload|force-reload) 147 | log_daemon_msg "Reloading $DESC" "$NAME" 148 | do_reload 149 | log_end_msg $? 150 | ;; 151 | reopen-logs) 152 | log_daemon_msg "Reopening $DESC logs" $NAME 153 | if start-stop-daemon --stop --signal USR1 --oknodo --quiet \ 154 | --pidfile $PIDFILE --exec $DAEMON 155 | then 156 | log_end_msg 0 157 | else 158 | log_end_msg 1 159 | fi 160 | ;; 161 | restart) 162 | log_daemon_msg "Restarting $DESC" "$NAME" 163 | do_stop 164 | case "$?" in 165 | 0|1) 166 | do_start 167 | case "$?" in 168 | 0) log_end_msg 0 ;; 169 | 1) log_end_msg 1 ;; # Old process is still running 170 | *) log_end_msg 1 ;; # Failed to start 171 | esac 172 | ;; 173 | *) 174 | # Failed to stop 175 | log_end_msg 1 176 | ;; 177 | esac 178 | ;; 179 | *) 180 | echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2 181 | exit 1 182 | ;; 183 | esac 184 | 185 | : 186 | -------------------------------------------------------------------------------- /conf/www.conf: -------------------------------------------------------------------------------- 1 | [www] 2 | 3 | user = www-data 4 | group = www-data 5 | 6 | listen = 127.0.0.1:9007 7 | 8 | pm = dynamic 9 | pm.max_children = 5 10 | pm.start_servers = 2 11 | pm.min_spare_servers = 1 12 | pm.max_spare_servers = 3 13 | -------------------------------------------------------------------------------- /extensions/imagick-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$(dirname "$0")" 3 | 4 | # Dependencies 5 | sudo apt-get update 6 | sudo apt-get install -y \ 7 | imagemagick \ 8 | libmagickwand-dev 9 | 10 | git clone https://github.com/mkoppanen/imagick.git 11 | cd imagick 12 | git pull 13 | 14 | /usr/local/php7/bin/phpize 15 | ./configure --with-php-config=/usr/local/php7/bin/php-config 16 | 17 | make 18 | sudo make install 19 | -------------------------------------------------------------------------------- /extensions/imagick-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Add config files 4 | echo "extension=imagick.so" | sudo tee -a /usr/local/php7/etc/conf.d/modules.ini 5 | -------------------------------------------------------------------------------- /extensions/memcached-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$(dirname "$0")" 3 | 4 | # Dependencies 5 | sudo apt-get update 6 | sudo apt-get install -y \ 7 | libmemcached-dev \ 8 | libmemcached11 9 | 10 | git clone https://github.com/php-memcached-dev/php-memcached 11 | cd php-memcached 12 | 13 | # Fetch the latest changes 14 | git fetch --tags --prune 15 | 16 | # Get the latest tag 17 | TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) 18 | 19 | git checkout -f tags/$TAG 20 | git reset --hard 21 | 22 | /usr/local/php7/bin/phpize 23 | ./configure --with-php-config=/usr/local/php7/bin/php-config 24 | 25 | make 26 | sudo make install 27 | -------------------------------------------------------------------------------- /extensions/memcached-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Enable the module 4 | echo "extension=memcached.so" | sudo tee -a /usr/local/php7/etc/conf.d/modules.ini 5 | -------------------------------------------------------------------------------- /extensions/redis-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$(dirname "$0")" 3 | 4 | # Dependencies 5 | sudo apt-get update 6 | sudo apt-get install -y \ 7 | redis-server 8 | 9 | git clone https://github.com/phpredis/phpredis.git 10 | cd phpredis 11 | 12 | # Fetch the latest changes 13 | git fetch --tags --prune 14 | 15 | # Get the latest tag 16 | TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) 17 | 18 | git checkout -f tags/$TAG 19 | git reset --hard 20 | 21 | /usr/local/php7/bin/phpize 22 | ./configure --with-php-config=/usr/local/php7/bin/php-config 23 | 24 | make 25 | sudo make install 26 | -------------------------------------------------------------------------------- /extensions/redis-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Enable the module 4 | echo "extension=redis.so" | sudo tee -a /usr/local/php7/etc/conf.d/modules.ini 5 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$(dirname "$0")" 3 | 4 | # Create a dir for storing PHP module conf 5 | mkdir /usr/local/php7/etc/conf.d 6 | 7 | # Symlink php-fpm to php7-fpm 8 | ln -s /usr/local/php7/sbin/php-fpm /usr/local/php7/sbin/php7-fpm 9 | 10 | # Add config files 11 | cp php-src/php.ini-production /usr/local/php7/lib/php.ini 12 | cp conf/www.conf /usr/local/php7/etc/php-fpm.d/www.conf 13 | cp conf/php-fpm.conf /usr/local/php7/etc/php-fpm.conf 14 | cp conf/modules.ini /usr/local/php7/etc/conf.d/modules.ini 15 | 16 | # Add the init script 17 | cp conf/php7-fpm.init /etc/init.d/php7-fpm 18 | chmod +x /etc/init.d/php7-fpm 19 | update-rc.d php7-fpm defaults 20 | 21 | service php7-fpm start -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Install PHP 7 on Debian/Ubuntu 2 | 3 | These are a set of bash scripts for building and running PHP 7 (CLI and FPM) on Debian based Linux distributions: 4 | 5 | - `build.sh` installs the necessary build dependencies and the latest stable version of PHP with CLI and FPM server APIs (SAPI) from the latest PHP 7 branch of https://github.com/php/php-src. 6 | 7 | - `install.sh` sets up PHP-FPM by moving configuration files into their correct locations in `/usr/local/php7` and enables the `php7-fpm` service and adds it to the startup sequence. 8 | 9 | Please note that these are very simple scripts that don't implement error checking or process validation. 10 | 11 | ![Building PHP 7 on Orange Pi Zero (ARM)](https://kaspars.net/wp-content/uploads/2017/02/orange-pi-zero-php7-build.png) 12 | 13 | 14 | ## Usage 15 | 16 | $ git clone https://github.com/kasparsd/php-7-debian.git 17 | $ cd php-7-debian 18 | $ ./build.sh 19 | $ sudo ./install.sh 20 | 21 | On systems with little amount of RAM such as Raspberry Pi you might want to decrease the number of parallel `make` jobs by passing the `JOB_COUNT` variable: 22 | 23 | $ JOB_COUNT=1 ./build.sh 24 | 25 | The default job count is equal to the number of CPU cores. 26 | 27 | The PHP-FPM can be operated using the `php7-fpm` init script: 28 | 29 | Usage: /etc/init.d/php7-fpm {start|stop|status|restart|reload|force-reload} 30 | 31 | while the FPM socket is available at 32 | 33 | 127.0.0.1:9007 34 | 35 | and PHP CLI at `/usr/local/php7/bin/php`. 36 | 37 | ### Updating 38 | 39 | Pull down the latest changes from this repository `git pull` and run `./build.sh`. 40 | 41 | 42 | ## Configuration files 43 | 44 | All PHP configuration files are stored under `/usr/local/php7`: 45 | 46 | /usr/local/php7/lib/php.ini 47 | /usr/local/php7/etc/php-fpm.conf 48 | /usr/local/php7/etc/php-fpm.d/www.conf 49 | /usr/local/php7/etc/conf.d/modules.ini 50 | 51 | while the Debian init script is added to: 52 | 53 | /etc/init.d/php7-fpm 54 | 55 | 56 | ## Extensions 57 | 58 | Here is a list of PHP modules that are enabled by default in this build: 59 | 60 | $ /usr/local/php7/bin/php -m 61 | [PHP Modules] 62 | bcmath 63 | bz2 64 | calendar 65 | Core 66 | ctype 67 | curl 68 | date 69 | dba 70 | dom 71 | exif 72 | fileinfo 73 | filter 74 | ftp 75 | gd 76 | gettext 77 | hash 78 | iconv 79 | intl 80 | json 81 | libxml 82 | mbstring 83 | mysqli 84 | mysqlnd 85 | openssl 86 | pcntl 87 | pcre 88 | PDO 89 | pdo_mysql 90 | pdo_sqlite 91 | Phar 92 | posix 93 | pspell 94 | readline 95 | Reflection 96 | session 97 | shmop 98 | SimpleXML 99 | soap 100 | sockets 101 | SPL 102 | sqlite3 103 | standard 104 | sysvmsg 105 | sysvsem 106 | sysvshm 107 | tokenizer 108 | wddx 109 | xml 110 | xmlreader 111 | xmlwriter 112 | Zend OPcache 113 | zip 114 | zlib 115 | 116 | [Zend Modules] 117 | Zend OPcache 118 | 119 | 120 | ## Installing Extensions 121 | 122 | Please note that you need to restart `php7-fpm` to activate the extension. 123 | 124 | ### Install the Memcached Extension 125 | 126 | $ cd php-7-debian/extensions 127 | $ ./memcached-build.sh 128 | $ ./memcached-install.sh 129 | 130 | ### Install the Imagick Extension 131 | 132 | $ cd php-7-debian/extensions 133 | $ ./imagick-build.sh 134 | $ ./imagick-install.sh 135 | 136 | 137 | ## Credits 138 | 139 | - Created by [Kaspars Dambis](https://kaspars.net) 140 | - Contributors: [Piotr Plenik](https://github.com/jupeter) 141 | - Based on [`php7.sh`](https://gist.github.com/tvlooy/953a7c0658e70b573ab4) by [Tom Van Looy](http://www.intracto.com/nl/blog/running-symfony2-on-php7) 142 | -------------------------------------------------------------------------------- /remove.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /etc/init.d/php7-fpm stop 4 | rm -r /usr/local/php7 5 | update-rc.d php7-fpm remove 6 | rm /etc/init.d/php7-fpm 7 | --------------------------------------------------------------------------------