Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run php-fpm as a separate process #330

Open
wants to merge 3 commits into
base: next-release
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 90 additions & 81 deletions cookbooks/php/recipes/fpm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,44 +41,39 @@ class Chef::Recipe
action :create
end

# stopping common php-fpm service if it's running
execute 'stop obsolete php-fpm service' do
command "/usr/bin/monit stop php-fpm"
only_if "/usr/bin/monit status php-fpm"
end

# deleting obsolete service files
execute 'delete old init scripts' do
command "rm -f /etc/monit.d/php-fpm.monitrc && rm -rf /etc/init.d/php-fpm && rm -f /engineyard/bin/php-fpm"
only_if "test -f /etc/monit.d/php-fpm.monitrc"
end

monit_service 'monit_reload_config' do
action :nothing
end

bash 'eselect php and restart via monit' do
code <<-EOH
eselect php set fpm php#{node["php"]["minor_version"]}
EOH
not_if "php-fpm -v | grep PHP | grep #{node['php']['version']}"
notifies :run, 'execute[monit_restart_fpm]'
end


execute 'monit_restart_fpm' do
command "sudo monit restart php-fpm"
action :nothing
notifies :restartall, 'monit_service[monit_reload_config]'
end




# get all applications with type PHP
apps = node.dna['applications'].select{ |app, data| data['recipes'].detect{ |r| r == 'php' } }
# collect just the app names
app_names = apps.collect{ |app, data| app }

# generate global fpm config
template "/etc/php-fpm.conf" do
owner node["owner_name"]
group node["owner_name"]
mode "0644"
source "fpm-global.conf.erb"
variables({
:apps => app_names
})
# notifies :restart, resources(:service => "php-fpm"), :delayed
end

# Can't access get_fpm_coount inside block
app_fpm_count = (get_fpm_count / node.dna['applications'].size)
app_fpm_count = 1 unless app_fpm_count >= 1
mc_hostnames = node.engineyard.environment.instances.map{|i| i['private_hostname'] if i['role'][/^app|solo/]}.compact.map {|i| "#{i}:11211"}

# generate an fpm pool for each php app
app_names.each do |app_name|
Expand All @@ -91,7 +86,73 @@ class Chef::Recipe
not_if { FileTest.exists?("/data/#{app_name}/shared/config/env.custom") }
end

mc_hostnames = node.engineyard.environment.instances.map{|i| i['private_hostname'] if i['role'][/^app|solo/]}.compact.map {|i| "#{i}:11211"}
# Create init.d for each php-fpm application
# To be able to start and stop each application separately
template "/engineyard/bin/php-fpm_#{app_name}" do
owner node["owner_name"]
group node["owner_name"]
mode 0777
source "php-fpm-openrc.erb"
variables(
:app_name => app_name,
:user => node["owner_name"],
:group => node["owner_name"]
)
end

# Delete any existing init.d file if it's not a symlink
cookbook_file "/etc/init.d/php-fpm_#{app_name}" do
action :delete
backup 0
not_if "test -h /etc/init.d/php-fpm_#{app_name}"
end

# Create a symlink under init.d
link "/etc/init.d/php-fpm_#{app_name}" do
to "/engineyard/bin/php-fpm_#{app_name}"
end

# create symlinks for each app too. Required for deploy.
link "/engineyard/bin/app_#{app_name}" do
to "/engineyard/bin/php-fpm_#{app_name}"
end

# Create monitrc file for the application and restart monit
template "/etc/monit.d/php-fpm_#{app_name}.monitrc" do
owner node["owner_name"]
group node["owner_name"]
mode 0600
source "php-fpm.monitrc.erb"
variables(
:app_name => app_name
)
backup 0
notifies :reload, "monit_service[monit_reload_config]", :immediately
end

# generate global fpm config
template "/etc/php/php-fpm_#{app_name}.conf" do
owner node["owner_name"]
group node["owner_name"]
mode "0644"
source "fpm-global.conf.erb"
variables({
:app_name => app_name
})
notifies :restart, "monit_service[php-fpm_#{app_name}]", :delayed
end

