Monday, February 13, 2023

Notes on Different Docker image tags

Full Images

These are images based on the most latest release of an operating system. For example, if you talking about the `python:latest` then this would be the most recent stable Debian OS release. These images are usually the one's we use at the start of a project.

The catch with these images is that they are usually pretty big. The latest python image clocks at around 4GB. If image size is not a concern then using these full images in production poses little risk.

Slim

Denoted by `-slim` in the tags are paired down images of the full image. These contain the barest minimum of packages to run your particular tool - ie. Python, nodejs, etc. 

The catch with these is that a lot of stuff, you might use will be not available and you need to test when using these type of images. You'll often stumble into errors like missing dependencies or libraries when using these.

Alpine

Unlike the full images that are based on Debian, alpine tag images are based on the Alpine Linux Project, which is an operating system made for containers. Using these images usually results in the smallest possible image.

The catch is that Alpine uses different stuff compared to Debian. For example, musl instead of glibc because of the size. That might break your app if it has certain requirements. 

Other tags like stretch/buster/jessie/bullseye

These images denote that they are using a certain version of Debian. For example, if the image is tagged buster then that image is using Debian 10.4, if jessie then that's Debian 8.

What to use then?

1. If for local development, use the full image. 

2. It also ok to use the full image for production if size is not an issue. Just don't use the latest tag because this always pulls the latest image and it might break your app's dependencies. 

3. Use slim instead of alpine. Alpine is cool and all but it's a pain to debug.




Wednesday, January 11, 2023

Notes for Setting up Django for ASGI with Gunicorn, Uvicorn, Docker and Websockets

Gunicorn is a robust web server that has monitoring and automatic restarts. Perfect for production deployments. 

Uvicorn is an ASGI server based on uvloop and httptools, with emphasis on speed. 

ASGI means Asynchronous Server Gateway Interface intended for async-capable Python web servers, frameworks and apps. The other side of the coin is WSGI. TL:DR: ASGI = asynchronous, WSGI=synchronous

Installing

$ pip install gunicorn uvicorn[standard]

Install unicorn[standard] if you are using websockets. Expect to do this if you are using django channels.


Running with Docker

I assuming that the base image is `python:latest`. The command should look like:

$ gunicorn my_project.asgi:application -b 0.0.0.0:8000 --reload -k uvicorn.workers.UvicornWorker 

This binds the ports. I'm also using a nginx service configured with an upstream service pointing to the 8000 port on my django app container.

Why not daphne server?

The daphne server doesn't support a reload function which is a pain for local web development. See: https://github.com/django/daphne/issues/9

Wednesday, December 21, 2022

Dumping and Restoring a DB from host into a Docker container or back

Assuming you have the sql (ie. backup.sql) file on hand:

To create a backup of a mysql DB (ie. dumping it):

$ docker exec CONTAINER_NAME /usr/bin/mysqldump -u root --password=root DATABASE > backup.sql

To restore a mysql dump (for example):

$ cat backup.sql | docker exec -i CONTAINER_NAME /usr/bin/mysql -u root --password=root DATABASE 

Add the --force or -f flag to ignore errors

$ cat backup.sql | docker exec -i CONTAINER_NAME /usr/bin/mysql -u root --password=root  --force DATABASE 

I tested this using the mysql 8.0 image. 


ref: https://stackoverflow.com/questions/46579381/how-to-restore-mysql-dump-from-host-to-docker-container