Sean Quinn
Sean Quinn

Reputation: 2161

Why does uWSGI fail to start in Docker?

I am relatively new to using uWSGI to serve Python applications and I am attempting to start a uWSGI process in emperor mode with a vassal, but every time I try to start uWSGI inside of Docker with the following command (as root):

# /usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini

What I get as a response is:

[uWSGI] getting INI configuration from /etc/uwsgi/emperor.ini
2.0.13.1

The emperor.ini configuration file looks like:

# files/etc/uwsgi/emperor.ini
[uwsgi]
emperor = /etc/uwsgi/apps-enabled
die-on-term = true
log-date = true

While the only vassal's configuration looks like:

# files/etc/uwsgi/apps-enabled/application.ini
[uwsgi]
app_dir = /var/www/server
plugin = python
master = true
callable = app
chdir = %(app_dir)
mount = /=%(app_dir)/start.py
protocol = uwsgi
socket = :8079
uid = www-data
gid = www-data

buffer-size = 32768
enable-threads = true
single-interpreter = true
processes = 1

stats = 127.0.0.1:1717

(NB: The filenames above are given in terms of where they live relative to the Dockerfile which will then copy them to the correct locations, basically removing the prefix files)

Currently the uWSGI Docker image I'm using is built off of an ubuntu:trusty base image (though I've tried ubuntu:latest and alpine:latest and encountered the same problem), and although I am attempting to launch the uWSGI process with supervisor, as stated previously, it also fails when run directly from the command line. In the Docker image I'm installing uWSGI using pip but have also tried using apt-get with the same result.

I should also mention that I've tried different versions of uWSGI 2.0.13.1 and 1.9.something with the same result, if that helps.

# Dockerfile
FROM ubuntu:trusty
MAINTAINER Sean Quinn "[email protected]"

RUN apt-get update \
 && apt-get install -y \
      ack-grep git nano \
      supervisor \
      build-essential gcc python python-dev python-pip

RUN sed -i 's/^\(\[supervisord\]\)$/\1\nnodaemon=true/' /etc/supervisor/supervisord.conf \
 && sed -i 's/^\(\[supervisord\]\)$/\1\nloglevel=debug/' /etc/supervisor/supervisord.conf \
 && sed -i 's/^\(files = .*\)$/;\1/' /etc/supervisor/supervisord.conf \
 && sed -i 's/^\(\[include\]\)$/\1\nfiles = \/etc\/supervisor\/conf.d\/*.conf/' /etc/supervisor/supervisord.conf

ENV UWSGI_VERSION 2.0.13.1

RUN pip install uwsgi==${UWSGI_VERSION}

RUN mkdir -p /etc/uwsgi \
 && mkdir -p /etc/uwsgi/apps-available \
 && mkdir -p /etc/uwsgi/apps-enabled \
 && mkdir -p /var/log/uwsgi

COPY files/etc/supervisor/conf.d/uwsgi.conf /etc/supervisor/conf.d/uwsgi.conf
COPY files/etc/uwsgi/emperor.ini /etc/uwsgi/emperor.ini

VOLUME /etc/uwsgi/apps-enabled
VOLUME /var/www

ENTRYPOINT ["/usr/bin/supervisord"]
CMD ["-c", "/etc/supervisor/supervisord.conf"]

As mentioned, the supervisord process attempts to launch the uWSGI process using the following supervisor configuration.

# files/etc/supervisor/conf.d/uwsgi.conf
[program:uwsgi]
command=/usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
user=root

The application Python files are mounted in a subdirectory of /var/www and the application uWSGI configuration is mounted into /etc/uwsgi/apps-enabled.

The bizarre thing is, if I install supervisor and uWSGI on a new Ubuntu VM (outside of Docker) with all of the configuration and files in place I can see uWSGI properly process the emperor.ini and read the vassal .ini files. I haven't yet attempted to add nginx into the equation because I want to make sure uWSGI is starting and reading configuration files correctly first and foremost.

Is there any way to increase the logging or ascertain why I'm only seeing what appears to be the version number of the uWSGI binary? It's like the uWSGI process is completely ignoring command line options. I feel like I'm missing something that should be obvious.

Thanks in advance for any help anyone can give!

Upvotes: 2

Views: 2503

Answers (1)

Sean Quinn
Sean Quinn

Reputation: 2161

tl;dr don't use UWSGI_VERSION as an environment variable, apparently it forces uWSGI to only print the version number instead of start?

I believe I solved my own issue!

After experimenting with other uWSGI images on Docker's hub, I found that they were also running into the same issue so I began to look further into possible configuration issues. I tried changing permissions among other things.

I noticed however that when I used jpetazzo/nsenter to enter the running container that I saw uWSGI start (rather than simply output the uWSGI version information as highlighted above). When entering using docker exec, uWSGI would only print the version information. After playing around a bit more, I discovered that issuing the command su - from within the container launched using docker exec I again saw uWSGI start.

After some inspection, I discovered several differences in the environment variables between the root user in one shell vs. another. It led me to the UWSGI_VERSION environment variable, which appears to have been the culprit because removing UWSGI_VERSION allowed uWSGI to start.

I modified my Dockerfile to use UWSGI_PIP_VERSION instead as the environment variable to indicate the version of uWSGI to install, which seems to be a safe alternative to UWSGI_VERSION. YMMV.

Upvotes: 3

Related Questions