{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 快速参考\n", "\n", "参考:[Docker 小技巧](https://www.mianshigee.com/project/jinfagang-alfred)\n", "\n", "````{admonition} Docker 命令行的基本使用\n", ":class: tip\n", "```bash\n", "docker + 管理对象(比如容器,镜像) + 具体操作(比如创建,启动,停止,删除)\n", "```\n", "\n", "```{admonition} 例子\n", "- `docker image pull nginx` 拉取 `nginx` 的 docker 镜像\n", "- `docker container stop web` 停止 `web` 的 docker 容器\n", "```\n", "````\n", "\n", "```{include} quickref.txt\n", "```\n", "\n", "## 镜像管理和发布\n", "\n", "```{topic} 镜像获取\n", "- `pull`:从 registry 拉取\n", "- `build`:从 Dockerfile 构建\n", "- `load`:从本地获取\n", "```\n", "\n", "### 镜像基本操作\n", "\n", "查看基本功能:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Usage: docker image COMMAND\n", "\n", "Manage images\n", "\n", "Commands:\n", " build Build an image from a Dockerfile\n", " history Show the history of an image\n", " import Import the contents from a tarball to create a filesystem image\n", " inspect Display detailed information on one or more images\n", " load Load an image from a tar archive or STDIN\n", " ls List images\n", " prune Remove unused images\n", " pull Pull an image or a repository from a registry\n", " push Push an image or a repository to a registry\n", " rm Remove one or more images\n", " save Save one or more images to a tar archive (streamed to STDOUT by default)\n", " tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE\n", "\n", "Run 'docker image COMMAND --help' for more information on a command.\n" ] } ], "source": [ "!docker image" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{topic} 镜像拉取\n", "默认从 Docker Hub 拉取,如果不指定版本,会拉取最新版。\n", "```\n", "\n", "比如:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using default tag: latest\n", "latest: Pulling from library/nginx\n", "Digest: sha256:790711e34858c9b0741edffef6ed3d8199d8faa33f2870dea5db70f16384df79\n", "Status: Image is up to date for nginx:latest\n", "docker.io/library/nginx:latest\n" ] } ], "source": [ "!docker pull nginx" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "指定版本:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.20.0: Pulling from library/nginx\n", "\n", "\u001b[1B2152171a: Pulling fs layer \n", "\u001b[1B15a5cec8: Pulling fs layer \n", "\u001b[1Bb026b9ce: Pulling fs layer \n", "\u001b[1Bdc384fb3: Pulling fs layer \n", "\u001b[1B372d6dee: Pulling fs layer \n", "\u001b[1BDigest: sha256:ea4560b87ff03479670d15df426f7d02e30cb6340dcd3004cdfc048d6a1d54b4\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[2A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[1A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[6A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[5A\u001b[2K\u001b[4A\u001b[2K\u001b[3A\u001b[2K\u001b[2A\u001b[2K\u001b[1A\u001b[2K\n", "Status: Downloaded newer image for nginx:1.20.0\n", "docker.io/library/nginx:1.20.0\n" ] } ], "source": [ "!docker pull nginx:1.20.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "从 Quay 上拉取镜像:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using default tag: latest\n", "Error response from daemon: unauthorized: access to the requested resource is not authorized\n" ] } ], "source": [ "!docker pull quay.io/bitnami/nginx" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "````{topic} 镜像的查看\n", "\n", "比如:\n", "```bash\n", "$ docker image ls\n", "```\n", "```\n", "REPOSITORY TAG IMAGE ID CREATED SIZE\n", "quay.io/bitnami/nginx latest 0922eabe1625 6 hours ago 89.3MB\n", "nginx 1.20.0 7ab27dbbfbdf 10 days ago 133MB \n", "``` \n", "\n", "查看虚悬镜像:\n", "```bash\n", "!docker image ls -f dangling=true\n", "```\n", "````\n", "\n", "````{topic} 镜像的删除\n", "```bash\n", "$ docker image rm 0922eabe1625\n", "```\n", "```\n", "Untagged: quay.io/bitnami/nginx:latest\n", "Untagged: quay.io/bitnami/nginx@sha256:d143befa04e503472603190da62db157383797d281fb04e6a72c85b48e0b3239\n", "Deleted: sha256:0922eabe16250e2f4711146e31b7aac0e547f52daa6cf01c9d00cf64d49c68c8\n", "Deleted: sha256:5eee4ed0f6b242e2c6e4f4066c7aca26bf9b3b021b511b56a0dadd52610606bd\n", "Deleted: sha256:472a75325eda417558f9100ff8b4a97f4a5e8586a14eb9c8fc12f944b26a21f8\n", "Deleted: sha256:cdcb5872f8a64a0b5839711fcd2a87ba05795e5bf6a70ba9510b8066cdd25e76\n", "Deleted: sha256:e0f1b7345a521469bbeb7ec53ef98227bd38c87efa19855c5ba0db0ac25c8e83\n", "Deleted: sha256:11b9c2261cfc687fba8d300b83434854cc01e91a2f8b1c21dadd937e59290c99\n", "Deleted: sha256:4819311ec2867ad82d017253500be1148fc335ad13b6c1eb6875154da582fcf2\n", "Deleted: sha256:784480add553b8e8d5ee1bbd229ed8be92099e5fb61009ed7398b93d5705a560\n", "Deleted: sha256:e0c520d1a43832d5d2b1028e3f57047f9d9f71078c0187f4bb05e6a6a572993d\n", "Deleted: sha256:94d5b1d6c9e31de42ce58b8ce51eb6fb5292ec889a6d95763ad2905330b92762\n", "Deleted: sha256:95deba55c490bbb8de44551d3e6a89704758c93ba8503a593cb7c07dfbae0058\n", "Deleted: sha256:1ad1d903ef1def850cd44e2010b46542196e5f91e53317dbdb2c1eedfc2d770c\n", "```\n", "````\n", "\n", "````{topic} 镜像导入\n", "```bash\n", "$ docker image load -i .\\nginx.image\n", "```\n", "```\n", "1839f9962bd8: Loading layer [==================================================>] 64.8MB/64.8MB\n", "a2f4f809e04e: Loading layer [==================================================>] 3.072kB/3.072kB\n", "9b63e6289fbe: Loading layer [==================================================>] 4.096kB/4.096kB\n", "f7141923aaa3: Loading layer [==================================================>] 3.584kB/3.584kB\n", "272bc57d3405: Loading layer [==================================================>] 7.168kB/7.168kB\n", "Loaded image: nginx:1.20.0\n", "```\n", "````\n", "\n", "````{topic} 镜像保存\n", "```bash\n", "$ docker image save nginx:1.20.0 -o nginx.image\n", "```\n", "````\n", "\n", "### Dockerfile 基本结构\n", "\n", "Docker 可以通过从 `Dockerfile` 中读取指令来自动构建映像。Dockerfile 是文本文档,它包含用户可以在命令行上调用的所有命令来组装镜像。\n", "\n", "比如在 Ubuntu 系统下创建简单的 Python 环境:\n", "\n", "```Dockerfile\n", "FROM ubuntu:20.04\n", "RUN apt-get update && \\\n", " DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y python3.9 python3-pip python3.9-dev\n", "ADD hello.py /\n", "CMD [\"python3\", \"/hello.py\"]\n", "```\n", "\n", "## scratch 镜像\n", "\n", "Scratch 是空白 Docker 镜像。\n", "\n", "```{rubric} 通过 scratch 来构建基础镜像。\n", "```\n", "\n", "::::{tab-set}\n", "\n", ":::{tab-item} hello.c\n", "```\n", "#include \n", "int main()\n", "{\n", " printf(\"hello docker\\n\");\n", "}\n", "```\n", ":::\n", "::::\n", "\n", "```{rubric} 编译成二进制文件\n", "```\n", "```bash\n", "$ gcc --static -o hello hello.c\n", "$ ./hello\n", "hello docker\n", "$\n", "```\n", "\n", "::::{tab-set}\n", "\n", ":::{tab-item} Dockerfile\n", "```\n", "FROM scratch\n", "ADD hello /\n", "CMD [\"/hello\"]\n", "```\n", ":::\n", "::::\n", "\n", "```{rubric} 构建\n", "```\n", "\n", "```bash\n", "$ docker build -t hello .\n", "$ docker image ls\n", "REPOSITORY TAG IMAGE ID CREATED SIZE\n", "hello latest 2936e77a9daa 40 minutes ago 872kB\n", "```\n", "\n", "```{rubric} 运行\n", "```\n", "```bash\n", "$ docker container run -it hello\n", "hello docker\n", "```\n", "\n", "## Docker 数据存储\n", "\n", "默认情况下,在运行中的容器里创建的文件,被保存在可写的容器层:\n", "\n", "- 如果容器被删除了,则数据也没有了\n", "- 这个可写的容器层是和特定的容器绑定的,也就是这些数据无法方便的和其它容器共享\n", "\n", "Docker 主要提供了两种方式做数据的持久化\n", "\n", "- Data Volume:由 Docker 管理(`/var/lib/docker/volumes/` Linux), 持久化数据的最好方式\n", "- Bind Mount,由用户指定存储的数据具体 mount 在系统什么位置\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3.8.13 ('tvmo': conda)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.13" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "f84f946b1c3af061cd4f6d85753fa9fad51e40b700ed1d7b0dec8a56b8e85b7c" } } }, "nbformat": 4, "nbformat_minor": 2 }