Docker basics

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the containerization category.

Last Updated: 2024-12-03

Warning: This are WIP notes. Don't take this document in its current form too seriously

I started working on an existing php project which was fully dockerized locally. Unfortunately it was a black box to me, so this was my process of figuring out how Docker worked (generally and in this project)

Telltale files in a dockerized project

There are often two Docker related files in the root directory:

Docker CLI

Container

Images

Deleting stuff for blank-slate tests and debugging

docker rm -vf $(docker ps -aq) # containers
docker rmi -f $(docker images -aq) # images

How to create your own image

Let's say you did a lot of manual tweaking inside a docker container. From outside this container you can run docker commit your_container_id and then your system will be persisted exactly as is. This is not considered a best practice, but can be very handy for quick and dirty deploys (e.g. prototypes).

Later you can boot this up with docker run your_new_image_id.

Interactivity

Let's say you want to run a shell:

$ docker container run alpine /bin/sh

This version just exists immediately. Instead you have to add interactivity and attach a tty:

$ docker container run -it alpine /bin/sh

You will now be in the shell of the container, as you can confirm with uname -a

See history of what you've run

Containers that finished executing are hidden when you type docker container ls but they show up if you write docker container ls -a

Volumes

How to use current folder within docker container

docker run -it --rm -v $(pwd):/usr/src/project tensorflow/tensorflow bash

Now when you visit /usr/src/project it will have everything you need from the current folder.

Networking

Advanced Networking Details

Titbit on how Docker workers:

Docker Compose

Here's how to interpret part of the docker-composer.yml file:

 #MySQL Service
  db:
    image: mysql:5.7.22
    container_name: db
   restart: unless-stopped
   tty: true
   ports:
     - "4306:3306"
   environment:
     MYSQL_DATABASE: laravel
     MYSQL_ROOT_PASSWORD: your_mysql_root_password
   volumes:
     - dbdata:/var/lib/mysql/
     - ./mysql/my.cnf:/etc/mysql/my.cnf
   networks:
     - app-network

  # App service
  app:
    build:
      context: .
      dockerfile: Dockerfile

Volumes in Docker COmposer

services:
   wordpress:
    volumes:
      # enter name and corresponding directory on first container
      - project_p:/var/www/html

   wordpress_cli:
    volumes:
      # enter name and corresponding directory on second container
      - project_p:/var/www/html
    # specify order
    depends_on:
      - wordpress

# then declare volume generally
volumes:
  project_p:

How to set up development environments that vary from production?

How to copy a file out of a docker instance into home machine

docker cp <containerid>:/<path> <host-path>

get the container ID with $ docker container ls

then carry out with copy with something like:

docker container cp  267a3ee553e2:/var/www/html/wp-content/ .

Dockerfile

ADD command and URLs

The Add command accepts URLs

This is better than curling since, if you curl into docker, some ways of using volumes delete the file immediately. Also, curl (the package) might not be available.

# this works
ADD https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar /usr/local/bin/wp

# this does not
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp # ERROR: File not found

References