I have Dockerfile like:
FROM python:3.6.5-jessie
MAINTAINER twitter myname
RUN apt-get update
RUN apt-get install -y git
RUN apt-get install -y nginx
RUN pip install --upgrade pip
RUN git clone https://github.com/hongmingu/requirements
RUN pip install -r /requirements/requirements_django.txt
RUN apt-get install -y vim
RUN mkdir -p /uwsgi_log
RUN git clone https://github.com/hongmingu/smaple_django
RUN apt-get install -y nginx
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./uwsgi.ini /uwsgi.ini # it runs in daemonized mode
# These files are just setting files. nginx get request at port 8000 and uwsgi runs django project.
RUN uwsgi --ini /uwsgi.ini
RUN service nginx restart
CMD ["python3"]
I think these 2 lines not work:
RUN uwsgi --ini /uwsgi.ini
RUN service nginx restart
Because When I build it and run it with linux command: sudo docker run --rm -it -p 8080:8000 hongmingu/smaple:0.1 /bin/bash my 127.0.0.1:8080 does not work. But, When I attach container and type command manually like, uwsgi --ini /uwsgi.ini and service nginx restart, It works well.
So, Is it impossible to run uwsgi, nginx in Dockerfile?
I want to do it so that I hope I don't need to run uwsgi and nginx manually.
Where did I make fault? Is there any good way to do this?
This docker image(hongmingu/smaple:0.1) is here: https://cloud.docker.com/u/hongmingu/repository/docker/hongmingu/smaple
You misunderstood the RUN instruction
The RUN instruction will execute any commands in a new layer on top of
the current image and commit the results
It's used to build your image, it is not docker run which executes the command in the container.
The solutions involves to execute those 2 lines in the CMD or ENTRYPOINT with a shell script. uwsgi has also to be daemonized. Checkout this image https://github.com/tiangolo/uwsgi-nginx-docker
Related
I am attempting to build a simple app with Jenkins in a docker container. I have the following Dockerfile:
FROM ubuntu:trusty
# Install dependencies for Flask app.
RUN sudo apt-get update
RUN sudo apt-get install -y vim
RUN sudo apt-get install -y curl
RUN sudo apt-get install -y python3-pip
RUN pip3 install flask
# Install dependencies for Jenkins (Java).
# Install Java 1.8.
RUN sudo apt-get install -y python-software-properties debconf-utils
RUN sudo apt-get install -y software-properties-common
RUN sudo add-apt-repository -y ppa:webupd8team/java
RUN sudo apt-get update
RUN echo "oracle-java8-installer shared/accepted-oracle-license-v1-1 select true" | sudo debconf-set-selections
RUN sudo apt-get install -y oracle-java8-installer
# Install, start Jenkins.
RUN sudo apt-get install -y wget
RUN wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | apt-key add -
RUN echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list
RUN sudo apt-get update
RUN sudo apt-get install -y jenkins
RUN sudo /etc/init.d/jenkins start
COPY ./app /app
CMD ["python3","/app/main.py"]
I run this container with the following:
docker build -t jenkins_test .
docker run --name jenkins_test_container -tid -p 5000:5000 -p 8080:8080 jenkins_test:latest
I am able to start flask and install Jenkins, however, when running, Jenkins is not running. curl localhost:8080 is not successful.
In the log output, I am able to see:
Correct java version found
* Starting Jenkins Automation Server jenkins [ OK ]
However, it's still not running.
I can ssh into the container and manually run sudo /etc/init.d/jenkins start to start it, but I want it to start on docker run or docker build.
I have also tried putting sudo /etc/init.d/jenkins start in the CMD portion of the Docker file:
CMD python3 /app/main.py; sudo /etc/init.d/jenkins start
With this, I am able to curl Flask, but still not Jenkins.
How can I get Jenkins to start automatically?
You have some points that you need to be aware of:
No need to use sudo as the default user is root already.
In order to run multiple service in the same container you need to use any kind of service manager like Supervisord. Jenkins is not running because the CMD is the main entry point for your container so only flask should be running. Check the following link in order to know how to start multiple service in docker.
RUN will be executed only during the build process unlike CMD which will be executed each time you start a container from that image.
Combine all the RUN lines together as possible in order to minimize the build layers which lead to a smaller docker image.
Regarding the usage of this:
CMD python3 /app/main.py; sudo /etc/init.d/jenkins start
It does not work for you because this command python3 /app/main.py is not running as a background process so this command sudo /etc/init.d/jenkins start wont run until the previous command is done.
I was only able to get this to work by starting Jenkins in the CMD portion, but needed to start Jenkins before Flask since Flask would continuously run and the next command would never execute:
Did not work:
CMD python3 /app/main.py; sudo /etc/init.d/jenkins start
This did work:
CMD sudo /etc/init.d/jenkins start; python3 /app/main.py
EDIT:
I believe putting it in the RUN portion would not work because container would build but not save the any running services. I'm not sure if containers can be saved and loaded with running processes like that but I might be wrong. Would appreciate clarification if so.
It seems like a thing that should be in RUN so if anyone knows why that didn't work or some best practices, would also appreciate the info.
I have one dockerfile as below.
FROM centos:centos6
RUN yum install httpd* -y
RUN yum install mysql* -y
ENTRYPOINT service mysqld start && bash
ENTRYPOINT service httpd start && bash
Docker file running successful but when i enter into the container only one service is in start start that is httpd.
I want to start both the service automatically using dockerfile.
Please let us know how to do that
You should create a entrypoint.sh file:
#!/bin/bash
service mysqld start
service httpd start
And Dockerfile:
FROM centos:centos6
RUN yum install httpd* -y
RUN yum install mysql* -y
COPY ./entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
You also try to use supervisord in your docker image
I'm trying to start a service like Apache2 automatic inside a Docker container
My Dockerfile:
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get -y install apache2
ADD ./startup.sh /opt/startup.sh
RUN chmod +x /opt/startup.sh
CMD ["/bin/bash", "/opt/startup.sh"]
RUN /opt/startup.sh
My startup.sh:
#!/bin/bash
service apache2 start
But Apache2 isn't started automatic in the container.
Containers by themselves have no capability to start services in the traditional sense that you're used to, eg. by using upstart or systemd. So you just have to start apache manually...
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get -y install apache2
EXPOSE 80 443
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
Remember that when you start the container you will need to map the port correctly with the -p parameter. The dockerfile doesn't deal with any VOLUMES, this simply installs apache2 and starts it. If you need to understand how those work, you'll need to consult the Dockerfile Reference.
I have built an image using these steps:
download adminer package
wget https://www.adminer.org/static/download/4.2.4/adminer-4.2.4-en.php
mv adminer-4.2.4-en.php adminer.php
create docker file
vi dockerfile
FROM ubuntu
RUN apt-get -y install apache2 php5 php5-curl php5-cli php5-mysql php5-gd mysql-client mysql-server
RUN apt-get -y install postgresql postgresql-contrib
RUN apt-get -y install php5-pgsql
COPY adminer.php /var/www/html/
RUN chmod -R 777 /var/www/html/
build and run
docker build -t shantanuo/adminer1 .
docker run -i -t --rm -p 80:80 --name adminer1 shantanuo/adminer1
I need to run this command to start apache once I am inside the container.
sudo service apache2 start
How do I include this command in the dockerfile? (Build failed after adding CMD for this purpose.)
Is there any other (better) way of installing adminer.php package?
Is it possible to reduce the size of this image?
What you do is opening an interactive bash session and try to start a server.
It would be better if you started your same image in detached mode (-d) instead of -it, and let apache runs.
For that, as commented, you need to start FROM httpd:2.4 which:
has a Dockerfile starting by default apache
has a httpd-foreground scripts launching apache server in foreground.
Even better would be to use a PHP docker image:
FROM php:5.6-apache
That way, you don't even have to install apache or php. You just copy your php application.
Then, if you need to, you can still open a bash session with:
docker exec -it <yourContainer> bash
I'm building a Docker image with this Dockerfile
FROM ubuntu:12.04
ENV DEBIAN_FRONTEND noninteractive
ENV PATH /usr/local/rvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# update apt
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y dist-upgrade
RUN apt-get install -y beanstalkd
RUN sed -i 's/\#START=yes/START=yes/g' /etc/default/beanstalkd
EXPOSE 11300
ENTRYPOINT service beanstalkd start
The image is successfully built and then I want to create an instance:
docker run -i -d -p 11300:11300 beanstalk /bin/bash
However, when I do docker ps -a, the instance has status Exit 0. I'm assuming that this means that the instance is not running. When I try to start it or attach to it, nothing seems to be happening.
So the question is why is the container not running?
Thanks, Michal
With service beanstalkd start you are starting the server, and then exiting. You will want to run the program directly - ENTRYPOINT /usr/local/bin/beanstalkd -l 0.0.0.0 -p 11300 -b .... (etc)