tldr docker
tldr dockerManage Docker containers and images.- List currently running docker containers: docker container ls- List all docker containers (running and stopped): docker container ls -a- Start a container: docker container start container- Stop a container: docker container stop container- Start a container from an image and get a shell inside of it: docker container run -it image bash- Run a command inside of an already running container: docker container exec container command- Remove a stopped container: docker container rm container- Fetch and follow the logs of a container: docker container logs -f container |
本文以实际操作为例,演示的docker的基本用法,操作示例如下:
- ubuntu
- mysql
- hexo
- portainer
ubuntu on docker
docker pull ubuntu docker run --name ubuntu-1 -it ubuntu /bin/bash root@c5bfcf6cf3ce:/# uname -aLinux c5bfcf6cf3ce 4.9.87-linuxkit-aufs #1 SMP Wed Mar 14 15:12:16 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux docker run --name ubuntu-2 -it ubuntu /bin/bash root@0e2ad964e587:/# uname -aLinux 0e2ad964e587 4.9.87-linuxkit-aufs #1 SMP Wed Mar 14 15:12:16 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux |
docker image 与 docker container 的关系
docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES0e2ad964e587 ubuntu "/bin/bash" 23 seconds ago Up 23 seconds ubuntu-2c5bfcf6cf3ce ubuntu "/bin/bash" 41 seconds ago Up 41 seconds ubuntu-1 |
从上面的docker ps结果可以看到,由同一个 IMAGE 通过docker run产生了2个独立的容器,一个容器内部文件修改不会影响另一个容器。IMAGE 和 CONTAINER 的关系,有点类似 Class 和其实例的关系,CONTAINER 只是 IMAGE 运行后的一个实例,可参考这篇关于AUFS的文章和Containers 101: Docker fundamentals这篇介绍 docker 基本原理的文章,从文章中各选了一张图作为示例说明如下。
docker image 和 docker container 图例说明
除了运行的容器这一层是可读写的,下面每一层(Layer)都是只读的,像运行 Dockerfile 中的每个RUN都会创建一个 IMAGE,IMAGE 下一层为其父 IMAGE,最下层无父 IMAGE 的称之为 BASE IMAGE。
在容器中增加新文件
退出当前的伪终端,同时退出容器。如果容器里有类似 MySQL 这样的服务在运行,退出伪终端并不会导致容器退出,如果需要停止此容器,需要运行docker container stop CONTAINER命令。
root@0e2ad964e587:/# echo test > ~/test.txtroot@0e2ad964e587:/# exit |
docker container stop 关闭容器
docker container stop ubuntu-2ubuntu-2 |
docker container start 启动容器
docker container start ubuntu-2ubuntu-2 |
docker exec 进入正在运行的容器
docker exec -it ubuntu-2 bashubuntu-2 |
查看前面新增文件的内容
使用docker container start CONTAINER可以恢复此容器上次退出时的最后状态。
root@0e2ad964e587:/# cat ~/test.txttestroot@0e2ad964e587:/# |
mysql-5.7.22 on docker
mysql 数据存储目录创建
先在宿主机(host)上建立MySQL的数据存储目录,并会将此目录映射至 docker 容器中的/var/lib/mysql目录。
mkdir -p /usr/local/var/mysql-5.7.22/ |
启动容器运行 mysql server
docker run -p 3306:3306 --rm -v /usr/local/var/mysql-5.7.22:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=test.root --name mysql-5.7.22 -d mysql:5.7.22 \ --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci \ --datadir=/var/lib/mysql --bind-address=0.0.0.0b6acb3be644d76f09eb10629bef370fc1fbd66ffbf11d4767e6bd497e4b07bc1 |
docker run 常用参数说明
-d, --detach Run container in background and print container ID-e, --env list Set environment variables-i, --interactive Keep STDIN open even if not attached-p, --publish list Publish a container's port(s) to the host (host-port:container-port)-t, --tty Allocate a pseudo-TTY-v, --volume list Bind mount a volume (host-dir:container-dir) --name string Assign a name to the container --rm Automatically remove the container when it exits |
docker exec 进入运行中的容器
docker exec -it mysql-5.7.22 bash |
docker top 查看容器中的进程
docker top mysql-5.7.22PID USER TIME COMMAND3861 999 0:00 mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --datadir=/var/lib/mysql |
docker container 操作容器
stop 停止容器
docker container stop mysql-5.7.22 |
rm 删除容器
docker container rm mysql-5.7.22 |
mysql docker-compose.yml 配置
version: '3.5'services: mysql: image: mysql:5.7.22 command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --datadir=/var/lib/mysql container_name: mysql-5.7.22 ports: - "3306:3306" restart: always volumes: - /usr/local/var/mysql-5.7.22:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: test.root |
docker container stop mysql-5.7.22mysql-5.7.22 docker container rm mysql-5.7.22mysql-5.7.22 docker-compose up -dCreating network "57_default" with the default driverCreating mysql-5.7.22 ... done docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES2f62947ce66b mysql:5.7.22 "docker-entrypoint.s…" About a minute ago Up 8 seconds 0.0.0.0:3306->3306/tcp mysql-5.7.22524f60344fb7 yuweijun/hexo-server:3.7.0 "docker-entrypoint.s…" 3 hours ago Up 3 hours 0.0.0.0:4000->4000/tcp hexo-server |
hexo-3.7.0 on docker
docker pull 最新版本node
docker pull node |
安装hexo
docker run --name node-10.5.0 -it node bash root@ec3be3657e06:/# npm i -g hexo root@ec3be3657e06:/# exit |
docker commit 当前容器
docker commit会根据容器最后的状态制作一个新的 IMAGE。
docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESec3be3657e06 node "bash" About a minute ago Exited (0) 31 seconds ago node-10.5.0 |
docker commit node-10.5.0 yuweijun/hexosha256:92166c083a4f82e368c1067fe8cd9dc313b24636918ba0ccab7f58bd57fd63cc |
docker image ls 查看当前 images
docker image lsREPOSITORY TAG IMAGE ID CREATED SIZEyuweijun/hexo latest 92166c083a4f About a minute ago 703MBnode latest 8753edeb1aa3 3 minutes ago 674MB |
通过容器启动 hexo server
以下示例命令中hexo应用的根目录为/github.com/hexo。
docker run --name hexo-server -p 4000:4000 -v $HOME/.ssh:/root/.ssh \ -v /github.com/hexo:/github.com/hexo -it yuweijun/hexo \ hexo --cwd /github.com/hexo serverINFO Start processingINFO Hexo is running at http://localhost:4000/blog/. Press Ctrl+C to stop. |
第一次运行之后生成了hexo-server容器,后面只要执行docker container start CONTAINER就可以启动hexo server。
docker container start hexo-serverhexo-server |
docker container start -i
启动hexo-server容器可以运行hexo server,如果需要控制台输出日志,命令需要多传一个参数:
-i --interactive Attach container’s STDIN
docker container start -i hexo-serverINFO Start processingINFO Hexo is running at http://localhost:4000/blog/. Press Ctrl+C to stop. |
docker container lsCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES1d46ae36a29a yuweijun/hexo "hexo --cwd /github.…" 14 minutes ago Up 6 minutes 0.0.0.0:4000->4000/tcp hexo-server0e2ad964e587 ubuntu "/bin/bash" 6 hours ago Up 5 hours ubuntu-2c5bfcf6cf3ce ubuntu "/bin/bash" 6 hours ago Up 6 hours ubuntu-1b6acb3be644d mysql:5.7.22 "docker-entrypoint.s…" 17 hours ago Up 17 hours 0.0.0.0:3306->3306/tcp mysql-5.7.22 |
docker logs -f 查看容器运行日志
docker logs -f hexo-serverINFO Start processingINFO Hexo is running at http://localhost:4000/blog/. Press Ctrl+C to stop. |
通过容器执行 hexo clean
docker run --rm --name hexo-clean \ -v $HOME/.ssh:/root/.ssh -v /github.com/hexo:/github.com/hexo \ -it yuweijun/hexo hexo --cwd /github.com/hexo cleanINFO Deleted database.before exist |
第一次运行之后生成了hexo-clean容器,后面只要执行docker container start -i CONTAINER就可以。
docker container start -i hexo-cleanINFO Deleted database.before exist |
Dockerfile 文件配置
docker run只接受一个命令,如果需要执行一系列命令时,最好是使用 Dockerfile 定制自己的镜像文件。
docker 启动脚本 docker-entrypoint.sh
if [ -e /github.com/hexo ]; then cd /github.com/hexo if [ ! -e /github.com/hexo/node_modules ]; then npm install fi hexo clean hexo serverelse echo 'docker run --name hexo-server -p 4000:4000 -v $HOME/.ssh:/root/.ssh -v /github.com/hexo:/github.com/hexo -it yuweijun/hexo-server:3.7.0'fi |
Dockerfile
FROM yuweijun/hexoCOPY docker-entrypoint.sh /usr/local/bin/ENTRYPOINT ["docker-entrypoint.sh"]EXPOSE 4000CMD ["/bin/bash"] |
docker-entrypoint.sh文件和Dockerfile文件放在同一个目录下,并且控制台cd到这个目录下执行以下镜像构建命令:
docker build 构建
docker build -t yuweijun/hexo-server:3.7.0 .Sending build context to Docker daemon 3.072kBStep 1/5 : FROM yuweijun/hexo ---> ef20fe8ae205Step 2/5 : COPY docker-entrypoint.sh /usr/local/bin/ ---> Using cache ---> cab9386a8e74Step 3/5 : ENTRYPOINT ["docker-entrypoint.sh"] ---> Using cache ---> e05e55eb54b1Step 4/5 : EXPOSE 4000 ---> Using cache ---> d2517e6fc536Step 5/5 : CMD ["/bin/bash"] ---> Using cache ---> 8dc78ad81ca3Successfully built 8dc78ad81ca3Successfully tagged yuweijun/hexo-server:3.7.0 |
Dockerfile RUN/ENTRYPOINT/CMD 区别
Dockerfile文件中的RUN、CMD和ENTRYPOINT这三个指令看上去功能很类似,都可以用来运行命令,下面简单说一下三者区别:
- RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。
- CMD 设置容器启动后默认执行的命令及其参数,如果有多个 CMD,则只有最后一个生效,但 CMD 能够被
docker run后面跟的命令行参数替换。 - ENTRYPOINT 配置容器启动时运行的命令,ENTRYPOINT 指令可让容器以应用程序或者服务的形式运行,与 CMD 不同的是,ENTRYPOINT 一定会被执行。
- 如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。
启动新版 hexo-server
先删除前面生成的hexo-server容器。
docker container rm hexo-server |
启动新版hexo-server。
docker run --name hexo-server -p 4000:4000 \ -v $HOME/.ssh:/root/.ssh -v /github.com/hexo:/github.com/hexo \ -it yuweijun/hexo-server:3.7.0INFO Deleted database.INFO Start processingINFO Hexo is running at http://localhost:4000/blog/. Press Ctrl+C to stop. |
hexo docker-compose.yml 配置
version: '3.5'services: hexo: image: yuweijun/hexo-server:3.7.0 container_name: hexo-server ports: - "4000:4000" restart: always volumes: - $HOME/.ssh:/root/.ssh - /github.com/hexo:/github.com/hexo |
使用docker-compose命令启动hexo-server服务:
docker container rm hexo-server docker-compose up -dRecreating c5e37b50081e_370_hexo_1 ... done docker container lsCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES524f60344fb7 yuweijun/hexo-server:3.7.0 "docker-entrypoint.s…" 2 minutes ago Up 11 seconds 0.0.0.0:4000->4000/tcp hexo-server |
portainer on docker
portainer(基于 Go)是一个轻量级的 docker 管理工具。
docker volume create portainer_dataportainer_data docker run -d -p 9000:9000 --name portainer \ --restart always -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data portainer/portainerUnable to find image 'portainer/portainer:latest' locallylatest: Pulling from portainer/portainerd1e017099d17: Pull completea8d2fd955b4d: Pull completeDigest: sha256:7affc7f6d02ebceaa4e0cd137ef3c784629e5ebfa2354c4776337f8bc42664a4Status: Downloaded newer image for portainer/portainer:latest699ab479af8316ac88c1dbdb1990f84d3b76a1f6deb3e35ad8f3a05b757d5080 |
one service per container
容器的主要是通过 Dockerfile 配置中最后的 ENTRYPOINT 和 CMD 运行进程,通常建议通过每个容器使用一项服务来分隔关注点。
Containers vs VMs
二者区别简单来说就是,docker 的 IMAGE 或者 CONTAINER 没有 OS 内核,与宿主机共享内核。
docker commands diagram
References
- get started - docker
- Run multiple services in a containe
- docker cheat sheet
- Docker RUN vs CMD vs ENTRYPOINT
- How to Automate Docker Deployments
- docker commit
- docker exec
- docker run
- docker container start
- portainer Deployment
- docker compose version 3 reference
- Containers 101: Docker fundamentals
- What is Docker and How to Use it With Python
- Docker Getting Start: Related Knowledge
- Understanding Volumes in Docker