Using Docker to install gunicorn, I am unable to to use the gunicorn command.
To start Django, I have this line in my docker-compose.yaml:
command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn myproject.wsgi -b 0.0.0.0:8000"
This results in bash: gunicorn: command not found
When I build the Docker images it says gunicorn has been successfully installed.
My Dockerfile looks like:
FROM python:3.5
ENV PYTHONUNBUFFERED 1
RUN mkdir /config
ADD requirements.txt /config/
RUN pip install -r /config/requirements.txt
RUN mkdir /src;
WORKDIR /src
I've been using this http://ruddra.com/2016/08/14/docker-django-nginx-postgres/ as a guide.
If you are finding that gunicorn doesn't exist it could be because
docker image may use a cached layer of the requirements.txt which doesn't have gunicorn in it as a dependency.
Therefore it will result in not installing gunicorn meanwhile specifying pip install gunicorn in a seperate RUN command will work.
Solution:
Build docker image without caching when edits have been made to requirements.txt
docker build --no-cache .
Related
Docker project was created on Linux machine, I'm running windows and I can't get docker-compose up to work. I've read through Stackoverflow's answers and so far I've tried the following (none have worked):
Using Visual Studio Code I saved as "LF" instead of CRLF
Deleted the file entirely, created a new one using Visual Studio Code, typed the words
Cut the entire file, pasted it in Notepad so that formatting gets cleared, copied and pasted back
Added various forms of #!/bin/bash to the start of the entrypoint.sh
Changed Docker File to use COPY instead of ADD
At this point I'm not sure what else to try. Any ideas?
Edit
entrypoint.sh
if [ "$1" == 'celery' ]; then
celery -A vicmun worker -l info --uid=celery --gid=celery
else
./../wait_for_it.sh db:5433 --timeout=10
python manage.py migrate
python manage.py runserver 0.0.0.0:8000
fi
Dockerfile
FROM python:3.9
ENV PYTHONUNBUFFERED 1
ARG APP_ENV=${APP_ENV}
RUN mkdir /src
RUN mkdir /static
WORKDIR /src
ADD ./src /src
ADD entrypoint-${APP_ENV}.sh /entrypoint.sh
ADD wait_for_it.sh /wait_for_it.sh
RUN addgroup --system celery && adduser --system --ingroup celery celery
RUN ["chmod", "+x", "/wait_for_it.sh"]
RUN apt-get -y update
RUN apt-get -y install ffmpeg
RUN pip install -r requirements.txt
ENTRYPOINT ["bash", "/entrypoint.sh"]
I don't know your config, but I could resolve that problem by adding in the CMD.
In my case, I could execute a script with docker as follows:
Dockerfile
FROM python:3.10-alpine3.15
ENV PYTHONUNBUFFERED=1
WORKDIR /app
RUN apk update \
&& apk add --no-cache gcc musl-dev postgresql-dev python3-dev libffi-dev \
&& pip install --upgrade pip
COPY requirements.txt .
RUN python -m pip install -r requirements.txt
COPY . .
CMD [ "sh", "entrypoint.sh" ]
entrypoint.sh
#!/bin/sh
python manage.py makemigrations
python manage.py migrate
python manage.py runserver 0.0.0.0:8000
Well, I feel the cringe for this. Turns out the solution was something I had already done, but it didn't go through until I rebuilt with --no-cache option.
Solution was to:
Using Visual Studio Code I saved as "LF" instead of CRLF
and run docker-compose build --no-cache
I have been running an app without docker and have just added in Dockerfile and docker-compose.
The issue I am having is that after I successfuly build the app, runserver produces the below error when I run either that or migrate.
➜ app git:(master) sudo docker-compose run app sh -c "python manage.py runserver"
Error loading shared library libpython3.8.so.1.0: No such file or directory (needed by /usr/local/bin/python)
Error relocating /usr/local/bin/python: Py_BytesMain: symbol not found
failed to resize tty, using default size
%
➜ app git:(master) sudo docker-compose run app sh -c "python manage.py migrate"
Error loading shared library libpython3.8.so.1.0: No such file or directory (needed by /usr/local/bin/python)
Error relocating /usr/local/bin/python: Py_BytesMain: symbol not found
Dockerfile
FROM python:3.8-alpine
MAINTAINER realize-sec
ENV PYTHONUNBUFFERED 1
COPY requirements.txt /requirements.txt
RUN pip install -r requirements.txt
RUN mkdir /app
WORKDIR /app
COPY ./app /app
RUN adduser -D user
USER user
docker-compose.yml
version: "3"
services:
app:
build:
context: ""
ports:
- "8000:8000"
volumes:
- ./app:/app
command: >
sh -c "python manage.py runserver 0.0.0.0:8000"
What am I doing wrong that is causing this?
When I run without docker using python3 manage.py runserver it works fine.
Because I haven’t tested the build, I don’t know whether any of these things will help you to ultimately build your containers, however here are some observations to hopefully set you on the right path.
Your context is a null string and is usually a dot (.)
You typically finish the Dockerfile with the following command:
CMD [ "python3", "manage.py", "runserver", "0.0.0.0:8000" ]
So you can remove that from your compose file.
Other than that, on a more general note, although Alpine images are small, they are prone to breaking because of the additional dependencies and packages that you need to add/remove. You’re probably better off with going for the slim version overall. The original build will take a bit longer but it will be more manageable.
Also, if you’re running a modern version of Docker on your machine, then you can move the syntax version of the compose file to version 3.7 or 3.8, depending upon your version of Docker.
I created simple project in Django with docker. According to heroku's documentation about release phase with container registry (https://devcenter.heroku.com/articles/container-registry-and-runtime#release-phase) I created a new app with postgres addon. To deploy app with docker I executed following commands:
heroku container:push web
heroku container:push release
heroku container:release web release
But after last command my terminal is blocked and it looks like release phase actually run a container.
Releasing images web,release to teleagh... done
Running release command...
[2019-12-30 21:22:00 +0000] [17] [INFO] Starting gunicorn 19.9.0
[2019-12-30 21:22:00 +0000] [17] [INFO] Listening at: http://0.0.0.0:5519 (17)
[2019-12-30 21:22:00 +0000] [17] [INFO] Using worker: sync
[2019-12-30 21:22:00 +0000] [27] [INFO] Booting worker with pid: 27
My goal is tu run django migrations before release. I would really apreciate any help.
Procfile:
release: python manage.py migrate
Dockerfile:
FROM python:3.7-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT=8000
WORKDIR /app
ADD requirements.txt .
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y curl
ADD . ./
RUN python manage.py collectstatic --noinput
CMD gunicorn --bind 0.0.0.0:$PORT teleagh.wsgi
Procfile does not make effect when container deploy is used in heroku. If you want to set release phase command I can suggest two options that I have tested a lot:
1. Create dedicated Dockerfile for each phase with extensions matching the phase name.
Dockerfile.web
FROM python:3.7-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT=8000
WORKDIR /app
ADD requirements.txt .
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y curl
ADD . ./
RUN python manage.py collectstatic --noinput
CMD gunicorn --bind 0.0.0.0:$PORT teleagh.wsgi
Dockerfile.release
FROM python:3.7-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT=8000
WORKDIR /app
ADD requirements.txt .
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y curl
ADD . ./
RUN python manage.py collectstatic --noinput
CMD python manage.py migrate
The deploying process will be looking the same like yours with one exception — push command must have additional argument --recursive. Moreover it is possible to push all containers in one command:
heroku container:push web release --recursive
heroku container:release web release
2. Create a bash script to detect what phase is running in the container at the moment.
start.sh
#!/bin/bash
if [ -z "$SSH_CLIENT" ] && [ -n "$HEROKU_EXEC_URL" ];
then
source <(curl --fail --retry 3 -sSL "$HEROKU_EXEC_URL")
fi
if [[ "$DYNO" =~ ^release.* ]];
then
set -e
python3 manage.py migrate
else
exec gunicorn teleagh.wsgi -b 0.0.0.0:${PORT} --reload --access-logfile -
fi
Then the only Dockerfile will be looking like:
FROM python:3.7-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT=8000
WORKDIR /app
ADD requirements.txt .
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y curl
ADD . ./
RUN python manage.py collectstatic --noinput
CMD ./start.sh
Hope this will be helpful
You can add a release phase to the heroku.yml file.
ex.
build:
...
release:
command:
- rake db:migrate
run:
web: bundle exec puma -C config/puma.rb
Source
I am using jenkins for continuous integration from gitlab and continuous deployment. My "execute shell" consist of the following commands .
#!/bin/bash
source /my_env/bin/activate # Activate the virtualenv
cd /var/lib/jenkins/workspace/Operations_central
#pip install -r requirements.txt # Install or upgrade dependencies
python manage.py makemigrations
python manage.py migrate # Apply South's database
sudo service nginx restart
fuser -n tcp -k 8088
gunicorn applicationfile.wsgi:application --bind=myserverip:portno`
I'm trying to create docker container with my application, that works good on local machine and production server. But when I create docker container with my project I see only "It worked" page instead of my project!
FROM python:2.7
MAINTAINER Name name <mail#gmail.com>
ENV PYTHONUNBUFFERED 1
ENV DJANGO_SETTINGS_MODULE lms.settings
RUN ls -la /
RUN mkdir /lms/
WORKDIR /lms/
RUN pip install six Django==1.5.12 numpy python-dateutil Pillow django-colorful gunicorn south djangorestframework djangorestframework-jsonp simplejson psutil
ADD . /lms/
RUN (cd /lms/ && python manage.py syncdb --noinput)
RUN (cd /lms/ && python manage.py collectstatic --noinput)
RUN ls -la /lms/
RUN cd /lms/
CMD gunicorn --env DJANGO_SETTINGS_MODULE=lms.settings lms.wsgi --pythonpath '/lms/' --bind 0.0.0.0:8000
You should modify your Dockerfile like this
FROM python:2.7
MAINTAINER Name name <mail#gmail.com>
ENV PYTHONUNBUFFERED 1
ENV DJANGO_SETTINGS_MODULE lms.settings
RUN ls -la /
RUN mkdir /lms
WORKDIR /lms
RUN pip install six Django==1.5.12 numpy python-dateutil Pillow django-colorful gunicorn south djangorestframework djangorestframework-jsonp simplejson psutil
ADD . /lms
RUN python manage.py syncdb --noinput
RUN python manage.py collectstatic --noinput
RUN ls -la
CMD gunicorn --env DJANGO_SETTINGS_MODULE=lms.settings lms.wsgi --pythonpath '/lms/' --bind 0.0.0.0:8000`
See the doc for WORKDIR
https://docs.docker.com/reference/builder/#workdir
and this "best practices"
https://docs.docker.com/articles/dockerfile_best-practices/
When you RUN cd /lms it executes the cd and exits, so the next command is not in /lms and also, do not put a / at the end of your directory when you specify the WORKDIR, as you had twice WORDKIR, your default directory was /lms/lms I guess