Red Hat
Red Hat

Reputation: 7

How to run python script in docker container?

For some reason unknown to me section CMD does not work, but if I run the script by going into the container, it works.

FROM ubuntu:20.04
RUN mkdir /home/bob
WORKDIR /home/bob
RUN apt-get install -y python3 python3-pip
RUN echo "pyodbc" > /tmp/req.txt
RUN pip3 install -r /tmp/req.txt
# Will attached to /home/bob/folder1 in container (folder0 contain files and folder with test1 name)
ADD ./folder0 ./folder1
RUN chmod ug+x /home/bob/test1
CMD [python3 /home/bob/test1/bin/start.py &> /home/bob/test1/status.log]
# CMD tail -f /tmp/req.txt

What am I doing wrong? ps: just started learning docker

Upvotes: 0

Views: 8104

Answers (2)

David Maze
David Maze

Reputation: 158908

Syntactically, CMD can have two forms. The exec form must be a JSON array, with individual words double-quoted; you are responsible for breaking the command into words, and you cannot use shell forms like redirection. The shell form does not have extra punctuation and implicitly wraps its command in sh -c, but can use all shell features. (These links are to ENTRYPOINT examples but the same syntax works for CMD and also RUN.) Your example has square brackets, like the exec form, but not double-quotes; you should just remove those.

Stylistically, remember that a Docker image has an isolated filesystem. You generally will want to build a working Python application on the host and then package it in a container; so use the requirements.txt file from running pip freeze on the host, rather than trying to rebuild it from scratch in the Dockerfile. Similarly, since the image is isolated, it doesn't usually make sense to have a "home directory", and since the container will also have an isolated filesystem, it doesn't make sense to capture the process's output to a file in the container that will be hard to read later.

I'd rewrite this Dockerfile as:

# Use the standard Docker Hub Python image, rather than installing
# Python on an Ubuntu image.  (You may have a specific requirement
# to use specific base images.)
FROM python:3.9

# Use a short directory name.  Don't make it look like a user's home
# directory.  This will automatically create the directory for you.
WORKDIR /app

# Install Python package dependencies.  The base image will already
# have pip installed.  Do this as a separate step, so that it can
# be cached on rebuild if the requirements.txt file hasn't changed.
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy the rest of the application in.  You can rename things here if
# you really need to, but it can lead to confusing differences between
# your development environment and the deployed application.
COPY . .

# The main script should be executable on the host system (run
# `chmod +x start.py`) and start with a shebang line
# #!/usr/bin/env python3
# so you should be able to just
CMD ./start.py
# without any redirections or any special punctuation

If you just docker run the built image, it will print its output to stdout; if you docker run -d the image in the background, docker logs will be able to retrieve its logs.

Upvotes: 1

Antonio Petricca
Antonio Petricca

Reputation: 11026

Write a script named start.sh like this:

python3 /home/bob/test1/bin/start.py &> /home/bob/test1/status.log

Then update your docker file as follow:

FROM ubuntu:20.04

RUN mkdir /home/bob
WORKDIR /home/bob

RUN apt-get install -y python3 python3-pip
RUN echo "pyodbc" > /tmp/req.txt
RUN pip3 install -r /tmp/req.txt

# Will attached to /home/bob/folder1 in container (folder0 contain files and folder with test1 name)

ADD ./folder0 ./folder1
RUN chmod ug+x /home/bob/test1

COPY start.sh .
RUN chmod a+x start.sh

CMD ./start.sh

Upvotes: 1

Related Questions