I am learning docker. I want to practice how to see logs inside of a docker container once I run a python image.
This is the python code I want to execute:
#loop.py
#loop.py
import time
while True:
print('test')
time.sleep(3)
This is the docker file:
FROM python:3.8-slim-buster
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
COPY requirements.txt .
RUN python -m pip install -r requirements.txt
WORKDIR /app
COPY . /app
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
USER appuser
CMD ["python", "loop.py"]
I build the image like this:
docker build -t image_test .
Once it is created ( I can see it doing docker image ls) I want to run it, I have different ways but the container is created and is terminated instantly:
docker run <imageID>.
I have tried too:
docker docker run <imageID> sleep infinity. Then I can do: docker exec -it <containerID> bash and I can run inside the container python loop.py but it automatically ends.
I modified the CMD like this as well:
CMD ["python","-u", "loop.py"]
I have tried:
docker run -it --entrypoint=/bin/bash image_test and I directly go to the terminal inside of the container, but if I execute the python code as before, it automatically ends, instead of run the infinite loop.
why?
You don't need bash to run a python program. You can use it to exec into a running container. But the container will be running as long as the python is connected to the stdout.
I ran these commands and they all work on my machine.
sudo docker run image_test
sudo docker run -d image_test
sudo docker ps
sudo docker logs -f 041
sudo docker exec -ti 041 bash
sudo docker stop 041
sudo docker rm 041
Related
I have a Dockerfile:
FROM ubuntu:18.04
RUN apt-get -y update
RUN apt-get install -y software-properties-common
RUN add-apt-repository ppa:deadsnakes/ppa
RUN apt-get update -y
RUN apt-get install -y python3.7 build-essential python3-pip
RUN pip3 install --upgrade pip
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8
ENV FLASK_APP application.py
COPY . /app
WORKDIR /app
RUN pip3 install -r requirements.txt
EXPOSE 5000
ENTRYPOINT python3 -m flask run --host=0.0.0.0
But I want to also run python3 download.py before running the ENTRYPOINT. If I put it in here, and then build, then it executes here. I need it to execute only on ElasticBeanstalk.
How would I do that?
There's a pattern of using the Docker ENTRYPOINT to do first-time setup, and then launching the CMD. For example, you could write an entrypoint script like
#!/bin/sh
# Do the first-time setup
python3 download.py
# Run the CMD
exec "$#"
Since this is a shell script, you can include whatever logic or additional setup you need here.
In your Dockerfile, you need to change your ENTRYPOINT line to CMD, COPY in this script, and set it as the image's ENTRYPOINT.
...
COPY . /app
...
# If the script isn't already executable on the host
RUN chmod +x entrypoint.sh
# Must use JSON-array syntax
ENTRYPOINT ["/app/entrypoint.sh"]
# The same command as originally
CMD python3 -m flask run --host=0.0.0.0
If you want to debug this, since this setup honors the "command" part, you can run a one-off container that launches an interactive shell instead of the Flask process. This will still do the first-time setup, but then run the command from the docker run command instead of what was in the CMD line.
docker run --rm -it myimage bash
You can control whether you run the python3 download.py using environment variables. And then running locally you do docker run -e....
I am trying to setup my python environment in docker.
My docker image is like this:
FROM python:2.7
# updating repository
RUN apt-get update
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
COPY requirements.txt requirements.txt
RUN pip install --no-cache -r requirements.txt
EXPOSE 8888
COPY . .
CMD ["python", "test.py"]
with this build command:
docker build -t ml-python-2.7 .
After image is built,
I ran
docker run -it --name ml-container -v ${PWD}:/usr/src/app ml-python-2.7 python test.py
My sample test.py
print('test here')
It works when I first run this command and update the output every time I changed my test.py
The problem is if I want to keep the container and remove the --rm option, the container quit and I can't run
docker run -it --name ml-container -v ${PWD}:/usr/src/app ml-python-2.7 python test.py
anymore because it says there is a container name conflict. How do I keep the container and run the test.py again after that file is updated? Thanks!
After the container has exited, you can start it again using docker start. More information here: How to continue a docker which is exited
I am trying to setup my python environment in docker.
My docker image is like this:
FROM python:2.7
# updating repository
RUN apt-get update
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
COPY requirements.txt requirements.txt
RUN pip install --no-cache -r requirements.txt
EXPOSE 8888
COPY . .
CMD ["python", "test.py"]
with this build command:
docker build -t ml-python-2.7 .
After image is built,
I ran
docker run -it --rm --name ml-container ml-python-2.7 python test.py
My sample test.py
print('test here')
It works when I first run this command.
docker run -it --rm --name ml-container ml-python-2.7 python test.py
but after I change the test.py to print('second test')
and run the above command again, it still output test here.
How do I make sure it updates automatically or if there is more elegant way to do this?
Thanks!
Docker does not store the changes you are making to files inside the container unless you commit it. If you want it to do so, you need to do a Docker Commit like:
docker commit <CONTAINER NAME HERE>
Or you could mount a local folder to the docker image like this:
docker run -ti -v ~/folder_in_host:/var/log/folder_in_container <IMAGE NAME HERE>
I've been following the flask megatutorial by the inestimable Miguel Grinberg (https://learn.miguelgrinberg.com/read/mega-tutorial/ch19.html), and recently hit on a snag in deployment.
The docker run command starts the container and then it immediately stops. It isn't showing up in docker ps -a either. I've trawled through lots of responses here which seem to suggest that the solution is to add "-it" to the docker run command however this does not solve the issue.
Here's my dockerfile:
FROM python:3.6-alpine
RUN adduser -D james
WORKDIR /home/myflix
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install -r requirements.txt
RUN venv/bin/pip install gunicorn pymysql
COPY app app
COPY migrations migrations
COPY myflix.py config.py boot.sh ./
RUN chmod +x boot.sh
ENV FLASK_APP myflix.py
RUN chown -R james:james ./
USER james
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]
My image is called myflix:secondattempt.
The command used to start the container:
sudo docker run --name myflixcont -d -p 8000:5000 --rm myflix:secondattempt
As I said, I've already tried dropping in various combinations of "-i" and "-t" in front of the "-d" to no avail.
-it means interactive tty.
You can not use -it in conjunction with -d which means detached.
Remove -d and add -it:
docker run --name myflixcont -it -p 8000:5000 --rm myflix:secondattempt
Another point (with the purpose of helping you) is that ENTRYPOINT runs in exec mode. meaning that it does not start a bash or dash itself. You should specify it manually and explicitly:
ENTRYPOINT ["sh", "file.sh"]
# or
ENTRYPOINT ["bash", "file.sh"]
Is docker binaries not available within docker? If so, how could I call it within docker?
app.py
import subprocess
cmd_payload = ['docker']
subprocess.Popen(cmd_payload, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Dockerfile
FROM python:2.7-slim
VOLUME /data
WORKDIR /data
ADD . /data
CMD ["python", "app.py"]
Then, run
docker build -t app .
docker run app
OUTOUT:
[Errno 2] No such file or directory
EDIT:
if i change
cmd_payload = ['docker']
to
cmd_payload = ['echo']
it doesnt throw an error. I would like to run docker executable . How could i do that?
If you want to run docker within of a container, the easy way to reach that is share docker daemon by volumes, Re-run your docker container with this:
docker run -it -v /var/run/docker.sock:/var/run/docker.sock:ro -v /usr/bin/docker:/usr/bin/docker:ro app
Moreover you have to add the library to Dockerfile
FROM python:2.7-slim
RUN apt-get update && apt-get install -y libltdl7 && rm -rf /var/lib/apt/lists/*
VOLUME /data
WORKDIR /data
ADD . /data
CMD ["python", "app.py"]
subprocess was able to run docker executable by adding shell=True
cmd_payload = 'docker'
subprocess.Popen(cmd_payload, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
Not sure why it couldnt find it if not invoked under a shell