4

Im pretty new to nginx and - more for learning purpose - im trying to configure Nginx in order to run php with a different user for every subdomains.

For example, i would like to use user john for all scripts on foo.example.com and user jack for bar.example.com.

I have already created the user on my system (ubuntu server), but i dont know how to instruct nginx to use the users - and im looking for a solution tht can handle easly many users, lets say ~2000.

Looking the documentation, i dont understand if i have to spawn a php5-cgi process for every user (with a different port) and then grab them into my sites-available sites (as i said im a newbie, but this looks to me like a server-suicide), and the only 2 pages in the nginx configuration that talk about that.. is written in chinese (page1, page2), hard to translate with google translate (but, looking the codes, uses a totally different from the server-suicide way)

Any suggestion?

Update

galador's answer do the job, but im trying to build a dinamycal environment (with wildcards subdomains) that doesnt need torestart nginx/fpm for every new site, is this possible?

Strae
  • 457
  • 1
  • 8
  • 22
  • You can't do what you want. If you want to do shared hosting then use Apache with mod_php and suexec. Seriously, trying to use Nginx for this is just a huge headache. – Martin Fjordvald Mar 31 '11 at 06:33
  • @Martin: im not tryin to make a shared hosting - i just want each subdomains to run php with a different user for security purpose, i know Plesk do something like that (setting cgi as php wrapper) – Strae Mar 31 '11 at 08:13
  • You might not want to use it for shared hosting but you want the exact same setup. FastCGI is not capable of user switching like this. You can use fpm pools for each subdomain but then you'd need a ton of memory as each pool would need dedicated processes. Shared processes between different users is not possible with FastCGI. – Martin Fjordvald Mar 31 '11 at 08:18
  • @Martin: thanks for your advice, i'll check out suexec then. – Strae Mar 31 '11 at 08:45

1 Answers1

6

Edit: I just noticed your "needs to scale to ~2000 users" requirement... this might not be your best option, but could probably be easily automated with a bit of scripting.

You could use php-fpm to do something like this (fpm is part of the PHP since PHP 5.3.3. I host a couple of sites on my VPS, and use something similar.

My main php-fpm.conf looks like:

;;;;;;;;;;;;;;;;;;;;;
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;
include=/usr/local/etc/fpm.d/*.conf

;;;;;;;;;;;;;;;;;;
; Global Options ;
;;;;;;;;;;;;;;;;;;

[global]
; Pid file
; Default Value: none
pid = /var/run/php-fpm.pid

; Error log file
; Default Value: /var/log/php-fpm.log
error_log = /var/log/php-fpm.log

; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
;log_level = notice

; If this number of child processes exit with SIGSEGV or SIGBUS within the time
; interval set by emergency_restart_interval then FPM will restart. A value
; of '0' means 'Off'.
; Default Value: 0
;emergency_restart_threshold = 0

; Interval of time used by emergency_restart_interval to determine when 
; a graceful restart will be initiated.  This can be useful to work around
; accidental corruptions in an accelerator's shared memory.
; Available Units: s(econds), m(inutes), h(ours), or d(ays)
; Default Unit: seconds
; Default Value: 0
;emergency_restart_interval = 0

; Time limit for child processes to wait for a reaction on signals from master.
; Available units: s(econds), m(inutes), h(ours), or d(ays)
; Default Unit: seconds
; Default Value: 0
;process_control_timeout = 0

; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.
; Default Value: yes
;daemonize = yes

And then, in the fpm.d folder, I have configuration files for each site like this:

[myuser]
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
user = myuser
group = myuser

pm = dynamic
pm.max_children = 15
pm.start_servers = 3
pm.min_spare_servers = 1
pm.max_spare_servers = 5
pm.max_requests = 2000

request_slowlog_timeout = 5
slowlog = /home/myuser/tmp/logs/myuser.slow.log

php_admin_value[error_log] = /home/myuser/tmp/logs/myuser.error.log
php_admin_flag[log_errors] = on

Then, for each site, you change the user and the port in their own file, and in the nginx config, you'd have something like:

location ~ .*.php$ {
    include /usr/local/etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Changing the port in the fastcgi_pass directive.

bhamby
  • 243
  • 1
  • 10
  • From php-fpm, fourth point: `Ability to start workers with different uid/gid/chroot/environment and different php.ini` ..that's exaclty what i need. Thanks, i'll give it a try - but why you updated when noticed my ~2000 users point? Is fastcgi w/o fpm better when there are a lot of users? – Strae Mar 29 '11 at 17:15
  • I just mean that if you had that many different users, you'd have to create a separate configuration for each one, which may be more work than you want. Although, as I said, you can probably do some automating with a bit of scripting. – bhamby Mar 29 '11 at 17:52
  • I try out your solution, works well - but i have to restart nginx and fpm or every new site... i updated my question – Strae Mar 30 '11 at 21:27
  • Sorry, that might be a silly question but: "Then, for each site, you change the user and the port in their own file" - why do you have to change the port too? Isn't the php-fpm children spawned under the user/group specified in conf file? – adrian7 Apr 23 '12 at 11:45
  • You can specify the user/group per process pool. So if you wanted to have two separate pools for two different users where they couldn't access the other's files, then you could spawn it in this way. – bhamby Apr 23 '12 at 17:12