Nginx RTMP not recording - php

I already setting up Nginx RTMP in ubuntu linux hosted by DigitalOcean. And currently running my laravel web application in localhost mode in my desktop. Everything seems work fine for the live streaming. I'm testing with my localhost JWPlayer and Open Broadcaster Software(OBS) for live streaming. It works. But whenever I need to record the streaming video to linux directory (/var/www), seems like nothing happen and no error at all after I hit stop streaming button in OBS.
I'm don't know how does the recording works, I try record manual and it has the link on it. I click start record, it comes out /var/rec/{mystream}.flv
This manual version of recording link embed in laravel website:
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
recorder rec1 {
record all manual;
record_suffix all.flv;
record_path /var/rec;
record_unique on;
}
}
}
}
Start Recording:
Start rec1
nginx config for http:
access_log logs/rtmp_access.log;
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /var/www/;
}
location /control {
rtmp_control all;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
By the way
Plan B: I plan to store my recorded stream files to Amazon AWS s3. Anyone know how to do this with RTMP Nginx instead of using Wowza Amazon.

You can run inside shell script nginx conf. Check the permission first:
chown -R nobody:nogroup foldername
chmod -R 700 foldername
Shell script:
ffmpeg -v error -y -i "$1" -vcodec libx264 -acodec aac -f mp4 -movflags +faststart "/tmp/recordings/$2.mp4"
aws s3 cp "/tmp/recordings/$basname.mp4" "s3://bucketname/"
exec_record_done bash -c "/home/ubuntu/script/record.sh $path $basname";

You should check the permissions on the directory you're trying to record to (/var/rec in your case). Nginx, even though started up with sudo, spawns worker processes as user "nobody" by default. You can also try changing the user that the worker processes spawn as: https://serverfault.com/a/534512/102045

When i did this with my partner I would use
record_path /tmp/rec;
Then in the file I would set a crontab that permanently tries to send new files(videos) to his NextCloud FTP(In this case could be your amazon aws)

It seems like bhh1998 and akash jakhad answers are correct, although it seems that nowadays the nginx.conf file comes with nginx user as default, so instead of using nobody and nogroup, use only nginx instead. The command mentioned in previous answers would be like this:
chown -R nginx:nginx foldername
To be sure of the correct username, check your configuration file and see which user is being specified.

In addition to the user permission settings mentioned in other answers, I also had to change the path to end with a trailing slash i.e. /var/rec/ instead of /var/rec.

Related

Nginx php-fpm 404 error for one request and not another

I am hosting multiple php slim applications on the same server. They are located at the path apis/'tier'/'organization'/'appName'/'version' so for example apis/FreeTierSmall/master/exampleApp/v1.
I am using Nginx with php-fpm and am getting a very weird bug. I am trying to redirect any requests that start with apis/master/ to apis/FreeTierSmall/master. I've turned on the Nginx rewrite_log and can see that the files get redirected correctly. I get the correct result if I try apis/FreeTierSmall/master/example/v1. However, I get a 404 error if I try apis/master/example/v1 which redirects to the same php file. I know the redirect is working because I can see it in the logs. It seems that there is some problem with php-fpm. I am adding a header to the php-fpm execution so I know that it is calling the correct script. For some reason though a request of the same file is producing a 404 error in one case and not the other.
Is there some parameter that could cause the same file passed to fpm to work in one instance and not the other?
Here is my nginx configuration:
worker_processes 1;
pid /run/nginx.pid;
user nginx www-data;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main_timed '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time $pipe $upstream_cache_status'
'FPM - $document_root - $fastcgi_script_name > $request';
access_log /var/log/nginx/access.log main_timed;
# error_log /dev/stderr notice;
error_log /var/log/nginx/error.log debug;
# error_log above can be debug
rewrite_log on;
keepalive_timeout 65;
server {
listen [::]:80 default_server;
listen 80 default_server;
server_name _;
sendfile off;
root /var/www/html;
index index.php index.html;
error_page 404 /404.html;
# NOTE: Once you use last, that is the last redirect you can do. You must find the file after that.
# HEALTH CHECK
location /apis/FreeTierSmall/elb-status {
access_log off;
return 200 'A-OK!';
# because default content-type is application/octet-stream,
# browser will offer to "save the file"...
# the next line allows you to see it in the browser so you can test
add_header Content-Type text/plain;
}
# NORMAL API PATHS
location /apis/ {
#rewrite the old apis
rewrite ^/apis/master/([\w-]+)/([\w-]+)(.*)$ /apis/FreeTierSmall/master/$1/$2/api.php$3 last;
rewrite ^/apis/interfaceop/([\w-]+)/([\w-]+)(.*)$ /apis/FreeTierSmall/interfaceop/$1/$2/api.php$3 last;
# add api.php to the path of the file
rewrite ^/apis/([\w-]+)/([\w-]+)/([\w-]+)/([\w-]+)(.*)$ /apis/$1/$2/$3/$4/api.php$5 last;
}
# ANY OTHER FILES
location / {
# try to serve the file, the directory, or a 404 error
add_header X-debug-message-2 "A static file was served or 404 error $uri" always;
try_files $uri $uri/ /robots.txt; # Need to change back to =404
}
# ERRORS
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/lib/nginx/html;
}
# PHP FILES
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php {
add_header X-debug-message-5 "fastCGI -> .php $document_root$fastcgi_script_name" always;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_read_timeout 300;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
# SECURITY CONCERNS
# deny access to . files, for security
location ~ /\. {
log_not_found off;
deny all;
}
}
}
Turns out, the issue is that the URI of the request doesn't get changed with rewrite. Slim was providing the 404 error because the route didn't exist, and the route didn't exist because the URI never got changed by rewrite. So, rewrite doesn't actually change the request parameters it's just used to decide what file is going to be served. This is ok for most use cases but horrible for apis... a very odd error to debug. Good luck whoever runs into this in the future.
The solution: use proxy_pass.
location /apis/master/ {
# Reroutes /apis/master/* to /apis/FreeTierSmall/master/* correctly!
proxy_pass http://localhost:80/apis/FreeTierSmall/master/;
}

