WordPress Migration Saga – Getting Used to Docker

5 min read
from Le blog de Laurel

Here is the second post from WordPress Migration Saga, a series that presents the migration of an existing WordPress website to another host, in Docker.

In this post we will go over a series of commands in Docker, to get a little aquainted with this kind of working environment.

To find out about the migration context and the prerequisites for this kind of migration, read the first part, The Beginnings.

Let’s get Docker installed on our server. Below we can see instructions for Linux, more details for various operating systems can be found at Docker Engine.

sudo apt-get update

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Let’s install Docker Compose on our server. See Install Docker Compose

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version

If you don’t want to use docker for any elevated docker command, you can add the user to the docker group. See Post-installation steps for Linux

sudo groupadd docker
sudo usermod -aG docker myuser
su - myuser
id -nG

Now that we have installed Docker, let’s run a few commands, to get to know Docker. There is a vast list of commands available here.

If we wanted to launch a container, we need to run the following command:

# docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

The command above just launched your first Docker container. 🙂

Now you can list all Docker containers with ps -a, or only a specific number using ps -n 7 and get info about them using the first characters of the container id and inspect or logs.

# list all containers
docker ps -a
# list first n containers
docker ps -n 7
# show information about container
docker inspect a8d
# view logs
docker logs a8d

You can rename a container using rename, and connect to a container using exec.

# rename
docker rename nervous_babbage other_name
# run the container and detach it
docker run -d a8d
# run a command in container
docker exec a8d ps
# start interactive and allocate a pseudo-tty
docker exec -it a8d bash

Then stop and remove the container:

# stop
docker stop a8d
# remove
docker rm a8d
# delete all stopped containers
docker rm $(docker ps -a -q)

Containers, just like with git and GitHub, can be put under versioning, and the changes can be pushed to Docker Hub, in public repositories (or paid private repositories).

Other commands:

# create and copy file
touch testfile
docker container cp testfile unruffled_snyder:/opt
# show difference
docker diff a8d
# run with different options and args
docker container run -idt -P nginx
docker container run -idt -p 8888:80 nginx
docker container run -idt --name ghost -p 3001:2368 ghost:alpine
# list images
docker images
docker image history ghost:alpine
# pull images
docker pull ubuntu
docker pull centos
# run multiple containers
docker container run -idt --name dev-ubuntu --net host ubuntu bash
docker container run -idt --name dev-centos --net host centos bash
# list multiple containers
docker ps -n 2
# connect to container and install vim
docker exec -it dev-ubuntu bash
ps aux
apt-get update
apt-get install vim
touch /opt/myfile
# stop and start
docker stop dev-ubuntu dev-centos
docker start dev-ubuntu
# connect again and verify vim is installed
docker exec -it dev-ubuntu bash
which vim
# remove
docker rm dev-ubuntu
# create volume
docker volume create portainer_data
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
# commit changes
docker ps -l
docker diff a8d
docker container commit image_name hubuser/reponame:v2
docker image ls
docker image history a8d
docker login
docker image push hubuser/reponame:v2
# checkout, run and push
cd reponame/
git checkout docker
ls
docker image build -t hubuser/reponame:v3 .
docker image ls
docker image history hubuser/reponame:v3
docker container run -idt -P hubuser/reponame:v3
docker ps
docker image push hubuser/reponame:v3

What about Docker Compose? In a test folder, create a YAML file named docker-compose.yml, and run docker-compose up to start and run the application, with the option -d to detach it and run in background.

version: '3.7' 

networks:
    webserver-test:

services:

    my_webserver:
        image: nginx:1.15.12-alpine
        container_name: my_webserver
        restart: unless-stopped
        ports:
            - "1234:80"
        volumes:
            - my_html:/usr/share/nginx/html
        networks:
            - webserver-test
volumes:
    my_html:
# run in detached mode, pull the needed Docker images, and start the containers
myuser@host:~/test$ docker-compose up -d
Creating network "test_webserver-test" with the default driver
Creating volume "test_my_html" with default driver
Creating my_webserver ... done
# list services, watch logs
myuser@host:~/test$ docker-compose ps
    Name             Command          State          Ports        
------------------------------------------------------------------
my_webserver   nginx -g daemon off;   Up      0.0.0.0:1234->80/tcp
myuser@host:~/test$ docker-compose logs
Attaching to my_webserver
# stop
myuser@host:~/test$ docker-compose stop
Stopping my_webserver ... done
# remove the containers and default network, but preserve your data
myuser@host:~/test$ docker-compose down
Removing my_webserver ... done
Removing network test_webserver-test
# remove the containers, default network, and the data
myuser@host:~/test$ docker-compose down --volumes
Removing network test_webserver-test
WARNING: Network test_webserver-test not found.
Removing volume test_my_html

Other useful commands for development and testing. If you have created all kind of containers for testing purposes, now it is time to clean your host, before starting the real work. Don’t use those commands after you have created your websites, though!

docker stop $(sudo docker ps -a -q)
docker rm $(sudo docker ps -a -q)
docker volume rm $(sudo docker volume ls -q)
docker network prune
service docker restart

You can test Docker commands online, too, using Play with Docker.

From Le blog de Laurel

In the next post, Step By Step Guide for Ubuntu 18.04, we will see step by step how the migration of an existing WordPress website in Docker can be made on Linux.

Leave a Reply

Your email address will not be published. Required fields are marked *