how to stop dockerized nginx in foreground from flooding logs? - ruby-on-rails

I'm running nginx and unicorn in a docker container managed by supervisord.
So, supervisord is the docker command. It in turn spawns nginx and unicorn. Unicorn talks to nginx over a socket. nginx listens on port 80.
I also have a logspout docker container running, basically piping all the docker logs to papertrail by listening to docker.sock.
The problem is nginx is constantly spewing thousands of mundane entries to the logs:
172.31.45.231 - - [25/May/2016:05:53:33 +0000] "GET / HTTP/1.0" 200 12961 0.0090
I'm trying to disable it.
So far I've:
set access_logs /dev/null; in nginx.conf and vhost files.
tried to tell supervisord to stop logging the requests
[program:nginx]
command=bash -c "/usr/sbin/nginx -c /etc/nginx/nginx.conf"
stdout_logfile=/dev/null
stderr_logfile=/dev/null
tried to tell supervisord to send the logs to syslog not stdout:
[program:nginx]
command=bash -c "/usr/sbin/nginx -c /etc/nginx/nginx.conf"
stdout_logfile=syslog
stderr_logfile=syslog
Set log level in Unicorn to Warn in the rails code, and via env var.
Full supervisord conf:
[supervisord]
nodaemon=true
loglevel=warn
[program:unicorn]
command=bundle exec unicorn -c /railsapp/config/unicorn.rb
process_name=%(program_name)s_%(process_num)02d
numprocs=1
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
redirect_stderr=true
[program:nginx]
command=bash -c "/usr/sbin/nginx -c /etc/nginx/nginx.conf"
stdout_logfile=/dev/null
stderr_logfile=/dev/null

You could try and change nginx log level with a:
access_log off;
The goal remains to modify the nginx.conf used by the nginx image.

Related

failed (111: Connection refused) while connecting to upstream -- nginx/gunicorn connection via 127.0.0.1 [duplicate]

This question already has answers here:
Docker-compose/Nginx/Gunicorn - Nginx not working
(1 answer)
How to communicate between Docker containers via "hostname"
(5 answers)
Closed 4 months ago.
Below are the important details:
Dockerfile for nginx build
FROM nginx:latest
EXPOSE 443
COPY nginx.conf /etc/nginx/nginx.conf
Nginx.conf
events {}
http {
client_max_body_size 1000M;
server {
server_name _;
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_set_header Host $host;
}
listen 443 ssl;
ssl_certificate cert/name.crt;
ssl_certificate_key cert/name.key;
}
}
Nginx docker command
docker run -dit -p 0.0.0.0:443:443 -v /etc/cert/:/etc/nginx/cert <MY NGINX CONTAINER> nginx -g 'daemon off;'
Docker command to start gunicorn server
docker run -dit -p 127.0.0.1:8000:8000 <My FASTAPI CONTAINER> gunicorn -w 3 -k uvicorn.workers.UvicornWorker -b 127.0.0.1:8000 server:app
Other details:
I expose port 8000 in my Fastapi container docker build
I run nginx docker command right before the gunicorn docker command
I am currently testing with python requests library and have turned verify=False for the SSL configuration
Edit:
My issue related most directly to this post:
From inside of a Docker container, how do I connect to the localhost of the machine?
Binding to 0.0.0.0:8000 for my gunicorn run and adding the tag --network="host" to my docker run nginx command solved my issue

Port 8013 unavailable installing the Data Hub Central warfile in MarkLogic running in a docker container