# generate global fpm config
template "/etc/php/php-fpm_#{app_name}.conf" do
owner node["owner_name"]
group node["owner_name"]
mode "0644"
source "fpm-global.conf.erb"
variables({
:app_name => app_name
})
notifies :restart, "monit_service[php-fpm_#{app_name}]", :delayed
end

template "/data/#{app_name}/shared/config/fpm-pool.conf" do
owner node["owner_name"]
Expand All @@ -109,67 +170,15 @@ class Chef::Recipe
:max_children => app_fpm_count,
:memcache_hostnames => mc_hostnames.join(',')
})

notifies :restart, "monit_service[php-fpm_#{app_name}]", :delayed
end
end

# Report to Cloud dashboard
#ey_cloud_report "processing php" do
# message "processing php - monitoring"
#end

# Create global init.d file
# We are unable to start and stop each app individually
cookbook_file "/engineyard/bin/php-fpm" do
owner node["owner_name"]
group node["owner_name"]
mode 0777
source "init.d-php-fpm.sh"
backup 0
end

# Delete any existing init.d file if it's not a symlink
cookbook_file "/etc/init.d/php-fpm" do
action :delete
backup 0

not_if "test -h /etc/init.d/php-fpm"
end

# Create a symlink under init.d
link "/etc/init.d/php-fpm" do
to "/engineyard/bin/php-fpm"
end

# get all applications with type PHP
apps = node.dna['applications'].select{ |app, data| data['recipes'].detect{ |r| r == 'php' } }
# collect just the app names
app_names = apps.collect{ |app, data| app }

app_names.each do |app|
# create symlinks for each app, too. Required for deploy.
link "/engineyard/bin/app_#{app}" do
to "/engineyard/bin/php-fpm"
monit_service "php-fpm_#{app_name}" do
service_name "php-fpm_#{app_name}"
action :start
end

# Change ownership of app slowlog if set to root
check_fpm_log_owner(app)
end
check_fpm_log_owner(app_name)

# Create monitrc file (all apps) and restart monit
template "/etc/monit.d/php-fpm.monitrc" do
owner node["owner_name"]
group node["owner_name"]
mode 0600
source "php-fpm.monitrc.erb"
variables(
:apps => app_names,
:user => node["owner_name"]
)
backup 0

notifies :run, 'execute[restart-monit]'
end

# cookbooks/php/libraries/php_helpers.rb
restart_fpm
34 changes: 34 additions & 0 deletions cookbooks/php/resources/monit_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#
# Cookbook:: php
# Resource:: monit_service
#
# Author:: Jevgenij Sevostjanov <jevgenij@lmiw.net>

resource_name :monit_service

property :service_name, String, name_property: true

action :start do
execute "monit start #{new_resource.service_name}" do
command "/usr/bin/monit start #{new_resource.service_name}"
not_if "/usr/bin/monit status #{new_resource.service_name} | grep -Eq 'Initializing|Running'"
end
end

action :restart do
execute "monit restart #{new_resource.service_name}" do
command "/usr/bin/monit restart #{new_resource.service_name}"
end
end

action :restartall do
execute "monit restart all php-fpm services" do
command "/usr/bin/monit restart all -g php-fpm"
end
end

action :reload do
execute "monit reload" do
command "/usr/bin/monit reload && sleep 3"
end
end
10 changes: 5 additions & 5 deletions cookbooks/php/templates/default/fpm-global.conf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;

; For application <%= @app_name %>

; All relative paths in this configuration file are relative to PHP's install
; prefix (/usr/lib64/php5.3). This prefix can be dynamicaly changed by using the
; '-p' argument from the command line.
Expand All @@ -22,14 +24,14 @@
; Pid file
; Note: the default prefix is /usr/lib64/php5.3/var
; Default Value: none
pid = /var/run/engineyard/php-fpm.pid
pid = /var/run/engineyard/php-fpm_<%= @app_name %>.pid

