I have been trying to set up a local docker container that would host NGINX server. To start with, here is my Dockerfile:
# Set nginx base image
FROM nginx
# File Author / Maintainer
MAINTAINER myuser "myemail#mydomain.com"
# Copy custom configuration file from the current directory
COPY nginx.conf /etc/nginx/nginx.conf
I did build this file using the docker build command and when I listed the images, I get to see this image in the list.
Now, I tried to run this newly created image which resulted in an error:
my-MacBook-Pro:nginx-docker me$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myrepo nginx-latest 0d73419e8da9 12 minutes ago 182.8 MB
hello-world latest c54a2cc56cbb 13 days ago 1.848 kB
nginx latest 0d409d33b27e 6 weeks ago 182.8 MB
my-MacBook-Pro:nginx-docker me$ docker run -it myrepo:nginx-latest
2016/07/15 07:07:35 [emerg] 1#1: open() "/etc/nginx/logs/access.log" failed (2: No such file or directory)
nginx: [emerg] open() "/etc/nginx/logs/access.log" failed (2: No such file or directory)
The path to the log file is configured in my nginx.conf which is as below:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
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 8080;
server_name localhost;
root /Users/me/Projects/Sandbox/my-app;
#charset koi8-r;
access_log logs/host.access.log main;
#
# Wide-open CORS config for nginx
#
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
# /api will server your proxied API that is running on same machine different port
# or another machine. So you can protect your API endpoint not get hit by public directly
location /api {
proxy_pass http://localhost:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin *;
proxy_set_header Access-Control-Allow-Origin $http_origin;
}
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;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
include servers/*;
}
When I now tried to run this NGINX image, I get the following error:
2016/07/15 07:07:35 [emerg] 1#1: open() "/etc/nginx/logs/access.log" failed (2: No such file or directory)
nginx: [emerg] open() "/etc/nginx/logs/access.log" failed (2: No such file or directory)
What should I do to fix this? Also what and where should that path be? I suppose it is on the underlying OS path that is exposed by Docker?
The base image in your Dockerfile is nginx (nginx:latest to be exact). It has a pre-configured nginx configuration that comes from Debian Nginx package. You may inspect the container yourself: docker run -it --rm nginx /bin/bash and look at the files and directories to learn few facts about it:
it provides nginx user
it provides /var/log/nginx directory, but root owns it
it provides access.log and error.log in that directory writable by anyone
(Dockerfile for the base Nginx image is here)
Your configuration:
runs Nginx as nginx (it's the default)
tries to write log files into /etc/nginx/logs
Apparently, this directory does not exist because no one has created it. If it'd existed it should be writable by nginx user.
Related
I am trying to get deploy a FlaskApp with Gunicorn/WSGI/Nginx. I've been trying to get this to work for awhile and can't find any thing other than the Digital Ocean guides that I've followed to a T. Below are my files I've got in their current states. I have tried several different tweaks to mywebapp.service file because I am pretty sure this is where my problem lay. I can run /bin/gunicorn --workers 3 --bind 0.0.0.0:8000 -u nginx -g nginx wsgi and gunicorn will work. I'm pretty sure its some small possibly fundamental thing that I am missing but I lost. My nginx user owns the app directory.
[root#localhost mywebapp]# systemctl status mywebapp
● mywebapp.service - Gunicorn instance to serve mywebapp
Loaded: loaded (/etc/systemd/system/mywebapp.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2018-06-30 13:00:35 EDT; 25min ago
Main PID: 29706 (code=exited, status=203/EXEC)
Jun 30 13:00:35 localhost.localdomain systemd[1]: Started Gunicorn instance to serve mywebapp.
Jun 30 13:00:35 localhost.localdomain systemd[1]: Starting Gunicorn instance to serve mywebapp...
Jun 30 13:00:35 localhost.localdomain systemd[1]: mywebapp.service: main process exited, code=exited, status=203/EXEC
Jun 30 13:00:35 localhost.localdomain systemd[1]: Unit mywebapp.service entered failed state.
Jun 30 13:00:35 localhost.localdomain systemd[1]: mywebapp.service failed.
/home/nginx/mywebapp
mywebappenv mywebapp.py __pycache__ wsgi.py
/etc/systemd/system/mywebapp.service
[Unit]
Description=Gunicorn instance to serve mywebapp
After=network.target
[Service]
User=nginx
Group=nginx
WorkingDirectory=/home/nginx/mywebapp
Environment="PATH=/home/nginx/mywebapp/mywebappenv/bin"
ExecStart=/bin/gunicorn --workers 3 --bind unix:/home/nginx/mywebapp/mywebapp.sock -u nginx -g nginx wsgi
Restart=always
[Install]
WantedBy=multi-user.target
/home/nginx/mywebapp/mywebapp.py
from flask import Flask
application = Flask(__name__)
#application.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
application.run(host='0.0.0.0')
/home/nginx/mywebapp/wsgi.py
from mywebapp import application
if __name__ == "__main__":
application.run()
[root#localhost mywebapp]# cat /etc/nginx/nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name 10.8.0.173;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/home/nginx/mywebapp/mywebapp.sock;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
Based on the answers provided here's how I solved it.
Navigate to your virtualenv as below
cd /my-env/bin/
chown the current use (user specified on the gunicorn.service file)
Below example has user as 'sammy' in file /etc/systemd/system/gunicorn.service
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
On the bin folder, run command ls to confirm you have file 'gunicorn'
Chown the file with this Linux command
sudo chown sammy gunicorn
Run these commands to restart gunicorn and confirm
sudo systemctl enable gunicorn
sudo systemctl start gunicorn
sudo systemctl status gunicorn
PS: My environment was Ubuntu 18.04
I finally figured out I could look in journalctl and found the actual log. I had to chown the gunicorn file for the nginx user. Now its working and I just gotta tweak my nginx stuff cause its not find thing darn socket..
I have kibana listening on localhost:5601 and if I SSH tunnel to this port I can access kibana in my browser just fine.
I have installed nginx to act as a reverse proxy but having completed the setup all I get is 502 Bad Gateway. The more detailed error in the nginx error log is
*1 upstream prematurely closed connection while reading response header from upstream,
client: 1.2.3.4,
server: elk.mydomain.com,
request: "GET /app/kibana HTTP/1.1",
upstream: "http://localhost:5601/app/kibana"
My nginx config is:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.fedora.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
index index.html index.htm;
}
My kibana.conf file within /etc/nginx/conf.d/ is:
server {
listen 80 default_server;
server_name elk.mydomain.com;
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/htpasswd.users;
location / {
proxy_pass http://localhost:5601;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_cache_bypass \$http_upgrade;
}
}
This is a brand new Amazon Linux EC2 instance with the latest versions of kibana and nginx installed.
Has anyone encountered this problem before? I feel like it's a simple nginx config problem but I just can't see it.
It turns out that the slashes before the dollars proxy_set_header Upgrade \$http_upgrade; were a result of a copy-paste from another configuration management tool.
I removed the unnecessary slashes to make proxy_set_header Upgrade $http_upgrade; and reclaimed my sanity.
I am trying to deploy a flask application called pytimesheets on a CentOS7 VM using Gunicorn and Nginx. I was basically following this tutorial with some minor changes.
When I start the application with gunicorn --bind 0.0.0.0:8080 wsgi:app (without using Nginx) it works, but that's not the way I want it to run.
So I created a systemd service unit file /etc/systemd/system/pytimesheets.service:
[Unit]
Description=Gunicorn instance to serve pytimesheets
After=network.target
[Service]
User=centos
Group=nginx
WorkingDirectory=/home/centos/pytimesheets/pytimesheets
Environment="PATH=/home/centos/miniconda/envs/pytimesheets-dev/bin"
ExecStart=/home/centos/miniconda/envs/pytimesheets-dev/bin/gunicorn --workers 3 --bind unix:pytimesheets.sock -m 007 wsgi:app
[Install]
WantedBy=mulit-user.target
Started and enabled the gunicorn service - worked!
Next, I configured Nginx:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
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;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 8080;
server_name my.servername.com;
location / {
proxy_set_header HOST $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/home/centos/pytimesheets/pytimesheets/pytimesheets.sock;
}
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
I added the user nginx to my usergroup (centos, has sudo privileges) sudo usermod -a -G user nginx and gave it execute permissions in my home directory chmod 710 /home/centos
Finally, I started nginx, but all I get when I visit the site is a 502 Bad Gateway Error.
The Nginx error log shows me this:
2016/07/06 13:33:44 [crit] 17464#0:
*1 connect() to unix:/home/centos/pytimesheets/pytimesheets/pytimesheets.sock
failed (13: Permission denied) while connecting to upstream,
client: 10.250.16.87, server: my.servername.com,
request: "GET / HTTP/1.1",
upstream: "http://unix:/home/centos/pytimesheets/pytimesheets/pytimesheets.sock:/",
host: "my.servername.com"
The sock file is created once I start the pytimesheets service, and the location /home/centos/pytimesheets/pytimesheets/pytimesheets.sock may look weird, but it's correct.
My guess is that there is something messed up with the user rights.
Does anybody have an idea what I did wrong?
Update
I was able to run the application after setting setenforce = Permissive. However, I don't know if this is a permament solution.
There are 3 ingredients to this issue:
Docker container: I have a Docker container that is deployed on an EC2 instance. More specifically, I have the rocker/shiny image, which I have run using:
sudo docker run -d -v /home/ubuntu/projects/shiny_example:/srv/shiny-server -p 3838:3838 rocker/shiny
Shiny server: The standard Shiny server configuration file is untouched, and is set up to serve everything in the /srv/shiny-server folder on port 3838, and the contents of my local ~/projects/shiny_example are mapped to the container's /srv/shiny-server/.
In my local ~/projects/shiny_example, I have cloned a random Shiny app:
git clone https://github.com/rstudio/shiny_example
nginx: I have set up nginx as a reverse proxy and here are the contents of the /etc/nginx/nginx.conf in its entirety.
The issue is that with this setup, when I try to retrieve http://<ip-address>/shiny/shiny_example, I get a 404. The main clue I have as to what might be wrong is that when I do a:
wget http://localhost:3838/shiny_example
from the command line on my EC2 instance, I get:
--2016-06-13 11:05:08-- http://localhost:3838/shiny_example
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:3838... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: /shiny_example/ [following]
--2016-06-13 11:05:08-- http://localhost:3838/shiny_example/
Reusing existing connection to localhost:3838.
HTTP request sent, awaiting response... 200 OK
Length: 3136 (3.1K) [text/html]
Saving to: ‘shiny_example.3’
100%[==============================================================================================================================>] 3,136 --.-K/s in 0.04s
2016-06-13 11:05:09 (79.6 KB/s) - ‘shiny_example.3’ saved [3136/3136]
where the emphasis is mine.
I think that my nginx configuration does not account for the fact that when requesting a Docker mapped port, there is a 301 redirect. I think that the solution involves proxy_next_upstream, but I would appreciate some help in trying to set this up in my context.
I also think that this question can be shorn of the Docker context, but it would be nice to understand how to prevent a 301 redirect when requesting a resource from Shiny server that is in a Docker container, and whether this behavior is expected.
I can't be sure without more output, but suspect your error is in your proxy_redirect line:
location /shiny/ {
rewrite ^/shiny/(.*)$ /$1 break;
proxy_pass http://localhost:3838;
proxy_redirect http://localhost:3838/ $scheme://$host/shiny_example;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 20d;
}
Try changing that to:
location /shiny/ {
rewrite ^/shiny/(.*)$ /$1 break;
proxy_pass http://localhost:3838;
proxy_redirect http://localhost:3838/ $scheme://$host/shiny/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 20d;
}
The reason for that is when the 301 header comes back from "http://localhost:3838" to add the trailing slash, it gets rewritten to "http://localhost/shiny_example" which doesn't exist in your nginx config, plus it may also remove a slash from the path. This means the 301 from "http://localhost:3838/shiny_example" to "http://localhost:3838/shiny_example/" would get rewritten to to "http://localhost/shiny_exampleshiny_example/", at which point you get a 404.
There was nothing wrong with anything. Basically, one of the lines in /etc/nginx/nginx.conf was include /etc/nginx/sites-enabled/*, which was pulling in the default file for enabled sites, which has the following lines:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name localhost;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
which was overwriting my listen directives for port 80 and for location /. Commenting out the include directive for the default conf file for enabled sites in the /etc/nginx/nginx.conf file resolved all issues for me.
Not sure if this is still relevant but I have a minimal example here: https://github.com/mRcSchwering/butterbirne
A service shinyserver (which is based on rocker/shiny) is started with a service webserver (based on nginx:latest):
version: '2'
services:
shinyserver:
build: shinyserver/
webserver:
build: webserver/
ports:
- 80:80
I configured the ngin, so that it would redirect directly to the shiny server root. In my case I added the app (called myapp here) as the root of shinyserver (so no /myapp is needed). This is the whole 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;
keepalive_timeout 65;
# apparently this is needed for shiny server
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# proxy shinyserver
server {
listen 80;
location / {
proxy_pass http://shinyserver:3838;
proxy_redirect http://shinyserver:3838/ $scheme://$host/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 20d;
proxy_buffering off;
}
}
}
I am currently wanting to use NGINX in my Rails setup. I have placed the configuration files in the directory RAILS_ROOT/config/nginx. Here is my config-file placed named development.conf and the mime.types-file.
I am wanting to place my logs in the RAILS_ROOT/log-directory.
This is my development.conf:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# main access log
access_log log/nginx.access.log;
# main error log
error_log log/nginx.error.log debug;
sendfile on;
keepalive_timeout 65;
server {
listen 9001; #omg!
server_name local.woman.dk;
rewrite ^/(.*)/$ /$1 last;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_max_temp_file_size 0;
location / {
ssi on;
proxy_pass http://127.0.0.1:3000;
}
}
}
I am starting NGINX from my RAILS_ROOT with this command:
nginx -p . -c config/nginx/development.conf
And I get the following error:
nginx: [alert] could not open error log file: open() "./logs/error.log" failed (2: No such file or directory)
My version is this:
[(master)]=> nginx -v
nginx version: nginx/1.2.4
Am I doing anything wrong?
http://nginx.org/en/docs/ngx_core_module.html#error_log indicates that:
the default value is error_log logs/error.log error;
that for debug logging to work, nginx needs to be built with --with-debug.`
what's happening is that you're falling through to the default value, I'm not spotting any syntax errors so my guess is that your nginx is not compiled with --with-debug.
you can check that with the nginx -V (note: that's capital V)
On MAC it was in
/usr/local/logs/error.log
i found this after running:
nginx -V
configure arguments: --prefix=/usr/local --with-cc-opt=-Wno-deprecated-declarations --with-http_ssl_module --add-module=../nginx-rtmp-module/