[ JagoPG Site ]
This publication is more than a year old. The information can be out-dated.

Helpful Docker recipes

I think is one of the tools that most appreciate for keeping a clean development machine. In the past, I could have several databases installed as native apps in my computer. These led to store a ton of rubbish and temporal files in my computer, so I had to be searching for each database application that I used the location it installed everything. This is just an example, a similar thing could happen with webservers.

A solution was to use a virtual machine to store these applications. But I had to be opening a specific virtual machine each time I wanted to use a certain app. In addition, the use of disk increased because for each new tool I wanted to try I had to clone a virtual machine.

Docker, at least in MacOS, is a similar approach but easier. You still have your applications in a virtual environment, but at least is more elegant in the appearance. It's running in background, and I can run everything from terminal, which for me is more confortable.

But the aim of these post is not to analyse the pros and cons of this application, which you should have I try if you have not. In this post I am sharing some small recipes that make my life easier. The scripts are not rocket science, but I do not like to write more than once the same script, or rewrite a recipe in a different computer.

Starting MariaDB or MySQL

Depending on the database engine that you prefer, modify the name of the image from the script. The variables that they use are the same, so there is no need to modify them.

docker container run \
  --name mariadb-5 \
  -e MYSQL_ALLOW_EMPTY_PASSWORD=yes \
  -p 3306:3306 \
  -v /Users/<YOUR_USER>/Developer/mariadb:/var/lib/mysql \
  -d \
  mariadb:5.5.56

Wordpress site running on Apache

These will be two recipes: one for creating an image with a Wordpress application and serve it from Apache webserver; other for declaring two services, the previous created image and a database:

# Dockerfile
FROM php:7.4.2-apache

RUN mv "/usr/local/etc/php/php.ini-production" "/usr/local/etc/php/php.ini"
RUN cp "/usr/local/etc/php/php.ini" "/etc/php.ini"
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mysqli
RUN rm -r /var/www/html && mkdir -p /var/www
RUN echo 'hello world!' > /var/hello.txt
# Docker Compose
version: '3'
services:
  web:
    build: .
    ports:
      - "8080:80"
    volumes:
      - /Users/YOUR_USER/Developer/project:/var/www/html
    networks:
      - my_custom_network
  mysql:
    image: mysql:5.7
    ports:
      - "3306:3306"
    volumes:
      - /Users/<YOUR_USER>/Developer/mysql:/var/lib/mysql
    networks:
      - my_custom_network
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD=yes
networks:
  my_custom_network:

JS Web application running on Python framework

I will implement this recipe with Django, but the only lines that would be different are the tasks regarding to the specific framework. In this. Case, the tasks that are in the last RUN.

A proposal to improve this recipe is divide the image creation in two phases: the first to compile the JS and SCSS assets, so the image can be lighter.

FROM python:3.7-alpine

LABEL author "Your amazing name"
LABEL email "your_email@example.com"

RUN \
  apk update && \
  apk upgrade && \
  apk --no-cache add \
  nodejs \
  nodejs-npm \
  mariadb-dev \
  build-base \
  gettext \
  libffi \
  libffi-dev \
  zlib \
  py3-pillow \
  jpeg \
  tiff \
  freetype \
  jpeg-dev \
  zlib-dev

RUN mkdir -p /var/shared /var/app
COPY ./app /var/app
WORKDIR /var/app

RUN \
  npm install && npm run build:prod && \
  rm -rf node_modules

RUN pip install -r requirements.txt
RUN \
  python manage.py collectstatic --no-input && \
  ln -s /var/app/website/templates/website/images /var/app/website/static/front/images && \
  ln -s /var/shared/media /var/app/website/media

CMD python manage.py migrate && python manage.py runserver 0.0.0.0:8000

Delete all images with a name

Deletes all images that have a certain name: the latest image and its tags will be removed.

#!/usr/bin/env bash

if [[ "$#" != "1" ]]; then
  echo "usage: $0 <IMAGE_NAME>"
  exit 1
fi

imageName=$1
docker images \
        | grep $imageName \
        | tr -s ' ' \
        | cut -d ' ' -f 2 \
        | xargs -I {} docker rmi "$imageName:{}"

Delete all non-references images

When building several times a new image, the old ones are stored and de-referenced if they are not tagged. For deleting all these unreferenced images you can alias the following command:

docker image ls -f dangling=true -q | xargs docker image rm