Docker introduction
Docker Image and Container concepts
An image is typically a layered operating system file, such as Alpine Linux, which is a commonly used OS used with Docker. Images are downloaded.
A container is a build of the image with a defined configuration. Containers are run.
Docker Compose allows multiple containers to run.
Dockerfile
Dockerfile defines image to build, operating system, configuration. Note capital D.
docker-compose.yml can orchestrate containers
Dockertoolbox is legacy
Getting started
Install Docker
Preferably on a Linux based system. Ive had success on Debian, Windows WSL2 subsystem (Ubuntu), and Mac OS (Intel CPU). Running natively on Windows I can't recommend. Ive read that there is now support for M1 Macs too.
Define the image to build
Dockerfile example, pulls in another Dockerfile from hub.docker.com as a starting point, copies the source code from local into the VM, and opens port 80.
# Use existing image from hub.docker.com as starting point
# OS and stack
FROM php7.0-apache
# Copy local source code into the virtual machine
COPY src/ /var/www/html
# Expose port(s)
EXPOSE 80
Build the image
This should be run in the same location as the Dockerfile
docker build -t my-image .
-t tags the image with a human readable name
List all Docker images
This shows all the images that Docker has built, from these images containers can be built
Docker images
Build and run a container from the image
docker run -p 80:80 my-image
Note in the above the source code is statically copied from local into the virtual machine.
Build and run a container from the image
and mount the source code into the virtual machine
docker run -p 80:80 -v /full/local/path/to/sourcecode:/var/www/html my-image
Build and run a public image from hub.docker.com
docker run -t -i centos:centos6 /bin/bash
Connect to a running container
docker attach [machineID]
Docker Compose
Docker Compose is a tool to help define and share multi-container applications. We can create a YAML file to define the services and with a single command, can spin everything up or tear it all down.
Using Compose is basically a three-step process:
Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
Run docker-compose up and Compose starts and runs your entire app.
A docker-compose.yml looks like this:
version: '2.0'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
Standard LAMP (debian, mariadb) Example
docker-compse.yml:
version: '3.7'
services:
php-httpd:
image: php:7.3-apache
ports:
- 80:80
volumes:
- "/Users/ross/Sites/observium/www/:/var/www/html"
mariadb:
image: mariadb:10.5.2
volumes:
- mariadb-volume:/var/lib/mysql
environment:
TZ: "Europe/London"
MYSQL_ALLOW_EMPTY_PASSWORD: "no"
MYSQL_ROOT_PASSWORD: "root"
MYSQL_USER: 'test'
MYSQL_PASSWORD: 'test'
MYSQL_DATABASE: 'test'
phpmyadmin:
image: phpmyadmin/phpmyadmin
links:
- 'mariadb:db'
ports:
- 8081:80
volumes:
mariadb-volume:
or
Standard LAMP (ubuntu, mariadb) Example
Create a www folder in /Users/ross/Sites/observium/ with an index.html file
Build and run the container:
docker-compose up -d --build
This creates a standard LAMP instance with PHPMyAdmin that is running in the background.
To SSH into the running container:
Use docker ps to get the name of the existing container
Use the command docker attach or docker exec -it <container name> /bin/bash to get a bash or shell (replace /bin/bash with sh) in the container
Exit container: exit or CTRL + P then Q
Generically, use docker exec -it <container name> <command> to execute whatever command you specify in the container.
Docker Networking
By default, Docker uses bridge network mode. This is not recommended for production.
Hosts can ping each other by IP on the default bridge network, but not ping by hostname.
On custom bridge networks ping by ip and hostname will work because they use Automatic Network Discovery service.
Its possible for a host to be on more than one bridge network if needed.
Setting up a container to use a custom bridge network:
$ docker run -d --name alpine1 --network alpine-net alpine ash
(Note ash is Alpines version of bash)
You can also define the network in docker-compose.yml file.
Docker bind mount vs volumes
A bind mount, is best for local development as is mounts a directory from the host into the container using a mount point.
A volume is best used in production as it ‘clones’ the contents of the host directory to the container. Changes to the host directory contents are synced in realtime with the container folder.
Comments
Post a Comment