Deploying your Django API in one Docker Container in AWS

Docker is a wonderful technology revolutionazing how to run microservices. You may have some experience with it or may not. I will show in this short post how to run a Docker container in Amazon Web Services(EC2) with your whole API in it. This trick is only useful for APIs or django projects that doesn't need to scale and doesn't really have too much traffic.

Requirements:

  1. Install Docker in your machine
  2. Install Docker Machine too
  3. Have an account in AWS
  4. Have amazonec2-access-key, amazonec2-secret-key and amazonec2-vpc-id
  5. Follow the post

Let's begin.

We will use our cityprj so we can have the whole thing there. Again, it is not a good idea for a big project because you will want to have configuration information that is needed for deployment and it is a project really for IT(ops) instead of developers but it will be a good exercise and we can launch a mock of our service right away and start to receive feedback.

We will have nginx, supervisor and code in our container.

Create a folder called docker inside de project.

mkdir docker

Inside the previous created folder  create a file called cities.conf with the following code:

[supervisord]
nodaemon = true

[program:nginx]
command = /usr/sbin/nginx
startsecs = 15
#stdout_events_enabled = true
#stderr_events_enabled = true

[program:app-gunicorn]
command = gunicorn -w 2 -b 127.0.0.1:8000 -n cities citiesprj.wsgi:application --log-level=debug
--chdir=/citiesprj
stdout_events_enabled = true
stderr_events_enabled = true

Also we need the nginx conf.

Create another file calledj dango-nginx.conf with the following info:

server {
listen 80;
server_name yourdomain.com;

access_log /var/log/cities-nginx-access.log;
error_log /var/log/cities-nginx-error.log;

location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /static/ {
alias /var/www/html/media/cities/static/;
}
}

Remember to change the name of server_name to correspond with your domain or subdomain for the API.

Now is time for the dockerfile. Create the file Dockerfile with the following info:

FROM nginx
MAINTAINER Edilio Gallardo, edilio73@gmail.com

RUN apt-get update

RUN apt-get install -y git vim python python-pip supervisor

RUN git clone https://github.com/edilio/citiesprj.git

RUN echo "DEBUG=1" > /citiesprj/.env
RUN cd /citiesprj && pip install -r requirements/python/base.txt
RUN cd /citiesprj && ./manage.py collectstatic --noinput
RUN cd /citiesprj && gunicorn -w 2 -b 127.0.0.1:8000 -n cities citiesprj.wsgi:application &

COPY django-nginx.conf /etc/nginx/conf.d/default.conf

# restart nginx to load the config
RUN service nginx stop

COPY cities.conf /etc/supervisor/supervisord.conf
# start supervisor to run our wsgi server
CMD /usr/bin/supervisord -c /etc/supervisor/supervisord.conf

If our Docker Machine and docker were correctly install we could do:

> docker-machine create --driver amazonec2 --amazonec2-access-key <ACCESS-KEY> --amazonec2-secret-key <ACCESS-PASSWORD> --amazonec2-vpc-id <VPC_ID> citiesaws

Replacing <ACCESS-KEY>, <ACCESS-PASSWORD>, <VPC_ID> with your values and it should create a virtual machine in AWs called citiesaws.

eval "$(docker-machine env citiesaws)"
docker build -t cities .
docker run -d -p 80:80 --name cities cities

You should be ready for checking your VM IP in your browser and the site should be up.

You can go the admin and use user dev password guessdev1 in order to login.

The urls availbale are:

  1. /admin/
  2. /api/v1/cities/cities/
  3. /api/v1/docs

Admin for cities

Admin2 for cities

Browsable API

Swagger Docs

Currently unrated