Docker Alpine for Django, DRF, UWSGi, Postgres and many more

I’m running a couple of project using docker as container engine. Most of them are python related project, which uses django, django rest framework, uwsgi, postgres and packages related to cryptography and much more.

Using the plain python:3 takes up a huge space, so i switched to python:3-alpine

with some problems in adding packages since they do not compile or run.

FROM python:3-alpine 
COPY requirements.txt . 
RUN set -e; \
 apk add --no-cache --virtual .build-deps \
 gcc \
 libc-dev \
 linux-headers \
 python3-dev \
 libffi-dev \
 openssl-dev \
 make \
 ; \
 apk add --no-cache postgresql-dev; \
 pip install --no-cache-dir uwsgi; \
 pip install --no-cache-dir -r requirements.txt; \
 apk del .build-deps; 


But I found a solution after wasting hours here and there..


  • that the postgresql-dev is not installed  as virtual.
  • If you want to have uwsgi use the internal routing (e.g., to avoid logs on health checks you have to install (not virtual)
    pcre pcre-dev

    and then use

     pip install --no-cache-dir -I uwsgi;

It install packages and then deletes them from the image. In the end the image is still pretty large 186MB but before it used to be around 7 times more .. (python:3 starts at ~690 MB).


Automated deployment of a docker on ECS 

ECS is nice, but has plenty of drawbacks (i’m using it since few weeks, and compared to kubernetes it’s a pain in that place..). Deploying a new release is one of the problem, you have to go to the website, add a new task, update the service and so on so forth.

Since I’m lazy and I hate wasting time for automated task, I created a script.

$(aws ecr get-login --no-include-email --region your_region )
docker build -t  your_pacakge .
docker tag your_pacakge your_ecs_repository_url/your_package
docker push your_ecs_repository_url
taskDef=$(aws ecs register-task-definition --cli-input-json file://ecs/task.json | jq -r '.taskDefinition.taskDefinitionArn')
aws ecs update-service --cluster  --service  --task-definition $taskDef 


  • the ecs/task.json is the json you get in the JSON tab when you create the task, copy that one and remove all the fields that have as value null.
  • it requires jq or you have to find a way to parse the output
  • the docker commands URL and TAGS are in the repository page of ecs, you can copy from them.

Similar approach works also with fabric , except the login part (fabric wraps shells, so command are executed one and not saved), thus execute the login in the console before running the fab command.

UWSGI avoid logs of health checks

Using UWSGI to run your app is handy, but it logs all the calls to all the urls. If you have a health check you end up having plenty of 200 calls in your log that can be distracting.

route = ^/health donotlog:

where /health (or part of it) is the healthcheck url. This will tell to uwsgi to do not post log at that url.

EDIT Just figured out that you need the pcre library compiled within uwsgi, here the solution SO question (for alpine you need apk install pcre pcre-dev)