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
# 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
# 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).
# 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.
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.