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

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!

Related

Docker run results in "host not found in upstream" error

I have a frontend-only web application hosted in Docker. The backend already exists but it has "custom IP" address, so I had to update my local /etc/hosts file to access it. So, from my local machine I am able to access the backend API without problem.
But the problem is that Docker somehow can not resolve this "custom IP", even when the host in written in the container (image?) /etc/hosts file.
When the Docker container starts up I see this error
$ docker run media-saturn:dev
2016/05/11 07:26:46 [emerg] 1#1: host not found in upstream "my-server-address.com" in /etc/nginx/sites/ms.dev.my-company.com:36
nginx: [emerg] host not found in upstream "my-server-address.com" in /etc/nginx/sites/ms.dev.my-company.com:36
I update the /etc/hosts file via command in Dockerfile, like this
# install wget
RUN apt-get update \
&& apt-get install -y wget \
&& rm -rf /var/lib/apt/lists/*
# The trick is to add the hostname on the same line as you use it, otherwise the hosts file will get reset, since every RUN command starts a new intermediate container
# it has to be https otherwise authentification is required
RUN echo "123.45.123.45 my-server-address.com" >> /etc/hosts && wget https://my-server-address.com
When I ssh into the machine to check the current content of /etc/hosts, the line "123.45.123.45 my-server-address.com" is indeed there.
Can anyone help me out with this? I am Docker newbee.
I have solved this. There are two things at play.
One is how it works locally and the other is how it works in Docker Cloud.
Local workflow
cd into root of project, where Dockerfile is located
build image: docker build -t media-saturn:dev .
run the builded image: docker run -it --add-host="my-server-address.com:123.45.123.45" -p 80:80 media-saturn:dev
Docker cloud workflow
Add extra_host directive to your Stackfile, like this
and then click Redeploy in Docker cloud, so that changes take effect
extra_hosts:
'my-server-address.com:123.45.123.45'
Optimization tip
ignore as many folders as possible to speed up process of sending data to docker deamon
add .dockerignore file
typically you want to add folders like node_modelues, bower_modules and tmp
in my case the tmp contained about 1.3GB of small files, so ignoring it sped up the process significantly

Docker nginx container exists instantly

I want to have some control over the official nginx image, so I wrote my own Dockerfile that adds some extra funtionality to it.
The file has the following contents:
FROM nginx
RUN mkdir /var/www/html
COPY nginx/config/global.conf /etc/nginx/conf.d/
COPY nginx/config/nginx.conf /etc/nginx/nginx.conf
When I build this image and create a container of the image using this command:
docker run -it -d -v ~/Projects/test-website:/var/www/html --name test-nginx my-nginx
It will exit instantly. I can't access the log files as well. What could be the issue? I've copied the Dockerfile of the official nginx image and this does the same thing.
So I didn't know about the docker ps -a; docker logs <last container id> command. I executed this and it seemed I had a duplicated daemon off; command.
Thanks for the help guys ;)!

Stop a Nginx Docker container

I am trying to stop a Docker container running Nginx only after there has been no activity in the access.log of that Nginx instance for a period of time.
Is it possible to stop a Docker container from inside the container? The other solution I can think of is to have a cron running on the host OS that checks the /var/lib/docker/aufs/mnt/[container id]/ but I am planning on starting lots of containers and would prefer not to have to keep a list of IDs.
The docker container stops when the main process in the container stops.
I setup a little dockerfile and a start script to show how this could work in your case:
Dockerfile
FROM nginx
COPY start.sh /
CMD ["/start.sh"]
start.sh
#!/bin/bash
nginx &
sleep 20
# replace sleep 20 with your test of inactivity
nginx stop
Build container, run and test
$ docker build -t ng .
$ docker run -d ng
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a373e721da7 ng:latest "/start.sh" 4 seconds ago Up 3 seconds 443/tcp, 80/tcp distracted_colden
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a373e721da7 ng:latest "/start.sh" 16 seconds ago Up 16 seconds 80/tcp, 443/tcp distracted_colden
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$
You could share your docker sock within that docker image and then do any operations necessary.
to share docker sock within the docker image do something like this:
docker run -v /var/run/docker.sock:/run/docker.sock -v $(which docker):/bin/docker YOUR_IMAGE
inside ENV vars you will have your container id, example to run within container echo $HOSTNAME
I ran an nginx container and then wasn't able to fire it up again:
nginx: [emerg] bind() to unix:/var/run/nchan.sock failed (98: Address already in use)
The easiest fix was to just "prune":
docker system prune
Docker can run command in your running container using the exec command:
docker exec [-d|--detach[=false]] [--help] [-i|--interactive[=false]] [-t|--tty[=false]] CONTAINER COMMAND [ARG...]

Dockerized nginx is not starting

I have tried following some tutorials and documentation on dockerizing my web server, but I am having trouble getting the service to run via the docker run command.
This is my Dockerfile:
FROM ubuntu:trusty
#Update and install stuff
RUN apt-get update
RUN apt-get install -y python-software-properties aptitude screen htop nano nmap nginx
#Add files
ADD src/main/resources/ /usr/share/nginx/html
EXPOSE 80
CMD service nginx start
I create my image:
docker build -t myImage .
And when I run it:
docker run -p 81:80 myImage
it seems to just stop:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
90e54a254efa pms-gui:latest /bin/sh -c service n 3 seconds ago Exit 0 prickly_bohr
I would expect this to be running with port 81->80 but it is not. Running
docker start 90e
does not seem to do anything.
I also tried entering it directly
docker run -t -i -p 81:80 myImage /bin/bash
and from here I can start the service
service nginx start
and from another tab I can see it is working as intended (also in my browser):
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
408237a5e10b myImage:latest /bin/bash 12 seconds ago Up 11 seconds 0.0.0.0:81->80/tcp mad_turing
So I assume it is something I am doing wrong with my Dockerfile? Could anyone help me out with this, I am quite new to Docker. Thank you!
SOLUTION: Based on the answer from Ivant I found another way to start nginx in the foreground. My Dockerfile CMD now looks like:
CMD /usr/sbin/nginx -g "daemon off;"
As of now, the official nginx image uses this to run nginx (see the Dockerfile):
CMD ["nginx", "-g", "daemon off;"]
In my case, this was enough to get it to start properly. There are tutorials online suggesting more awkward ways of accomplishing this but the above seems quite clean.
Docker container runs as long as the command you specify with CMD, ENTRTYPOINT or through the command line is running. In your case the service command finishes right away and the whole container is shut down.
One way to fix this is to start nginx directly from the command line (make sure you don't run it as a daemon).
Another option is to create a small script which starts the service and then sleeps forever. Something like:
#!/bin/bash
service nginx start
while true; do sleep 1d; done
and run this instead of directly running the service command.
A third option would be to use something like runit or similar program, instead of the normal service.
Using docker-compose:
To follow the recommended solution, add to docker-compose.yml:
command: nginx -g "daemon off"
I also found I could simply add to nginx.conf:
daemon off;
...and continue to use in docker-compose.yml:
command: service nginx start
...although it would make the config file less portable outside docker.
Docker as a very nice index of offical and user images. When you want to do something, chances are someone already did it ;)
Just search for 'nginx' on index.docker.io, you will see, there is an official nginx image: https://registry.hub.docker.com/_/nginx/
There you have a full guide to help you start your webserver.
Feel free to take a look at other users nginx image to see variants :)
The idea is to start nginx in foreground mode.
If you run "service nginx start", it is a parent process which will start a child process of nginx. If you run "service nginx start" as CMD in a container, the Process ID 1 for the container will be "service nginx start" or ServiceManager (SystemD), while actual nginx would be running as a child process.
If you run "service nginx start", and then "ps -ef", you will get output as below. I have run it my host OS.
root#ip-172-31-85-74:/home/ubuntu# service nginx start
root#ip-172-31-85-74:/home/ubuntu#
root#ip-172-31-85-74:/home/ubuntu# ps -ef | grep nginx
root 18593 1 0 12:27 ? 00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 18595 18593 0 12:27 ? 00:00:00 nginx: worker process
root 18599 17918 0 12:27 pts/0 00:00:00 grep --color=auto nginx
So, here the process ID 18593 is the child process which has parent process 1.
Container exits when their Process ID 1 exits. And in case of CMD "service nginx start", the PID 1 is the process manager, may be SystemD. It starts nginx as a child process, and exits itself, hence the container exits.
Similarly, if you run a shell script (for eg : start.sh) in CMD, as soon as the script ends, the container will exit. Even though the script starts some services (eg - nginx) in its execution, as soon as the script ends, the container will exit, because the PID 1 will be of the shell script. The parent process will be "./start.sh", and the services started by script will be child processes. In case you want to use a shell script in CMD, and want the container to run indefinitely, you need a command at last of the script which doesn't let it end. Something as shown below:
#!/bin/bash
service nginx start
while true; do sleep 1d; done

Nginx Invalid PID number

I issued a nginx -s stop and after that I got this error when trying to reload it.
[error]: invalid PID number "" in "/var/run/nginx.pid"
That /var/run/nginx/pid file is empty atm.
What do I need to do to fix it?
nginx -s reload is only used to tell a running nginx process to reload its config. After a stop, you don't have a running nginx process to send a signal to. Just run nginx (possibly with a -c /path/to/config/file)
in my case I solved this by starting the service.
sudo /etc/init.d/nginx start
The command above will start the service in Debian/Ubuntu. It will issue an error if there is any problem (like Apache listening in the same port)
After that nginx -s reload will work like a charm
This will clear out the issue on ubuntu 16.04 and above
sudo service nginx stop
you may need to remove the pid file nginx.pid whose location may be defined in file /etc/nginx/nginx.conf look for line like
cat /etc/nginx/nginx.conf | grep pid # see if pid file is defined
this line may live in file /etc/nginx/nginx.conf
pid /run/nginx.pid; # in file /etc/nginx/nginx.conf
if pid file does exist then remove it now
ls -la /var/run/nginx/pid # this file may live elsewhere
ls -la /run/nginx.pid # on Ubuntu 16.04+
after the pid file has been removed lets launch nginx
sudo service nginx start
ps -eaf|grep nginx # confirm its running
sudo nginx -t && sudo nginx -s reload # confirm config is OK
# typical output
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
sudo service nginx stop # issue stop
ps -eaf|grep nginx # confirm it actually stopped
now sanity has been restored and you are free to launch at will
In the latest version(1.2.0) that I downloaded there is no "-s start" option, it will say
nginx: invalid option: "-s start"
You can start nginx by
sudo /etc/nginx/sbin/nginx
The server will be started and then there wont be any Invalid pid number errors.
To avoid downtime with restarting nginx,
ps aux | grep nginx
PID of nginx master process
echo PID > /var/run/nginx.pid
nginx -s reload
In my case nginx was stopped (crashed I assume). Solved the issue by:
service nginx status
nginx stop/waiting
service nginx start
nginx start/running, process 3535
Then nginx -s reload worked like a charm.
I am using nginx/1.8.0 on trusty.
This happens if the nginx process was stopped manually or was killed.
Check if the process is still running:
sudo lsof -nP -iTCP:<port> | grep LISTEN
I am on mac, and I reinstall the nginx with:
brew reinstall nginx
Then start the service using brew:
brew services start nginx
On CentOS 7 I done it with this:
sudo systemctl start nginx
#Then check all things are OK
sudo systemctl status -l nginx
For anyone who still has issues, in my case, there was an apache2 server that was running.
You can try debugging what went wrong in your nginx machine by executing this command -
systemctl status nginx
This gave me an insight that the port was already in us by apache2 server.
so you can do sudo service apache2 stop and then do sudo service nginx start.
Docker Alpine users should use
nginx
by using that nginx will be start there is no error by
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
then reload it by
nginx -s reload

Resources