docker run, docker exec and logs - nginx

If I do :
docker run --name nginx -d nginx:alpine /bin/sh -c 'echo "Hello stdout" > /dev/stdout'
I can see "Hello stdout" when I do :
docker logs nginx
But when the container is running (docker run --name nginx -d nginx:alpine) and I do :
docker exec nginx /bin/sh -c 'echo "Hello stdout" > /dev/stdout'
or when I attach the container with :
docker exec -it nginx /bin/sh
and then :
echo "Hello stdout" > /dev/stdout
I can't see anything in docker logs. And since my Nginx access logs are redirected to /dev/stdout, I can't see them as well.
What is happening here with this stdout ?

When you docker exec you can see you have several process
/ # ps -ef
PID USER TIME COMMAND
1 root 0:00 nginx: master process nginx -g daemon off;
6 nginx 0:00 nginx: worker process
7 root 0:00 /bin/sh
17 root 0:00 ps -ef
/ #
and in Linux, each process has its own stdin, stdout, stderr (and other file descriptors), in /proc/pid/fd
and so, with your docker exec (pid 7) you display something in
/proc/7/fd/1
If you do ls -ltr /proc/7/fd/1, it displays something like
/proc/4608/fd/1 -> /dev/pts/2 which means output is being sent to terminal
while your nginx process (pid 1) displays his output in
/proc/1/fd/1
If you do ls -ltr /proc/1/fd/1, it displays something like /proc/1/fd/1 -> pipe:[184442508] which means output is being sent to docker logging driver

Related

Podman mount host volume return 'Error: statfs: no such file or directory' in Mac OS

Recently switched from Docker Desktop to Podman, everything work smoothly except when I want to mount host volume into container. e.g.
➜ ~ podman run --name nginx -v ~/bin/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -d -p 8080:80 nginx
Error: statfs /Users/rb/bin/nginx/nginx.conf: no such file or directory
➜ ~ ls -lt ~/bin/nginx/nginx.conf
-rw-r--r-- 1 rb staff 490 Apr 23 14:31 /Users/rb/bin/nginx/nginx.conf
The host file ~/bin/nginx/nginx.conf do exist, so what's the problem here?
Had the same problem on MacOs.
I fixed it when used mount point not from the host machine itself, but from podman virtual machine.
So firstly i mounted the host volume to podman vm:
podman machine init -v $HOST_VOLUME:/mnt/$PODMAN_VM_VOLUME
And after that mounted PODMAN_VM_VOLUME to CONTAINER_VOLUME:
podman run -d -it --name test -v /mnt/$PODMAN_VM_VOLUME:/$CONTAINER_VOLUME

Openresty Hello world with docker

I'm trying make my application dockerize for that I've been following official openresty dockerfile. Os in my system is Ubuntu 16.04 64 bit.
I have already pull that image using this cmd.
docker pull openresty/openresty:1.11.2.3-xenial
Now I want to use this image and want make simple hello world application. For that I have created my work directory, create one custom dockerfile and build my custom image with that. And finaly I run that image. Below is my dockerfile content.
FROM openresty/openresty:1.11.2.3-xenial
EXPOSE 8080
CMD nginx -p `pwd` -c nginx.conf
nginx.conf
worker_processes 1;
error_log stderr notice;
events {
worker_connections 1024;
}
http {
include /usr/local/openresty/nginx/conf/mime.types;
server {
listen 8888;
location / {
default_type text/html;
content_by_lua_file "app.lua";
}
}
}
app.lua
ngx.say('Hello World!')
ngx.exit(200)
Build image
docker build -t user/openresty .
Start container
docker run rahul/openresty
When I try to start container, it gives me an error like nginx: invalid option: "/bin/sh"
I have no idea that I'm going on right or wrong direction.
Update:
docker run -it -p 8888:80 -v /home/software/docker/openresty:/usr/local/openresty/nginx/html:ro openresty/openresty:1.11.2.3-xenial
I just used this CLI and it's start showing index.html that I have created. Again I tried to link my custom nginx.conf using below CLI but it's not working.
docker run -it -p 8888:8888 -v /home/software/docker/openresty:/usr/local/openresty/nginx/html:ro -v /home/software/docker/openresty/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf:ro openresty/openresty:1.11.2.3-xenial
docker run -it -p 8888:8888 -v $(pwd):/app openresty/openresty:1.11.2.3-xenial -p /app -c nginx.conf
With below command it starts working but can anyone please explain it?
docker run -it -p 8888:8888 -v $(pwd):/app openresty/openresty:1.11.2.3-xenial -p /app -c nginx.conf
You have wrong port settings, look:
EXPOSE 8080
!=
listen 8888;

Docker Alpine nginx 403 Forbidden error for swagger-ui-builder