How to set up PHP 7 with NGINX

I installed PHP 7 Nightly and Nginx 1.9.7 (Mainline) on my development Debian Stable:
$ curl http://nginx.org/keys/nginx_signing.key | apt-key add -
$ echo -e 'deb http://nginx.org/packages/mainline/debian/ jessie nginx\ndeb-src http://nginx.org/packages/mainline/debian/ jessie nginx' > /etc/apt/sources.list.d/nginx.list
$ echo -e 'deb http://repos.zend.com/zend-server/early-access/php7/repos ubuntu/' > /etc/apt/sources.list.d/php.list
$ apt-get -y update && time apt-get -y dist-upgrade
$ apt-get -y --force-yes install --fix-missing nginx php7-nightly
$ service nginx restart
I have this configuration file in /etc/nginx/conf.d/php.conf (default.conf uncommented). It's the original default.conf, I just uncommented the PHP fastCGI lines:
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
I didn't found any tutorial on the net how to set up Nginx Mainline with PHP 7 yet. :(
Thank You!
After taking a quick look at the packages offered by zend (the packages you are installing), you'll have to write a script for your init system (systemd) to start and manage the php-fpm process.
The binaries are installed in /usr/local/php7/sbin/php-fpm. You'll also have to modify the configuration files in /usr/local/php7/etc. The main change will be to ensure that fpm has a pool listening on address 127.0.0.1 at port 9000.

nginx and php-fpm in Docker