My docker configuration needs to map ports for external access, but when trying to install the data hub central war file, mlDeploy and mlRedeploy encounter problems, that the ports are unavailable:
Task :mlDeployApp
Creating custom rewriters for staging and job app servers
Loading REST options for staging server
Initializing ExecutorService
Loading default query options from file default.xml
Shutting down ExecutorService
Loading REST options for jobs server
Initializing ExecutorService
Loading traces query options from file traces.xml
Shutting down ExecutorService
Writing traces query options to MarkLogic; port: 8013
Error occurred while loading modules; host: localhost; port: 8013;
cause: java.net.ConnectException: Failed to connect to localhost/127.0.0.1:8013
...
What went wrong:
Execution failed for task ':mlDeployApp'.
Error occurred while loading REST modules: Error occurred while loading modules; host: localhost; port: 8013; cause: java.net.ConnectException: Failed to connect to localhost/127.0.0.1:8013
Docker file contents
FROM store/marklogicdb/marklogic-server:10.0-7-dev-centos
WORKDIR /tmp
EXPOSE 7997-8040
EXPOSE 8080
EXPOSE 9000
CMD /etc/init.d/MarkLogic start && tail -f /dev/null
Original docker run command:
docker run -d --name=marklogic10.0-7_local -p 7997-8040:7997-8040 -p 8080:8080 -p 9000:9000 marklogic-initial-install:10.0-7-dev-centos
Revised docker run command:
docker run -d --name=marklogic10.0-7_local -p 7997-8012:7997-8012 -p 8014-8040:8014-8040 -p 8043:8013 -p 8090:8080 -p 9000:9000 marklogic-initial-install:10.0-7-dev-centos
Note: I originally had the same problem with port 8080 but mapped it to port 8090 which fixed the problem. Doing the same for port 8013 did not work.
The problem was with the installation steps and not the ports.

How to get NGINX running in Docker to reload nginx.conf configuration