This happened on Ubuntu 16.04 in VirtualBox on Windows 10, with docker version 1.12.1, and swagger-ui version 2.2.2.
I was trying to build and run Swagger UI in a docker container, following the instructions on their site:
docker build -t swagger-ui-builder .
docker run -p 127.0.0.1:8080:8080 swagger-ui-builder
The instruction says that now I should be able to view the swagger-ui running, however, when I opened 127.0.0.1:8080 I only got this page back:
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.8.1</center>
</body>
</html>
This is the content of the Dockerfile:
FROM alpine:3.3
MAINTAINER Roman Tarnavski
RUN apk add --update nginx
COPY nginx.conf /etc/nginx/
ADD ./dist/ /usr/share/nginx/html
EXPOSE 8080
CMD nginx -g 'daemon off;'
I found similar posts on stackoverflow, but none of them helped me solve this problem. What am I doing wrong and how to fix this?
The problem was caused by a permission requirement: the www-data user/group did not have access to website's directory and files.
This problem was explained in the accepted answer to this post: Nginx 403 forbidden for all files
To solve this, the following lines have to be added to the Dockerfile:
RUN set -x ; \
addgroup -g 82 -S www-data ; \
adduser -u 82 -D -S -G www-data www-data && exit 0 ; exit 1
RUN chown -R www-data:www-data /usr/share/nginx/html/*
RUN chmod -R 0755 /usr/share/nginx/html/*
The upper part of the commands are explained in this gist: https://gist.github.com/briceburg/47131d8caf235334b6114954a6e64922
The user/group www-data has to be added first, before the permission can be set for it. The snippet notes that 82 is the standard uid/gid for "www-data" in Alpine
The lower part of the commands is the solution to a similar question in another forum: https://www.digitalocean.com/community/questions/nginx-403-forbidden--2
So the fixed Dockerfile would look like this:
FROM alpine:3.3
MAINTAINER Roman Tarnavski
RUN apk add --update nginx
COPY nginx.conf /etc/nginx/
ADD ./dist/ /usr/share/nginx/html
RUN set -x ; \
addgroup -g 82 -S www-data ; \
adduser -u 82 -D -S -G www-data www-data && exit 0 ; exit 1
RUN chown -R www-data:www-data /usr/share/nginx/html/*
RUN chmod -R 0755 /usr/share/nginx/html/*
EXPOSE 8080
CMD nginx -g 'daemon off;'
Now if I rebuild and rerun swagger-ui-builder, the website shows up correctly.

Unable to use -lt when running Nginx Docker or cat logs

I've recently pulled a nginx image:
docker pull nginx
I can run it successfully and go to http://server_name and see the "Welcome to Nginx" page:
docker run -d -p 80:80 nginx
But then when I try to check logs:
docker exec 6c79549e3eb4f6e5fc06f049b67814ac4560ce2cdd7cc6ae84b44b5ae09a9a05 cat /var/log/nginx/access.log
It just hangs and outputs nothing. Same with error log. Now if I create a test.txt file in that same folder and use docker exec to (view) cat the file, I executes without hanging or any issues.
Even if I try to run it in interactive mode, it just hangs:
docker run -i -t -p 80:80 nginx
Once again the terminal hangs on the next line doing nothing, but it seems to work because I can access the nginx welcome page.
Really confused what is going on, I've tried to search for this problem, but have not found any solution so far. Without being able to view the logs, it is going to be pretty hard to debug :) Also shouldn't the access logs be moved to stdout in the nginx container since by convention docker containers log to stdout?
If you go inside the container docker exec -it <container-id> /bin/bash and check the log location ls -la /var/log/nginx/, you will see the following output:
lrwxrwxrwx 1 root root 11 Apr 30 23:05 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Apr 30 23:05 error.log -> /dev/stderr
Clearly, the logs are written in stdout. You can also try doing cat access.log inside the container and it still doesn't show anything.
Now, the right way to get your logs is going outside the container and doing docker logs <container-id>
Then, you would see your logs.
Hope this helps!

Nginx pid keeps changing every few second after killing the master process

I'm using the following Upstart script to keep Nginx up and running on Ubuntu server:
start on (filesystem and net-device-up IFACE=lo)
stop on runlevel [!2345]
env DAEMON=/usr/sbin/nginx
env CONF=/etc/nginx/nginx.conf
respawn
respawn limit 10 5
pre-start script
$DAEMON -t
if [ $? -ne 0 ]; then
exit $?
fi
end script
exec $DAEMON -c $CONF -g "daemon off;" > /dev/null 2>&1
This script works fine except when I'm killing the Nginx master process using the kill command. After killing the master process /var/run/nginx.pid remains the same but Nginx pid keeps changing every few seconds (this means Nginx is restarting all the time?). Any idea how to fix this?

Resources