; Error log file
; If it's set to "syslog", log is sent to syslogd instead of being written
; in a local file.
; Note: the default prefix is /usr/lib64/php5.3/var
; Default Value: log/php-fpm.log
error_log = /var/log/engineyard/php-fpm/error.log
error_log = /var/log/engineyard/php-fpm/<%= @app_name %>_error.log

; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
Expand Down Expand Up @@ -103,6 +105,4 @@ error_log = /var/log/engineyard/php-fpm/error.log
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;

<% @apps.each do |app| %>
include = /data/<%= app %>/shared/config/fpm-pool.conf
<% end %>
include = /data/<%= @app_name %>/shared/config/fpm-pool.conf
3 changes: 1 addition & 2 deletions cookbooks/php/templates/default/fpm-pool.conf.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
; PHP-FPM pool configuration for <%= @app_name %>
[<%= @app_name %>]
php_admin_value[error_log] = /data/<%= @app_name %>/current/log/error_log
listen = /var/run/engineyard/php-fpm_<%= @app_name %>.sock
user = <%= @user %>
group = <%= @user %>

listen.backlog = -1
pm = static
Expand Down
48 changes: 48 additions & 0 deletions cookbooks/php/templates/default/php-fpm-openrc.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/sbin/openrc-run

set_phpvars() {
PHP_FPM_CONF="/etc/php/php-fpm_<%= @app_name %>.conf"
PHP_FPM_PID="/var/run/engineyard/php-fpm_<%= @app_name %>.pid"
PHP_FPM_USER="<%= @user %>"
PHP_FPM_GROUP="<%= @group %>"
}

extra_commands="reload"

start() {
ebegin "Starting PHP FastCGI Process Manager for <%= @app_name %>"
set_phpvars
start-stop-daemon --start -u ${PHP_FPM_USER} -g ${PHP_FPM_GROUP} --pidfile ${PHP_FPM_PID} --exec \
/usr/bin/php-fpm -- -y "${PHP_FPM_CONF}" -g "${PHP_FPM_PID}"
local i=0
local timeout=5
while [ ! -f ${PHP_FPM_PID} ] && [ $i -le $timeout ]; do
sleep 1
i=$(($i + 1))
done

[ $timeout -gt $i ]
eend $?
}

stop() {
ebegin "Stopping PHP FastCGI Process Manager for <%= @app_name %>"
set_phpvars
start-stop-daemon --signal QUIT --stop --exec /usr/bin/php-fpm --pidfile ${PHP_FPM_PID}
eend $?
}

reload() {
ebegin "Reloading <%= @app_name %> PHP FastCGI Process Manager"
set_phpvars
if [ -f ${PHP_FPM_PID} ]; then
kill -USR2 $(cat ${PHP_FPM_PID})
else
echo "<%= @app_name %> PHP-FPM process is not running restarting"
start
if [ $? == 0 ]; then
mark_service_started
fi
fi
eend $?
}
15 changes: 6 additions & 9 deletions cookbooks/php/templates/default/php-fpm.monitrc.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
check process php-fpm
with pidfile /var/run/engineyard/php-fpm.pid
check process php-fpm_<%= @app_name %>
with pidfile /var/run/engineyard/php-fpm_<%= @app_name %>.pid
group php-fpm
start program = "/bin/bash -c '/etc/init.d/php-fpm start'"
as uid <%= @user %> and gid <%= @user %>
stop program = "/bin/bash -c '/etc/init.d/php-fpm stop'"
as uid <%= @user %> and gid <%= @user %>
<% @apps.each do |app| %>
if failed unixsocket /var/run/engineyard/php-fpm_<%= app %>.sock then restart
<% end %>
start program = "/bin/bash -c '/etc/init.d/php-fpm_<%= @app_name %> start'"
stop program = "/bin/bash -c '/etc/init.d/php-fpm_<%= @app_name %> stop'"
restart program = "/bin/bash -c '/etc/init.d/php-fpm_<%= @app_name %> reload'"
if failed unixsocket /var/run/engineyard/php-fpm_<%= @app_name %>.sock then restart