I am in the process of Dockerising my webserver/php workflow.
But because I am on Windows, I need to use a virtual machine. I chose boot2docker which is a Tiny Core Linux running in Virtualbox and adapted for Docker.
I selected three containers:
nginx: the official nginx container;
jprjr/php-fpm: a php-fpm container;
mysql: for databases.
In boot2docker, /www/ contains my web projects and conf/, which has the following tree:
conf
│
├───fig
│ fig.yml
│
└───nginx
nginx.conf
servers-global.conf
servers.conf
Because docker-compose is not available for boot2docker, I must use fig to automate everything. Here is my fig.xml:
mysql:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=root
ports:
- 3306:3306
php:
image: jprjr/php-fpm
links:
- mysql:mysql
volumes:
- /www:/srv/http:ro
ports:
- 9000:9000
nginx:
image: nginx
links:
- php:php
volumes:
- /www:/www:ro
ports:
- 80:80
command: nginx -c /www/conf/nginx/nginx.conf
Here is my nginx.conf:
daemon off;
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile off;
keepalive_timeout 65;
index index.php index.html index.htm;
include /www/conf/nginx/servers.conf;
autoindex on;
}
And the servers.conf:
server {
server_name lab.dev;
root /www/lab/;
include /www/conf/nginx/servers-global.conf;
}
# Some other servers (vhosts)
And the servers-global.conf:
listen 80;
location ~* \.php$ {
fastcgi_index index.php;
fastcgi_pass php:9000;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /srv/http$fastcgi_script_name;
}
So the problem now (sorry for all that configuration, I believe it was needed to clearly explain the problem): If I access lab.dev, no problem (which shows that the host is created in Windows) but if I try to access lab.dev/test_autoload/, I have a File not found.. I know this comes from php-fpm not being able to access the files, and the nginx logs confirm this:
nginx_1 | 2015/05/28 14:56:02 [error] 5#5: *3 FastCGI sent in stderr:
"Primary script unknown" while reading response header from upstream,
client: 192.168.59.3, server: lab.dev, request: "GET /test_autoload/ HTTP/1.1",
upstream: "fastcgi://172.17.0.120:9000", host: "lab.dev", referrer: "http://lab.dev/"
I know that there is a index.php in lab/test_autoload/ in both containers, I have checked. In nginx, it is located in /www/lab/test_autoload/index.php and /srv/http/lab/test_autoload/index.php in php.
I believe the problem comes from root and/or fastcgi_param SCRIPT_FILENAME, but I do not know how to solve it.
I have tried many things, such as modifying the roots, using a rewrite rule, adding/removing some /s, etc, but nothing has made it change.
Again, sorry for all this config, but I think it was needed to describe the environment I am in.
I finally found the answer.
The variable $fastcgi_script_name did not take into account the root (logical, as it would have included www/ otherwise. This means that a global file can not work. An example :
# "generated" vhost
server {
server_name lab.dev;
root /www/lab/;
listen 80;
location ~* \.php$ {
fastcgi_index index.php;
fastcgi_pass php:9000;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /srv/http$fastcgi_script_name;
# I need to add /lab after /srv/http because it requests PHP to look at the root of the web files, not in the lab/ folder
# fastcgi_param SCRIPT_FILENAME /srv/http/lab$fastcgi_script_name;
}
}
This meant that I couldn't write the lab/ at only one place, I needed to write at two different places (root and fastcgi_param) so I decided to write myself a small PHP script that used a .json and turned it into the servers.conf file. If anyone wants to have a look at it, just ask, it will be a pleasure to share it.
There's a mistake here:
fastcgi_param SCRIPT_FILENAME /srv/http/$fastcgi_script_name;
The good line is:
fastcgi_param SCRIPT_FILENAME /srv/http$fastcgi_script_name;
This is not the same thing.
Your nginx.conf is fully empty, where is the daemon off;
the user nginx line, worker_processes etc.. nginx need some configuration file before running the http.
In the http conf, same thing, is missing the mime types, the default_type, configuration of logs sendfile at on for boot2docker.
Your problem is clearly not a problem with Docker, but with the nginx configuration. Have you test your application with running docker run before using fig ? Did it worked ?

nginx - Unable to open primary script

I got error message:
FastCGI sent in stderr: "Unable to open primary script: /home/messi/web/wordpress/index.php (No such file or directory)" while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: www.domain.com, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "www.domain.com
here are my configuration files:
/etc/php5/fpm/php.ini
cgi.fix_pathinfo=0
doc_root =
user_dir =
....
/etc/php5/fpm/php-fpm.conf
[global]
pid = /var/run/php5-fpm.pid
error_log = /var/log/php5-fpm.log
include=/etc/php5/fpm/pool.d/*.conf
/etc/php5/fpm/pool.d/www.conf
[www]
user = www-data
group = www-data
listen = /var/run/php5-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /
security.limit_extensions = .php .php3 .php4 .php5
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/fpm-php.www.log
php_admin_flag[log_errors] = on
/etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
server_tokens off;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/sites-enabled/*;
}
/etc/nginx/sites-enabled/wordpress
server {
listen 80;
server_name www.domain.com;
root /home/messi/web/wordpress;
error_log /var/log/nginx/err.wordpress.log;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ /\. {
deny all;
}
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}
Setup user permission:
#adduser www-data messi
#chown -R www-data:www-data /home/messi/web
#chmod -R 664 /home/messi/web/wordpress
How can I resolve this?
Thanks
SELinux will cause this error on CentOS/RHEL 7+ by default :(
To test if SELinux is the source of your woes, do
setenforce 0
... and see if everything works. If that fixed it, you can leave SELinux off (weak, you're better than that), or you can turn it back on with
setenforce 1
... and then properly fix the issue.
If you do
tail -f /var/log/audit/audit.log
... you'll see the SELinux issue. In my case, it was denying PHP-FPM access to web files. You can run the following directives to fix it:
setsebool -P httpd_can_network_connect_db 1
setsebool -P httpd_can_network_connect 1
This actually didn't fix it for me at first, but then restoring SELinux context did it
restorecon -R -v /var/www
Hope that helps.
This is likely a permissions problem.
Make sure that every parent directory has +x permissions for the user (the nginx user and/or php-fpm user).
You can check these permissions with: namei -om /path/to/file.
If you have symlinks, make sure they point to a valid path.
Make sure chroots have access to the right paths.
Make sure SELinux (e.g. Fedora / Centos) or AppArmor (e.g. Ubuntu) or any other MAC security systems are not interfering with the file access.
For SeLinux:
Check /var/log/audit/audit.log or /var/log/messages
For AppArmor:
Im not a Ubuntu user and as far as I understand the logging for AppArmor isnt always easy to figure out. You might check here for info: http://ubuntuforums.org/showthread.php?t=1733231
It was SELinux in my case as well. I read some documentation found here:
https://wiki.centos.org/HowTos/SELinux
https://linux.die.net/man/1/chcon
and ended up with the command:
chcon -R -v --type=httpd_sys_content_t html/
....this changed the context of the files to the httpd type which is what my web server (Nginx) was running as.
You can find what context your web server runs as using:
ps axZ | grep nginx
....which in my case gave me:
system_u:system_r:**httpd_t**:s0 6246 ? Ss 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
system_u:system_r:**httpd_t**:s0 6249 ? S 0:00 nginx: worker process
Seeing the context of the running service was httpd_t I changed the context of my web site's root folder to that (recursively)
The point of SELinux is to only allow services and processes to access files of the same type as them. Since the web server ran as httpd_t than it made sense to set the context of the files/folder in the site to the same.
I'm new at this by the way.... But this seemed to be the best approach to me. It kept SELinux enabled, didn't lessen the security of what it does, nad matched up context of the files with the process/service.
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; ->
fastcgi_param SCRIPT_FILENAME/home/messi/web/wordpress$fastcgi_script_name;

Nginx downloads php instead of running it

Iv'e setup an Nginx php server on a linux REHL machine.
When accessing html files all goes well, but trying to access php file, the file is downloaded instead of being executed.
This is my nginx.conf:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
...and this is the server block:
server {
listen 80;
server_name {mywebsitename};
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html/{mywebsitename}/;
}
location /ngx_status_2462 {
stub_status on;
access_log off;
allow all;
}
location ~ \.php$ {
# fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/{mywebsitename}$fastcgi_script_name;
include fastcgi_params;
}
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
It might be because of the mimetype you're sending:
default_type application/octet-stream;
See: http://mimeapplication.net/octet-stream
I just had this exact same problem. I was using Ubuntu 12.04 and Linux Mint 14 so different OS but likely to have the same issues.
A couple of issues may happening. Firstly, you need to have php5-fpm installed (FastCGI Process Manager). I was trying to run it with my standard version of PHP but it was not working - http://www.php.net/manual/en/install.fpm.php
I also had Apache installed, and even if it weren't running it must have had some conflict because once I uninstalled Apache I was able to execute the PHP files.
I would also look at this line
fastcgi_pass 127.0.0.1:9000;
And consider changing it to
fastcgi_pass unix:/var/run/php5-fpm.sock;
Here is a detailed guide to installation of Nginx and PHP5-FPM for RHEL (and other OS's)
http://www.if-not-true-then-false.com/2011/install-nginx-php-fpm-on-fedora-centos-red-hat-rhel/
You need to change the user to nginx instead of apache in this file a/etc/php-fpm.d/www.conf
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
; RPM: apache Choosed to be able to access some dir as httpd
;user = apache
user = nginx
; RPM: Keep a group allowed to write in log dir.
;group = apache
group = nginx
and of course restart service php-fpm restart and service nginx restart
Comment out default_type application/octet-stream;

Categories