I am trying to get a NGINX based reverse proxy to work in Windows/WSL2 environment. I am very new to Docker and NGINX world. I am able to get the following command to work
docker run --name nginx-test -p 8080:80 -v /home/skotekar/nginx.conf:/etc/nginx/nginx.conf:ro -v /mnt/d/site1/wwwroot:/usr/share/nginx/html:ro -d nginx:alpine
I can then browse http://localhost:8080 and view my static content just fine. As you see from the command I have a default nginx.conf in my local /home folder which gets mapped into NGINX Docker when running. It works fine the first time.
Now if I stop the container using:
docker container stop nginx-test
Then make changes to the nginx.conf file in my /home directory and want to start the container with updated configuration using following command:
docker container start nginx-test
But this command fails gives me a very confusing message:
Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:59: mounting "/run/desktop/mnt/host/wsl/docker-desktop-bind-mounts/Ubuntu-20.04/c0d0caa87ff063ee46265048f5b1ee489a8945669d39c6f6110cd578b8cda1ed" to rootfs at "/var/lib/docker/overlay2/4e6b279945acb06200b3677272774f4b5fbb6a619214decbca8c594dbbe3b8ec/merged/etc/nginx/nginx.conf" caused: no such file or directory: unknown
Only way to get it back running is to delete the container and use the first command again. Any idea how to get this working. It will be easier if I could just restart my container after making changes to config until I figure out the correct reverse proxy settings I need.
Thanks
You do not need to restart container to reload new config. Nginx can hot-reload config without restarting.
Once you have mounted volume, you can make changes and they will be reflected in container immediately.
To test your config just execute this command:
docker exec nginx-test nginx -t
To reload new config:
docker exec nginx-test nginx -s reload
Edit! Access Windows host from Docker running in the WSL2
As per comments i am very curious about your issues, because i haven't seen them in my career.
So my steps to reproduce your use case is:
1. Download any web application for windows
I chose caddy web server as it is single binary and I know it. It is similar application to Nginx
https://caddyserver.com/download
2. Setup simple webpage on Windows Host
I prepared Caddyfile - Config for Caddy Web Server:
:80
respond "Hello, world from Caddy on Windows!"
Then i put this Caddyfile in the same directory, where I have Caddy Server binary:
PS C:\Users\Daniel\Downloads\caddy> ls
Directory: C:\Users\Daniel\Downloads\caddy
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 29.01.2021 11:59 52 Caddyfile
-a---- 29.01.2021 11:55 34081792 caddy_windows_amd64.exe
3. Start Web Server on Windows and verify it.
To start web server run: ./caddy.exe run
Example:
PS C:\Users\Daniel\Downloads\caddy> .\caddy_windows_amd64.exe run
2021/01/29 11:01:27.520 ←[34mINFO←[0m using adjacent Caddyfile
2021/01/29 11:01:27.528 ←[34mINFO←[0m admin admin endpoint started {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2021/01/29 11:01:27.529 ←[34mINFO←[0m tls.cache.maintenance started background certificate maintenance {"cache": "0xc000497490"}
2021/01/29 11:01:27.529 ←[34mINFO←[0m http server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server {"server_name": "srv0", "http_port": 80}
2021/01/29 11:01:27.530 ←[34mINFO←[0m tls cleaned up storage units
2021/01/29 11:01:27.532 ←[34mINFO←[0m autosaved config {"file": "C:\\Users\\Daniel\\AppData\\Roaming\\Caddy\\autosave.json"}
2021/01/29 11:01:27.532 ←[34mINFO←[0m serving initial configuration
Now verify if it is working. Go to your browser and visit the http://localhost/ page:
4. Now verify you have WSL2 running on the windows host:
PS C:\Users\Daniel> wsl.exe --list --all -v
NAME STATE VERSION
* Ubuntu-20.04 Running 2
If yes shell there with command wsl
5. Start docker daemon
daniel#DESKTOP-K8UQA2E:~$ sudo service docker start
* Starting Docker: docker
6. Check your IPv4 address for WSL Network adapter in the Windows and Linux
Open powershell and execute the ifconfig command, then find WSL network adapter:
Ethernet adapter vEthernet (WSL):
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::e96c:c3d6:464e:2a3b%72
IPv4 Address. . . . . . . . . . . : 172.20.240.1
Subnet Mask . . . . . . . . . . . : 255.255.240.0
Default Gateway . . . . . . . . . :
Your Windows IP is 172.20.240.1
Then go to WSL and execute curl 172.20.240.1, to check if your hosts are connected.
daniel#DESKTOP-K8UQA2E:~$ curl 172.20.240.1
Hello, world from Caddy on Windows!d
Now figure out the Linux Host IP with the ip a command and see IP in the same network as Windows:
5: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:ce:28:8e brd ff:ff:ff:ff:ff:ff
inet 172.20.252.177/20 brd 172.20.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fece:288e/64 scope link
valid_lft forever preferred_lft forever
7. Prepare simple nginx configuration
worker_processes 5; ## Default: 1
worker_rlimit_nofile 8192;
events {
worker_connections 4096; ## Default: 1024
}
http {
index index.html index.htm index.php;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
server_names_hash_bucket_size 128; # this seems to be required for some vhosts
server { # simple load balancing
listen 80;
location / {
return 200 "Hello World from Nginx in Linux";
}
location /windows {
proxy_pass http://172.20.240.1/;
}
}
}
This is very simple config
8. Start the docker with host networking mode.
If you do not want to use the host networking, you have to do forwarding packets from docker network to the wsl network because your docker will not have access to windows host directly.
But let's say you can start container with host networking.
Run this command:
daniel#DESKTOP-K8UQA2E:~/nginx-test$ sudo docker run -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf --name="nginx-local" --network=host -d nginx:latest
Verify your docker is working fine:
daniel#DESKTOP-K8UQA2E:~/nginx-test$ sudo docker logs nginx-local
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
daniel#DESKTOP-K8UQA2E:~/nginx-test$ sudo docker ps | grep nginx
de9873314b77 nginx:latest "/docker-entrypoint.…" 20 seconds ago Up 19 seconds
8. Try to get response from linux and windows
daniel#DESKTOP-K8UQA2E:~/nginx-test$ curl localhost
Hello World from Nginx in Linux
daniel#DESKTOP-K8UQA2E:~/nginx-test$ curl localhost/windows
Hello, world from Caddy on Windows!
daniel#DESKTOP-K8UQA2E:~/nginx-test$

Nginx container fails to start on Cloud Run

I'm attempting to serve simple static page with Nginx on Cloud Run. But the container fails to properly start serving.
Container is starting, as shown by the debug lines echoed from docker-entrypoint.sh:
2019-05-26T22:19:02.340289Z testing config
2019-05-26T22:19:02.433935Z nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
2019-05-26T22:19:02.434903Z nginx: configuration file /etc/nginx/nginx.conf test is successful
2019-05-26T22:19:02.436605Z starting on 8080
2019-05-26T22:19:02.487188Z2019/05/26 22:19:02 [alert] 6#6: prctl(PR_SET_DUMPABLE) failed (22: Invalid argument)
and eventually terminates
2019-05-26T22:20:00.153060259ZContainer terminated by the container manager on signal 9.
In order to conform with the Cloud Run service contract specifically listening on $PORT the docker-entrypoint.sh performs $PORT substitution in conf.d/*.conf.
FROM nginx:1.15-alpine
COPY nginx-default.conf.template /etc/nginx/conf.d/default.conf.template
COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
I'm pretty confident issue lies within docker-entrypoint.sh because once $PORT is hardcoded as 8080 and image looks like this:
FROM nginx:1.15-alpine
COPY nginx-default.conf /etc/nginx/conf.d/default.conf
Cloud Run "runs" fine.
The code performing the substitution:
export NGINX_PORT=${PORT:-8080}
for f in $(find /etc/nginx/conf.d/ -type f -name '*.conf'); do
envsubst '$NGINX_PORT' < $f > $f
done
NOTE: reading < $f and writing > $f to the same file works as tested by running the container locally.
Expected
nginx configuration gets $PORT placeholder substituted with actual values
container runs and listens on $PORT on Cloud Run
Actual
container fails to run on Cloud Run
container runs and listens on $PORT locally
I have published a blog post to show how to run nginx in a Cloud Run container (alongside with a process).
You can read the article here: https://ahmet.im/blog/cloud-run-multiple-processes-easy-way/ or take a look at the code repository at https://github.com/ahmetb/multi-process-container-lazy-solution
Basically, the nginx.conf file should be something like:
events {}
http {
server {
listen 8080; # Cloud Run PORT env variable
access_log /dev/stdout;
error_log /dev/stdout;
# if you need to serve static access, specify an absolute path like below
location /static/ {
alias /src/static/;
}
# anything else is routed to your app that you would start on port 8081
location / {
proxy_pass http://localhost:8081;
}
}
}
daemon off;
pid /run/nginx.pid;
You can sort of safely hard code port 8080 in your nginx.conf as it's very unlikely to change in the foreseeable future on Cloud Run.
fixed by replacing
for f in $(find /etc/nginx/conf.d/ -type f -name '*.conf'); do
envsubst '$NGINX_PORT' < $f > $f
done
with
sed -i "s/\${NGINX_PORT}/${NGINX_PORT}/g" /etc/nginx/conf.d/*.conf
and changing $NGINX_PORT -> ${NGINX_PORT} in *.conf files to avoid substitution ambiguities

PhpStorm debugger with a docker container, nginx in reverse proxy and https

I need some help in order to configure PhpStorm debugger with a particular development configuration.
On my pc (192.168.1.23) I have the source code of a PHP project, a dbms and an instance of nginx as reverse proxy. Nginx is configured in order to send all the traffic to a docker container:
server {
listen 80;
listen [::]:80;
server_name www.mysite.local;
root /usr/share/nginx/html/;
# pass PHP scripts to FastCGI server
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location / {
index index.html index.php;
}
}
upstream backend {
# configuration in order to use apache inside docker container
server 172.17.0.2:80;
}
The docker container (172.17.0.2) has been created with:
docker run -dP --add-host=db.local:172.17.0.1 \
-e remote_connect_back_xdbg=1 \
-e remote_host_xdbg='192.168.1.23' \
-v /opt/live:/opt/live \
--name local_php_apache_container local_php_apache_image
So Docker mounts my project (located at /opt/live) inside /opt/live of the container. The container is a Debian 9 with PHP 5.3 + Apache2.
And it is started automatically at the boot of the pc with this command:
docker exec -it local_php_apache_container /bin/bash
Inside the docker container, the xdebug configuration in php.ini is:
[xdebug]
xdebug.remote_connect_back=${remote_connect_back_xdbg}
xdebug.remote_enable=1
xdebug.remote_port=10123
xdebug.remote_handler=dbgp
xdebug.remote_log=/stackdriver/log/xdebug.log
xdebug.remote_mode=req
xdebug.remote_autostart=1
xdebug.remote_host=${remote_host_xdbg}
xdebug.idekey="netbeans-xdebug"
The idkey is netbeans-xdebug because with netbeans, the debugger works properly (https://www.mysite.local/index.php?XDEBUG_SESSION_START=netbeans-xdebug, https with a local untrusted certificate)
But I have a lot of problems with PHPStorm and the position of PHP interpreter, both with PHP Build-in Web Server and with PHP Remote Debug configuration...
Any suggestions?

Resources