Using Docker to develop and deploy Django apps
stavros.io
stavros.io
From my experience "deploying" containers is pretty easy: build the image, push the image, pull the image, start container. The hard parts are: how to deal with persistency (I decided to let RDS manage my database), how to centralize logging and monitoring (just Cloudwatch? Swarm? Kubernetes?), how to make sure the cluster is healthy at all times (e.g. a container crashes, is it being replaced? How long does it take?) and how to make sure you have the correct number of containers running (e.g. I want 2 containers for the app server, 3 as workers, 1 as load-balancer).
If you really think about it, once you remove these advantages (from using containers, that is) the difference between running a container and having a script that provisions a virtualenv and adds a supervisor/systemd/initd service is negligible.
If only it were easier to have seamless upgrades, it would be perfect.
Could you please clarify how do you do the deployment of a new version?
Not every commit to master is necessarily a deployment, right? So how do you trigger it?
How did you configure Captain Webhook to get the new image and replace the current one that was running?
Captain Webhook just restarts the service. The systemd service file looks like this, and auto-pulls on every restart: https://www.pastery.net/xrutdm/
I will update the post with the above, thank you.
I'm in a very similar situation as what you've got described, and I'll start in on that part of the project sometime in the next month or so.
Also been looking at Elastic Beanstalk for deployments. Have you looked at that yet?
I don't know how you'd communicate with nginx inside the container to tell it to switch, though, or how you would be able to know when all requests were done on the old container. Hopefully there's an easy way.
Too bad that a single SIGHUP becomes so complicated with containers, but I guess it's a tradeoff.
About the Beanstalk, I haven't looked into it too much, maybe that can help with deployment. I'd be grateful if you could let me know how it worked, if you ever try it out.
wat
> We have to do some contortions with the Django devserver, because Docker doesn’t care if Postgres is ready before starting the server, so Django sees that it can’t contact the database and quits. So, we just wait until port 5432 is ready before starting the devserver.
docker-compose starts all services simultaneously and doesn't want you to use an init system inside the container, which means that any dependency that requires a service to be actually available needs some sort of waiting hack.
# Remove the git repo to save space.
RUN rm -rf /code/.git
Pretty sure that it will not save any space because it will be in separate layer. If you want space to be saved to should be done as "one command".
RUN git clone ... /code/ && rm -rf /code/.git
Yes, the database can be in a container as well, with a persistent volume.
It's not that much more complex than what you just went through.
It supports rolling updates where one pod (this means container, usually) is updated at a time, with traffic being sent to other pods during that time.
I think the best practice right now is to use a Deployment (alternatively you can initiate a rolling update manually). Using a deployment makes updates as simple as "kubectl patch ...".
It does require a load balancer, which varies from platform to platform. In AWS, I assume it uses an ELB. On premise, you might use contrib/service-loadbalancer (haproxy).