php-fpm and nginx session problems - session

I've been having this problem for the past week or so. I've been working on a PHP project that relies HEAVILY on Sessions. For some reason we've been having troubles with the sessions saving the past few days. Any idea why?
Here's the error:
Warning: Unknown: open(/tmp/sess_mmd0ru5pl2h2h9bummcu1uu620, O_RDWR) failed: Permission denied (13) in Unknown on line 0 Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/tmp) in Unknown on line 0
Warning: session_start(): open(/tmp/sess_mmd0ru5pl2h2h9bummcu1uu620, O_RDWR) failed: Permission denied (13)
nginx version:
nginx version: nginx/1.0.11
PHP-FPM config:
;;;;;;;;;;;;;;;;;;;;;
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;
; All relative paths in this configuration file are relative to PHP's install
; prefix.
; Include one or more files. If glob(3) exists, it is used to include a bunch of
; files from a glob(3) pattern. This directive can be used everywhere in the
; file.
include=/etc/php-fpm.d/*.conf
;;;;;;;;;;;;;;;;;;
; Global Options ;
;;;;;;;;;;;;;;;;;;
[global]
; Pid file
; Default Value: none
pid = /var/run/php-fpm/php-fpm.pid
; Error log file
; Default Value: /var/log/php-fpm.log
error_log = /var/log/php-fpm/error.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
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
; See /etc/php-fpm.d/*.conf
nginx.conf:
#######################################################################
#
# This is the main Nginx configuration file.
#
# More information about the configuration options is available on
# * the English wiki - http://wiki.nginx.org/Main
# * the Russian documentation - http://sysoev.ru/nginx/
#
#######################################################################
#----------------------------------------------------------------------
# Main Module - directives that cover basic functionality
#
# http://wiki.nginx.org/NginxHttpMainModule
#
#----------------------------------------------------------------------
user nginx nginx;
worker_processes 5;
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
#----------------------------------------------------------------------
# Events Module
#
# http://wiki.nginx.org/NginxHttpEventsModule
#
#----------------------------------------------------------------------
events {
worker_connections 4096;
}
#----------------------------------------------------------------------
# HTTP Core Module
#
# http://wiki.nginx.org/NginxHttpCoreModule
#
#----------------------------------------------------------------------
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;
index index.php index.html index.htm;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# Load config files from the /etc/nginx/conf.d directory
# The default server is in conf.d/default.conf
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name stats.smilingdevil.com;
error_page 404 /404.php;
root /var/www;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
set $page_to_view "/index.php";
try_files $uri $uri/ #rewrites;
root /var/www/;
index index.php;
}
location #rewrites {
if ($uri ~* ^/([a-z0-9]+)$) {
set $page_to_view "/$1.php";
rewrite ^/([a-z]+)$ /$1.php last;
}
}
location ~ \.php$ {
include /etc/nginx/fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
}
}
}

Just change the ownership of /var/lib/php/session/ to nginx from apache instead of giving a world read.
sudo chown -R nginx:nginx /var/lib/php/session/

I found that my php.ini was attempting to save sessions to /var/lib/php/session rather than /tmp
So check your ini file and see where they're being saved to (or set it to somewhere else); then make sure that directory is writeable by the appropriate processes

TL;DR: Add nginx user to apache group
RHEL has decided that /var/lib/php/session is owned by the php package. That package has decided that it will always recreate the /var/lib/php/session directory when installed and will always return the directory to being owned by root with group set to apache with full permissions for each and no permissions for anything else. Therefore, while many suggested solutions here suggest changing the permissions of /var/lib/php/session, that will cause problems in the future.
https://bugzilla.redhat.com/show_bug.cgi?id=1146552
The RHEL suggested way of fixing this issue is to create your own session directory wherever you'd like to store it and set the permissions as necessary. Future php updates won't affect that new location and everything should stay working.
An alternative that has worked quite well for me is to simply add nginx to the apache group.

Chris Rutledge is right,
php some times is saving sesions on /var/lib/php/session/ directory
check your php.ini file or
create the directory with 777 rights
mkdir /var/lib/php/session
chmod -R 777 /var/lib/php/session

this error occured due to the user which run php process may not have permission to write on /tmp directory
to make it writeable by all user use this commend
chmod 777 /tmp
another reason which causes the same issue is read only file system
if /dev/sda1 is mounted on /tmp and due to heavy write your file system may become read only...
to make it rewritable again use this command
mount -t ext3 -o rw,remount /dev/sda1 /tmp

Seems I found something interesting on the Linux. In the chroot php-cgi make same errors when some PHP software try to read/write session. I thought this could be permission issue, but after set 777 and set owner of the webserver to the "/tmp" and set it in the After many hours it found that "urandom" device in the "/dev" needed to work it. Just make sure that it found or copy/make it and change permissions temporary (just for check and then change to safely):
chmod 777 /dev/urandom
Strange to me that it wasn't required in some PHP5.x version but in some PHP7.x need to be there.

I just went through an upgrade of PHP on CentOS. I had to change /etc/php-fpm.d/www.conf and update the php_value[session.save_path] variable and set it to /tmp
php_value[session.save_path] = /tmp
This works fine.
I don't think this will be a security hazard.

You might get this error when you'r using NGINX and the server gives permission to apache instead of nginx.
My fix is:
chown -R nginx:nginx /var/lib/php/
With chown you are changhing the owner of that specific folder and -R means its recursive.

Related

Changing the nginx fcgiwrap user

I'm trying to use fcgi with a shell script and make it callable via nginx.
No matter what I do though, the script is ran with www-data user. I need it to run as nginx user that nginx is using.
nginx 1.15.1
Installed fcgiwrap:
apt get install fcgiwrap
Config is following:
nginx.conf:
user nginx nginx;
worker_processes 1;
worker_rlimit_nofile 100000;
http {
location ~ (\.sh)$ {
gzip off;
root /home/nginx/www;
autoindex on;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include /usr/local/nginx/conf/fastcgi_params;
fastcgi_param DOCUMENT_ROOT /home/nginx/www;
fastcgi_param SCRIPT_FILENAME /home/nginx/www$fastcgi_script_name;
}
}
The problem I need to fix is access to some of the files other scripts have created that run under nginx user.
I also tried editing /etc/init.d/fcgiwrap to change
FCGI_USER="nginx"
FCGI_GROUP="nginx"
# Socket owner/group (will default to FCGI_USER/FCGI_GROUP if not defined)
FCGI_SOCKET_OWNER="nginx"
FCGI_SOCKET_GROUP="nginx"
But it had no effect. The script:
#!/bin/bash -e
echo 'Content-Type: text/plain'
echo ''
echo $(whoami)
echo $(groups)
The output is:
www-data
www-data
Define the path to the fcgiwrap.service file:
systemctl status fcgiwrap.service
Change the User and the Group in fcgiwrap.service file:
nano /lib/systemd/system/fcgiwrap.service

Laradock Nginx throws 413 error entity too large even if size = 20M and my file is 1.5MB

I am deploying a Laravel app by using Laradock.
When testing the upload part with two different 1.5MB dummy files (.docx and .pdf), I get the following error:
I already have checked the Nginx's nginx.conf file and it does have that setting to 20MB:
...
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 15;
types_hash_max_size 2048;
client_max_body_size 20M;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
error_log /dev/stderr;
gzip on;
gzip_disable "msie6";
...
I have reloaded the configurations:
$ sudo docker exec myapp_nginx_99 nginx -t
$ sudo docker exec myapp_nginx_99 nginx -s reload
But the error is still thrown:
413 Request Entity Too Large
Inside a php.ini file I have the following:
;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;
; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads = On
; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
; http://php.net/upload-tmp-dir
;upload_tmp_dir =
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 2M
; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20
I can see the maximum is 2MB, but I have tried with a 1.1MB PDF file and I still get the error.
Also, I have found out a laravel.ini right at the php-fpm directory and this is the original configuration:
date.timezone=UTC
display_errors=Off
log_errors=On
; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 256M
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 20M
; Sets max size of post data allowed.
; http://php.net/post-max-size
post_max_size = 20M
max_execution_time=600
default_socket_timeout=3600
request_terminate_timeout=600
However, if I try with a 836KB file, the upload is successful. Looks like the Max file upload is 1MB, but I can't find it anywhere ...
Given that I'm already using other applications, I am using a Nginx-proxy from Evert Ramos to resolve for each domain. Looks like the problem lies here.
If I execute $ nginx -T on this proxy container, I don't see the client_max_body_size
What else am I missing to fix this?

Include docker compose startup command in Dockerfile or docker run [duplicate]

I am trying to start an NGINX server within a docker container configured through docker-compose. The catch is, however, that I would like to substitute an environment variable inside of the http section, specifically within the "upstream" block.
It would be awesome to have this working, because I have several other containers that are all configured through environment variables, and I have about 5 environments that need to be running at any given time. I have tried using "envsubst" (as suggested by the official NGINX docs), perl_set, and set_by_lua, however none of them appear to be working.
Below is the NGINX config, as it is after my most recent trial
user nginx;
worker_processes 1;
env NGINXPROXY;
load_module modules/ngx_http_perl_module.so;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
perl_set $nginxproxy 'sub { return $ENV{"NGINXPROXY"}; }';
upstream api-upstream {
server ${nginxproxy};
}
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;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
Below is the NGINX dockerfile
# build stage
FROM node:latest
WORKDIR /app
COPY ./ /app
RUN npm install
RUN npm run build
# production stage
FROM nginx:1.17.0-perl
COPY --from=0 /app/dist /usr/share/nginx/html
RUN apt-get update && apt-get install -y gettext-base
RUN rm /etc/nginx/conf.d/default.conf
RUN rm /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d
COPY nginx.conf /etc/nginx
RUN mkdir /certs
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
Below is the section of the docker-compose.yml for the NGINX server (with names and IPs changed). The envsubst command is intentionally commented out at this point in my troubleshooting.
front-end:
environment:
- NGINXPROXY=172.31.67.100:9300
build: http://gitaccount:password#gitserver.com/group/front-end.git#develop
container_name: qa_front_end
image: qa-front-end
restart: always
networks:
qa_network:
ipv4_address: 172.28.0.215
ports:
- "9080:80"
# command: /bin/bash -c "envsubst '$$NGINXPROXY' < /etc/nginx/nginx.conf > /etc/nginx/nginx.conf && nginx -g 'daemon off;'"
What appears to be happening is when I reference the $nginxproxy variable in the upstream block (right after "server"), I get output that makes it look like it's referencing the string literal "$nginxproxy" rather than substituting the value of the variable.
qa3_front_end | 2019/06/18 12:35:36 [emerg] 1#1: host not found in upstream "${nginx_upstream}" in /etc/nginx/nginx.conf:19
qa3_front_end | nginx: [emerg] host not found in upstream "${nginx_upstream}" in /etc/nginx/nginx.conf:19
qa3_front_end exited with code 1
When I attempt to use envsubst, I get an error that makes it sound like the command messed with the format of the nginx.conf file
qa3_front_end | 2019/06/18 12:49:02 [emerg] 1#1: no "events" section in configuration
qa3_front_end | nginx: [emerg] no "events" section in configuration
qa3_front_end exited with code 1
I'm pretty stuck, so thanks in advance for your help.
Since nginx 1.19 you can now use environment variables in your configuration with docker-compose. I used the following setup:
# file: docker/nginx/templates/default.conf.conf
upstream api-upstream {
server ${API_HOST};
}
# file: docker-compose.yml
services:
nginx:
image: nginx:1.19-alpine
volumes:
- "./docker/nginx/templates:/etc/nginx/templates/"
environment:
NGINX_ENVSUBST_TEMPLATE_SUFFIX: ".conf"
API_HOST: api.example.com
I'm going off script a little from the example in the documentation. Note the extra .conf extension on the template file - this is not a typo. In the docs for the nginx image it is suggested to name the file, for example, default.conf.template. Upon startup, a script will take that file, substitute the environment variables, and then output the file to /etc/nginx/conf.d/ with the original file name, dropping the .template suffix.
By default that suffix is .template, but this breaks syntax highlighting unless you configure your editor. Instead, I specified .conf as the template suffix. If you only name your file default.conf the result will be a file named /etc/nginx/conf.d/default and your site won't be served as expected.
You can avoid some of the hassles with Compose interpreting environment variables by defining your own entrypoint. See this simple example:
entrypoint.sh (make sure this file is executable)
#!/bin/sh
export NGINXPROXY
envsubst '${NGINXPROXY}' < /config.template > /etc/nginx/nginx.conf
exec "$#"
docker-compose.yml
version: "3.7"
services:
front-end:
image: nginx
environment:
- NGINXPROXY=172.31.67.100:9300
ports:
- 80:80
volumes:
- ./config:/config.template
- ./entrypoint.sh:/entrypoint.sh
entrypoint: ["/entrypoint.sh"]
command: ["nginx", "-g", "daemon off;"]
My config file has the same content as your nginx.conf, aside from the fact that I had to comment the lines using the Perl module.
Note that I had to mount my config file to another location before I could envsubst it. I encountered some strange behaviour in the form that the file ends up empty after the substitution, which can be avoided by this approach. It shouldn't be a problem in your specific case, because you already embed it in your image on build time.
EDIT
For completeness, to change your setup as little as possible, you just have to make sure that you export your environment variable. Adapt your command like this:
command: ["/bin/bash", "-c", "export NGINXPROXY && envsubst '$$NGINXPROXY' < /etc/nginx/nginx.conf > /etc/nginx/nginx.conf && nginx -g 'daemon off;'"]
...and you should be good to go. I would always recommend the "cleaner" way with defining your own entrypoint, though.
So after some wrestling with this issue, I managed to get it working similarly to the answer provided by bellackn. I am going to post my exact solution here, in case anybody else needs to reference a complete solution.
Step1: Write your nginx.conf or default.conf how you would normally write it. Save the file as "nginx.conf.template", or "default.conf.template" depending on which you are trying to substitute variables into.
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
upstream api-upstream {
server 192.168.25.254;
}
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;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
Step2: Substitute a variable in the format ${VARNAME} for whatever value(s) you want to replace with an environment variable:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
upstream api-upstream {
server ${SERVER_NAME};
}
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;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
Step 3: In your docker-file, copy your nginx configuration files (your nginx.conf.template or default.conf.template) into your container at the appropriate location:
# build stage
FROM node:latest
WORKDIR /app
COPY ./ /app
RUN npm install
RUN npm run build
# production stage
FROM nginx:1.17.0-perl
COPY --from=0 /app/dist /usr/share/nginx/html
RUN apt-get update && apt-get install -y gettext-base
RUN rm /etc/nginx/conf.d/default.conf
RUN rm /etc/nginx/nginx.conf
#-----------------------------------#
|COPY default.conf /etc/nginx/conf.d|
|COPY nginx.conf.template /etc/nginx|
#-----------------------------------#
RUN mkdir /certs
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
Step 4: Set your environment variable in your docker-compos.yml file using the "environment" section label. Make sure your environment variable name matches whatever variable name you chose within your nginx config file. Use the "envsubt" command within your docker container to substitute your variable values in for your variables within your nginx.conf.template, and write the output to a file named nginx.conf in the correct location. This can be done within the docker-compose.yml file by using the "command" section label:
version: '2.0'
services:
front-end:
environment:
- SERVER_NAME=172.31.67.100:9100
build: http://git-account:git-password#git-server.com/project-group/repository-name.git#branch-ame
container_name: qa_front_end
image: qa-front-end-vue
restart: always
networks:
qa_network:
ipv4_address: 172.28.0.215
ports:
- "9080:80"
command: >
/bin/sh -c
"envsubst '
$${SERVER_NAME}
'< /etc/nginx/nginx.conf.template
> /etc/nginx/nginx.conf
&& nginx -g 'daemon off;'"
Step 5: Run your stack with docker-compose up (with whatever additional switches you need) and your nginx server should now start with whatever value you supplied in the "environment" section of your docker-compose.yml
As mentioned in the solution above, you can also define your own entry point, however this solution has also proven to work pretty well, and keeps everything contained into a single configuration file, giving me the ability to run a stack of services directly from git with nothing but a docker-compose.yml file.
A big thank you to everybody who took the time to ready through this, and bellackn for taking the time to help me solve the issue.
Like already explained in Jody's answer, nowadays the official Nginx Docker image supports parsing templates. This uses envsubst and its handling ensures not to mess with Nginx variables such as $host and all. Nice. However, envsubst does not support default values like a regular shell and Docker Compose do when using ${MY_VAR:-My Default}. So, this built-in templating would always need a full setup of all variables, even when using the defaults.
To define defaults in the image itself, one can use a custom entry point to first set the defaults and then simply delegate to the original entrypoint. Like a docker-defaults.sh:
#!/usr/bin/env sh
set -eu
# As of version 1.19, the official Nginx Docker image supports templates with
# variable substitution. But that uses `envsubst`, which does not allow for
# defaults for missing variables. Here, first use the regular command shell
# to set the defaults:
export PROXY_API_DEST=${PROXY_API_DEST:-http://host.docker.internal:8000/api/}
# Due to `set -u` this would fail if not defined and no default was set above
echo "Will proxy requests for /api/* to ${PROXY_API_DEST}*"
# Finally, let the original Nginx entry point do its work, passing whatever is
# set for CMD. Use `exec` to replace the current process, to trap any signals
# (like Ctrl+C) that Docker may send it:
exec /docker-entrypoint.sh "$#"
Along with, say, some docker-nginx-default.conf:
# After variable substitution, this will replace /etc/nginx/conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api/ {
# Proxy API calls to another destination; the default for the variable is
# set in docker-defaults.sh
proxy_pass $PROXY_API_DEST;
}
}
In the Dockerfile copy the template into /etc/nginx/templates/default.conf.template and set the custom entry point:
FROM nginx:stable-alpine
...
# Each time Nginx is started it will perform variable substition in all template
# files found in `/etc/nginx/templates/*.template`, and copy the results (without
# the `.template` suffix) into `/etc/nginx/conf.d/`. Below, this will replace the
# original `/etc/nginx/conf.d/default.conf`; see https://hub.docker.com/_/nginx
COPY docker-nginx-default.conf /etc/nginx/templates/default.conf.template
COPY docker-defaults.sh /
# Just in case the file mode was not properly set in Git
RUN chmod +x /docker-defaults.sh
# This will delegate to the original Nginx `docker-entrypoint.sh`
ENTRYPOINT ["/docker-defaults.sh"]
# The default parameters to ENTRYPOINT (unless overruled on the command line)
CMD ["nginx", "-g", "daemon off;"]
Now using, e.g., docker run --env PROXY_API_DEST=https://example.com/api/ ... will set a value, which in this example will default to http://host.docker.internal:8000/api/ if not set (which is actually http://localhost:8000/api/ on the local machine).
According to official documentation https://hub.docker.com/_/nginx
section "Using environment variables in nginx configuration (new in 1.19)"
you can use environment variables.
But it's does not work due to bug inside docker container script:
https://github.com/nginxinc/docker-nginx/blob/master/entrypoint/20-envsubst-on-templates.sh#L25
running this script always fails with error:
/docker-entrypoint.d/20-envsubst-on-templates.sh: line 25: 3: Bad file descriptor
I created issue https://github.com/nginxinc/docker-nginx/issues/645
and pull request https://github.com/nginxinc/docker-nginx/pull/646
As workaround for now I copied this script and change it locally/
You could switch to a more advanced nginx docker image. For example nginx4docker, it implements a bunch of basic env variables that can be set through docker and you don't have to fiddle around with nginx basic templating and all it's drawbacks.
nginx4docker could also be extended with your custom env variables. only mount a file that lists all your env variables to docker ... --mount $(pwd)/CUSTOM_ENV:/ENV ...
My solution is coping entrypoint sh file into /docker-entrypoint.d directory of nginx container. As mentioned above, you need to copy .template file. But you dont need to create two seperate files.
Copy the file config file with temporary name in Dockerfile. But it's important to not use ENTRYPOINT command in Dockerfile
FROM nginx
...
COPY ./default.conf /etc/nginx/conf.d/default.conf.temp
create an sh file named 05-docker-entrypoint.sh in your project directory (host) and put the following code into the sh file as mentioned above
#!/usr/bin/env sh
set -eu
envsubst '${MY_VARIABLE}' < /etc/nginx/conf.d/default.conf.temp > /etc/nginx/conf.d/default.conf
exec "$#"
Mount 05-docker-entrypoint.sh using docker-compose.yml file to /docker-entrypoint.d directory of nginx container or copy it using Dockerfile. This two options are looking like this :
Option 1. (i prefer this) Mounting file using compose file :
web:
expose:
- 80
environment:
- MY_VARIABLE=blabala
volumes:
- ./05-docker-entrypoint.sh:/docker-entrypoint.d/05-docker-entrypoint.sh
....
Option 2.
Use Dockerfile to copy files into container
Final Dockerfile with Option2 looks like :
FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf.temp
COPY ./05-docker-entrypoint.sh /docker-entrypoint.d/05-docker-entrypoint.sh

bash function to perform a sanity check on nginx files

I am trying to write a function which performs a sanity check of files before I move them into /etc/nginx/site-available.
There are located in my home directory and are modified regularly.
The only modification done in those files is to add a server_name.
They look like:
server {
listen 80;
server_name domain.com;
server_name www.domain.com;
server_name mynsite1.com;
server_name www.mysite1.com;
server_name mysite2.com;
server_name www.mysite2.com;
server_name mysite3.com;
server_name www.mysite3.com;
server_name mysite4.com;
server_name www.mysite4.com;
access_log /var/log/nginx/domain.com-access.log main;
error_log /var/log/nginx/domain.com-error.log warn;
root /var/www/docroot;
index index.php index.html index.htm;
location / {
try_files $uri /app_dev.php;
}
# 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;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$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;
}
}
Here is the function I have right now:
verify_nginx()
{
if [ ! -s "$file1" ]; then
echo "-> File \"$file1\" is empty or do not exist" | ts
exit 1
elif [ ! -s "$file2" ]; then
echo "-> File \"$file2\" is empty or do not exist" | ts
exit 1
fi
}
I would also like to add nginx -t -c /homedir/file1 in the function but I get the following error:
nginx: [emerg] "server" directive is not allowed here in /homedir/file:1
nginx: configuration file /homedir/file test failed
Indeed nginx -c is expecting nginx.conf which does not include my files in my homedir.
I could put my files in /etc/nginx/site-available which is included in nginx.conf but I want to perform the sanity check before I move the files to the correct location.
My questions:
Is there a way to test the configuration file located somewhere else than in /etc/nginx/site-available using nginx?
What kind of sanity checks should be performed on nginx files?
The files you're trying to sanity-check are not nginx config files, therefore (understandably) nginx -t says they're invalid. The -c flag expects "an alternative configuration file", not a single server block. server blocks live inside an http block.
If you want to run nginx -t you need to pass it a proper config file, which would include the files you're attempting to modify. You could, as Etan Reisner suggests, simply write a dummy nginx.conf that includes your files, something like this might work (I'm not on a machine with nginx installed atm, so you may have to add a few more stub directives):
http {
include path/to/files/*;
}
Then you can run nginx -t -c dummy_nginx.conf.
This has a problem though; you could still have any number of errors that are only revealed when your real config file is loaded.
Instead, you can verify your real config file with your changes before they're loaded by simply calling nginx -t before you reload; you could wrap this in a bash function if you wanted:
safe_reload() {
nginx -t &&
service nginx reload # only runs if nginx -t succeeds
}
You should also have some sort of backup or restore mechanism. This could be as simple as copying your old config files to parallel *.bak files, but much more pleasant is using a VCS like Mercurial or Git. You check in each iteration of your configs that succeed, and then you can easily revert to the previous known good configuration if anything goes wrong.

proFTPD permission denied

So, I'm running proFTPD (should be the newest one from www.webmin.com)(with webmin1.760),on Ubuntu 14.04.3 LTS Server (32-bit).
With the admin username and password,
I can use FileZilla to access the FTP server from another home PC, but I'm not permitted to upload/modify/create files.
Below is the error showed on the FileZilla, on delete :
Status: Deleting "/var/www/html/index.html"
Command: DELE index.html
Response: 550 index.html: Permission denied
, on create :
Status: Retrieving directory listing of "/var/www/html"...
Status: Directory listing of "/var/www/html" successful
Response: 421 No transfer timeout (600 seconds): closing control connection
Error: Connection closed by server
I've tried googling, but it doesn't seem to be a common error,
and I don't either find any permission option for admin in the "etc/proftpd/proftpd.conf"
This is my proftpd.conf:
#
# /etc/proftpd/proftpd.conf -- This is a basic ProFTPD configuration file.
# To really apply changes, reload proftpd after modifications, if
# it runs in daemon mode. It is not required in inetd/xinetd mode.
#
# Includes DSO modules
Include /etc/proftpd/modules.conf
# Set off to disable IPv6 support which is annoying on IPv4 only boxes.
UseIPv6 on
# If set on you can experience a longer connection delay in many cases.
IdentLookups off
ServerName Debian
ServerType standalone
DeferWelcome off
MultilineRFC2228 on
DefaultServer on
ShowSymlinks on
TimeoutNoTransfer 600
TimeoutStalled 600
TimeoutIdle 1200
DisplayLogin welcome.msg
DisplayChdir .message true
ListOptions "-l"
DenyFilter \*.*/
# Use this to jail all users in their homes
# DefaultRoot ~
# Users require a valid shell listed in /etc/shells to login.
# Use this directive to release that constrain.
# RequireValidShell off
# Port 21 is the standard FTP port.
Port 21
# In some cases you have to specify passive ports range to by-pass
# firewall limitations. Ephemeral ports can be used for that, but
# feel free to use a more narrow range.
# PassivePorts 49152 65534
# If your host was NATted, this option is useful in order to
# allow passive tranfers to work. You have to use your public
# address and opening the passive ports used on your firewall as well.
# MasqueradeAddress 1.2.3.4
# This is useful for masquerading address with dynamic IPs:
# refresh any configured MasqueradeAddress directives every 8 hours
<IfModule mod_dynmasq.c>
# DynMasqRefresh 28800
</IfModule>
# To prevent DoS attacks, set the maximum number of child processes
# to 30. If you need to allow more than 30 concurrent connections
# at once, simply increase this value. Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances 30
# Set the user and group that the server normally runs at.
User proftpd
Group nogroup
# Umask 022 is a good standard umask to prevent new files and dirs
# (second parm) from being group and world writable.
Umask 007 007
# Normally, we want files to be overwriteable.
AllowOverwrite on
# Uncomment this if you are using NIS or LDAP via NSS to retrieve passwords:
# PersistentPasswd off
# This is required to use both PAM-based authentication and local passwords
# AuthOrder mod_auth_pam.c* mod_auth_unix.c
# Be warned: use of this directive impacts CPU average load!
# Uncomment this if you like to see progress and transfer rate with ftpwho
# in downloads. That is not needed for uploads rates.
#
# UseSendFile off
TransferLog /var/log/proftpd/xferlog
SystemLog /var/log/proftpd/proftpd.log
# Logging onto /var/log/lastlog is enabled but set to off by default
#UseLastlog on
# In order to keep log file dates consistent after chroot, use timezone info
# from /etc/localtime. If this is not set, and proftpd is configured to
# chroot (e.g. DefaultRoot or <Anonymous>), it will use the non-daylight
# savings timezone regardless of whether DST is in effect.
#SetEnv TZ :/etc/localtime
<IfModule mod_quotatab.c>
QuotaEngine off
</IfModule>
<IfModule mod_ratio.c>
Ratios off
</IfModule>
# Delay engine reduces impact of the so-called Timing Attack described in
# http://www.securityfocus.com/bid/11430/discuss
# It is on by default.
<IfModule mod_delay.c>
DelayEngine on
</IfModule>
<IfModule mod_ctrls.c>
ControlsEngine off
ControlsMaxClients 2
ControlsLog /var/log/proftpd/controls.log
ControlsInterval 5
ControlsSocket /var/run/proftpd/proftpd.sock
</IfModule>
<IfModule mod_ctrls_admin.c>
AdminControlsEngine off
</IfModule>
#
# Alternative authentication frameworks
#
#Include /etc/proftpd/ldap.conf
#Include /etc/proftpd/sql.conf
#
# This is used for FTPS connections
#
#Include /etc/proftpd/tls.conf
#
# Useful to keep VirtualHost/VirtualRoot directives separated
#
#Include /etc/proftpd/virtuals.conf
# A basic anonymous configuration, no upload directories.
# <Anonymous ~ftp>
# User ftp
# Group nogroup
# # We want clients to be able to login with "anonymous" as well as "ftp"
# UserAlias anonymous ftp
# # Cosmetic changes, all files belongs to ftp user
# DirFakeUser on ftp
# DirFakeGroup on ftp
#
# RequireValidShell off
#
# # Limit the maximum number of anonymous logins
# MaxClients 10
#
# # We want 'welcome.msg' displayed at login, and '.message' displayed
# # in each newly chdired directory.
# DisplayLogin welcome.msg
# DisplayChdir .message
#
# # Limit WRITE everywhere in the anonymous chroot
# <Directory *>
# <Limit WRITE>
# DenyAll
# </Limit>
# </Directory>
#
# # Uncomment this if you're brave.
# # <Directory incoming>
# # # Umask 022 is a good standard umask to prevent new files and dirs
# # # (second parm) from being group and world writable.
# # Umask 022 022
# # <Limit READ WRITE>
# # DenyAll
# # </Limit>
# # <Limit STOR>
# # AllowAll
# # </Limit>
# # </Directory>
#
# </Anonymous>
# Include other custom configuration files
Include /etc/proftpd/conf.d/
AccessGrantMsg "Successful login"
<Global>
</Global>
It's very confusing to handle on my own because I can't even find any clue except the error shown on FileZilla.
FTP is important for me to config my server, it would be a big help if you can give any clue, thank you.
Also, I may as well use another FTP server, any suggestion?
sudo chown -R user:root /var/www/
then
chown -R user:www-data /var/www
change user
And I finally come up with a solution - changing the permission of my folder
Which can be found here

Resources