Docker containers
Windows 10 administrator account fix
If Windows 10 has a separate Administrator account, do the following. Log in as Administrator and go to Start
-> Computer Management
-> Local Users and Groups
-> Groups
-> docker-users
. Then add desired users to the group. Finally, log out as a user and log in again to refresh the group membership. It then will be possible to run Docker application without Administrator privileges.
Run Docker commands without sudo in Linux
Add docker
group if it doesn't exist already:
sudo groupadd docker
Add the connected user to the docker group:
sudo gpasswd -a $USER docker
Log out and log in again to update group membership. Restart the docker daemon:
sudo service docker restart
Sample application
Clone the repository from Github and cd
to the app folder:
git clone https://github.com/docker/getting-started.git
cd getting-started/app
Create Dockerfile
in the selected folder:
# syntax=docker/dockerfile:1
FROM node:12-alpine
RUN apk add --no-cache python3 g++ make
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
Build the container using the docker build
command:
docker build -t todo-app .
Start the container:
docker run -dp 3000:3000 todo-app
Delete a container
Get the ID of the running container:
docker ps
Stop the container:
docker stop <the-container-id>
Get the ID of stopped container:
docker ps -a
Remove the container:
docker rm <the-container-id>
Push the image
In order to push an image to Docker Hub, first create an account there and create a new repository. Then login to Docker Hub:
docker login -u romanak
Tag the existing image with a new name:
docker tag getting-started romanak/todo-app
Push the image to Docker Hub:
docker push romanak/todo-app
Run the image on a new instance
Go to Play with Docker and add a new instance. Then start the freshly pushed app:
docker run -dp 3000:3000 romanak/todo-app
Persist the data
Create a named volume:
docker volume create todo-db
Stop and remove the app container:
docker rm -f <id>
Start the app container, specify the named volume, and mount it to /etc/todos
:
docker run -dp 3000:3000 -v todo-db:/etc/todos todo-app
Find the location where Docker is actually storing the data:
docker volume inspect todo-db
Use bind mounts
Start a dev-mode container:
docker run -dp 3000:3000 \
-w /app -v "$(pwd):/app" \
node:12-alpine \
sh -c "yarn install && yarn run dev"
Watch logs:
docker logs -f <container-id>
EC2 practice
Default commands for webserver EC2 instance:
#!/bin/bash
sudo yum -y update
sudo yum -y install git
yum -y install httpd
systemctl enable httpd
systemctl start httpd
echo '<html><h1>Hello From $(hostname -f) Web Server!</h1></html>' > /var/www/html/index.html
Default commands for Docker EC2 instance:
#!/bin/bash
sudo yum -y update
sudo yum -y install git
sudo amazon-linux-extras install -y docker
sudo service docker start
sudo usermod -a -G docker ec2-user
Clone a simple Docker repository to local machine and cd
to it:
git clone https://github.com/romanak/docker-getting-started.git
cd docker-getting-started
Build the getting-started
image and start the container:
docker build -t getting-started .
docker run -dp 80:80 getting-started
cd app/
Build the todo-app
image and start the container:
docker build -t todo-app .
docker run -dp 3000:3000 todo-app
Apply a new tag which corresponds to Docker account:
docker tag getting-started romanak/getting-started
docker tag todo-app romanak/todo-app
Login to docker and push the images to Docker Hub:
docker login -u romanak
docker push romanak/getting-started
docker push romanak/todo-app
SSH to the created EC2 instance with the created key aws.pem
:
ssh -i aws.pem ec2-user@<machine-ip>
Run the Docker contaienrs from the Docker Hub in the EC2 instance:
docker run -dp 80:80 romanak/getting-started
docker run -dp 3000:3000 romanak/todo-app
Create a few items in the todo app, remove the container and create a new container from the Docker Hub image:
docker rm -f <container-id>
docker run -dp 3000:3000 romanak/todo-app
Observe that the old items have disappeared. Now remove the todo container again, create a shareable network and mysql container:
docker rm -f <container-id>
docker network create todo-app
docker run -dp 3306:3306 \
--network todo-app --network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:5.7
Log into MySQL database container with password secret
to make sure it works:
docker exec -it <mysql-container-id> mysql -u root -p
Use MySQL command to view the databases:
SHOW DATABASES;
Now we will deploy the todo container within the same network as MySQL database:
docker run -dp 3000:3000 \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
romanak/todo-app \
sh -c "yarn install && yarn run dev"
We can check the logs of deploying the container:
docker logs <container-id>
We can add a few items to the todo list and check the database entries:
docker exec -it <mysql-container-id> mysql -u root -p
With the following MySQL commands:
SHOW DATABASES;
USE todos;
SHOW tables;
SELECT * FROM todo_items;
At this point we can redeploy the container and observe that the items in the todo app are preserved across different container deployments.