From b44c9acd6ca091207a2801b0130d56225eefa6b6 Mon Sep 17 00:00:00 2001 From: Baohua Yang Date: Mon, 9 Feb 2026 12:56:12 -0800 Subject: [PATCH] Restruct --- 01_introduction/1.1_quickstart.md | 2 +- 01_introduction/1.2_what.md | 4 +- 01_introduction/1.3_why.md | 4 +- 02_basic_concept/2.1_image.md | 6 +- 02_basic_concept/2.2_container.md | 10 +- 02_basic_concept/2.3_repository.md | 2 +- 03_install/3.10_experimental.md | 2 +- 03_install/3.1_ubuntu.md | 2 +- 03_install/3.2_debian.md | 2 +- 03_install/3.3_fedora.md | 2 +- 03_install/3.4_centos.md | 2 +- 03_install/3.5_raspberry-pi.md | 2 +- 03_install/3.6_offline.md | 2 +- 03_install/3.7_mac.md | 2 +- 03_install/3.8_windows.md | 2 +- 03_install/3.9_mirror.md | 2 +- 04_image/4.1_pull.md | 2 +- 04_image/4.2_list.md | 2 +- 04_image/4.3_rm.md | 4 +- 04_image/4.4_commit.md | 2 +- 04_image/4.5_build.md | 2 +- 04_image/4.6_other.md | 2 +- 04_image/4.7_internal.md | 2 +- 04_image/dockerfile/README.md | 3 - 05_container/5.1_run.md | 6 +- 05_container/5.2_daemon.md | 6 +- 05_container/5.3_stop.md | 2 +- 05_container/5.4_attach_exec.md | 2 +- 05_container/5.5_import_export.md | 2 +- 05_container/5.6_rm.md | 4 +- 06_repository/6.1_dockerhub.md | 2 +- 06_repository/6.2_registry.md | 2 +- 06_repository/6.3_registry_auth.md | 2 +- 06_repository/6.4_nexus3_registry.md | 2 +- .../7.10_workdir.md | 4 +- .../user.md => 07_dockerfile/7.11_user.md | 4 +- .../7.12_healthcheck.md | 6 +- .../7.13_onbuild.md | 4 +- .../label.md => 07_dockerfile/7.14_label.md | 4 +- .../shell.md => 07_dockerfile/7.15_shell.md | 4 +- .../7.16_references.md | 2 +- .../run.md => 07_dockerfile/7.1_run.md | 4 +- .../copy.md => 07_dockerfile/7.2_copy.md | 4 +- .../add.md => 07_dockerfile/7.3_add.md | 4 +- .../cmd.md => 07_dockerfile/7.4_cmd.md | 4 +- .../7.5_entrypoint.md | 4 +- .../env.md => 07_dockerfile/7.6_env.md | 6 +- .../arg.md => 07_dockerfile/7.7_arg.md | 2 +- .../volume.md => 07_dockerfile/7.8_volume.md | 8 +- .../expose.md => 07_dockerfile/7.9_expose.md | 4 +- 07_dockerfile/README.md | 58 ++++ .../README.md | 2 +- .../data/README.md | 0 .../data/_images/types-of-mounts.png | Bin .../data/bind-mounts.md | 2 +- .../data/volume.md | 2 +- .../network/README.md | 2 +- .../network/dns.md | 0 .../network/port_mapping.md | 2 +- .../9.1_buildkit.md | 2 +- .../8.2_buildx.md => 09_buildx/9.2_buildx.md | 4 +- .../9.3_multi-arch-images.md | 2 +- {08_buildx => 09_buildx}/README.md | 10 +- .../10.1_introduction.md | 2 +- .../10.2_install.md | 2 +- .../9.3_usage.md => 10_compose/10.3_usage.md | 2 +- .../10.4_commands.md | 2 +- .../10.5_compose_file.md | 2 +- .../10.6_django.md | 10 +- .../9.7_rails.md => 10_compose/10.7_rails.md | 8 +- .../10.8_wordpress.md | 6 +- .../9.9_lnmp.md => 10_compose/10.9_lnmp.md | 2 +- {09_compose => 10_compose}/README.md | 2 +- .../demo/app/Dockerfile | 0 {09_compose => 10_compose}/demo/app/app.py | 0 .../demo/app/docker-compose.yml | 0 .../demo/django/.gitignore | 0 .../demo/django/Dockerfile | 0 .../demo/django/docker-compose.yml | 0 .../demo/django/requirements.txt | 0 .../demo/wordpress/docker-compose.yml | 0 {10_ops => 11_ops}/README.md | 2 +- {10_ops => 11_ops}/logs/README.md | 0 {10_ops => 11_ops}/logs/elk.md | 0 {10_ops => 11_ops}/monitor/README.md | 0 {10_ops => 11_ops}/monitor/prometheus.md | 0 {10_ops => 11_ops}/security/README.md | 8 +- {10_ops => 11_ops}/security/control_group.md | 0 {10_ops => 11_ops}/security/daemon_sec.md | 0 .../security/kernel_capability.md | 0 {10_ops => 11_ops}/security/kernel_ns.md | 0 {10_ops => 11_ops}/security/other_feature.md | 0 {10_ops => 11_ops}/security/summary.md | 0 .../README.md | 2 +- .../etcd/README.md | 0 .../etcd/_images/etcd_logo.png | Bin .../etcd/cluster.md | 0 .../etcd/demo/cluster/docker-compose.yml | 0 .../etcd/etcdctl.md | 0 .../etcd/install.md | 0 .../etcd/intro.md | 0 .../kubectl/README.md | 0 .../kubernetes/README.md | 0 .../_images/k8s-singlenode-docker.png | Bin .../kubernetes/_images/k8s_architecture.png | Bin .../kubernetes/_images/kube-proxy.png | Bin .../kubernetes/_images/kubernetes_design.jpg | Bin .../kubernetes/_images/kubernetes_logo.png | Bin .../kubernetes/_images/kubernetes_logo.svg | 0 .../kubernetes/advanced.md | 0 .../kubernetes/concepts.md | 0 .../kubernetes/design.md | 0 .../kubernetes/intro.md | 0 .../kubernetes/practice.md | 0 .../setup/README.md | 0 .../setup/dashboard.md | 0 .../setup/docker-desktop.md | 0 .../setup/k3s.md | 0 .../setup/kind.md | 0 .../setup/kubeadm-docker.md | 0 .../setup/kubeadm.md | 0 .../setup/systemd.md | 0 {12_ecosystem => 13_ecosystem}/README.md | 2 +- .../cloud/README.md | 0 .../cloud/_images/ECS.jpg | Bin .../cloud/_images/aliyun-logo.png | Bin .../cloud/_images/aws-logo.jpg | Bin .../cloud/_images/qcloud-logo.jpg | Bin .../cloud/alicloud.md | 0 {12_ecosystem => 13_ecosystem}/cloud/aws.md | 0 {12_ecosystem => 13_ecosystem}/cloud/intro.md | 0 .../cloud/multicloud.md | 0 .../cloud/summary.md | 0 .../cloud/tencentCloud.md | 0 .../coreos/README.md | 0 .../coreos/demo/example.fcc | 0 .../coreos/install.md | 0 .../coreos/intro.md | 0 .../podman/README.md | 0 .../14.1_arch.md | 8 +- .../14.2_namespace.md | 6 +- .../14.3_cgroups.md | 4 +- .../14.4_ufs.md | 2 +- .../14.5_container_format.md | 2 +- .../14.6_network.md | 2 +- .../README.md | 2 +- .../_images/docker_arch.png | Bin {14_cases => 15_cases}/README.md | 2 +- {14_cases => 15_cases}/ci/README.md | 0 {14_cases => 15_cases}/ci/actions/README.md | 0 {14_cases => 15_cases}/ci/devops_workflow.md | 0 {14_cases => 15_cases}/ci/drone/.env.example | 0 {14_cases => 15_cases}/ci/drone/.gitignore | 0 {14_cases => 15_cases}/ci/drone/README.md | 2 +- .../ci/drone/_images/drone-build.png | Bin .../ci/drone/demo/.drone.yml | 0 .../ci/drone/demo/README.md | 0 {14_cases => 15_cases}/ci/drone/demo/app.go | 0 .../ci/drone/docker-compose.yml | 0 {14_cases => 15_cases}/ci/drone/install.md | 0 {14_cases => 15_cases}/ide/README.md | 0 {14_cases => 15_cases}/ide/vsCode.md | 0 {14_cases => 15_cases}/os/README.md | 0 .../os/_images/alpinelinux-logo.png | Bin .../os/_images/busybox-logo.png | Bin .../os/_images/centos-logo.png | Bin .../os/_images/coreos-login.png | Bin .../os/_images/coreos-logo.jpg | Bin .../os/_images/coreos_crt.png | Bin .../os/_images/coreos_list.png | Bin .../os/_images/coreos_run_ip.png | Bin .../os/_images/debian-logo.png | Bin .../os/_images/docker_version.png | Bin .../os/_images/fedora-logo.png | Bin .../os/_images/php_pulling.png | Bin .../os/_images/ubuntu-logo.jpg | Bin .../os/_images/vmware_coreos.png | Bin {14_cases => 15_cases}/os/alpine.md | 0 {14_cases => 15_cases}/os/busybox.md | 0 {14_cases => 15_cases}/os/centos.md | 0 {14_cases => 15_cases}/os/debian.md | 0 {14_cases => 15_cases}/os/summary.md | 0 .../16.1_best_practices.md | 2 +- .../16.2_debug.md | 2 +- .../16.3_resources.md | 2 +- {15_appendix => 16_appendix}/README.md | 8 +- .../_images/cmd_logic 2.graffle}/data.plist | Bin .../_images/cmd_logic 2.graffle}/image10.pdf | Bin .../_images/cmd_logic 2.graffle}/image11.pdf | Bin .../_images/cmd_logic 2.graffle}/image12.pdf | Bin .../_images/cmd_logic 2.graffle}/image13.pdf | Bin .../_images/cmd_logic 2.graffle}/image4.pdf | Bin .../_images/cmd_logic 2.graffle}/image5.pdf | Bin .../_images/cmd_logic 2.graffle}/image6.pdf | Bin .../_images/cmd_logic 2.graffle}/image7.pdf | Bin .../_images/cmd_logic 2.graffle}/image9.pdf | Bin .../_images/cmd_logic.dot | 0 .../_images/cmd_logic.dot.bak | 0 .../_images/cmd_logic.graffle/data.plist | Bin 0 -> 6461 bytes .../_images/cmd_logic.graffle/image10.pdf | Bin 0 -> 8040 bytes .../_images/cmd_logic.graffle/image11.pdf | Bin 0 -> 8218 bytes .../_images/cmd_logic.graffle/image12.pdf | Bin 0 -> 17786 bytes .../_images/cmd_logic.graffle/image13.pdf | Bin 0 -> 14933 bytes .../_images/cmd_logic.graffle/image4.pdf | Bin 0 -> 9820 bytes .../_images/cmd_logic.graffle/image5.pdf | Bin 0 -> 12025 bytes .../_images/cmd_logic.graffle/image6.pdf | Bin 0 -> 11523 bytes .../_images/cmd_logic.graffle/image7.pdf | Bin 0 -> 9792 bytes .../_images/cmd_logic.graffle/image9.pdf | Bin 0 -> 48691 bytes .../_images/cmd_logic.png | Bin .../_images/container_status.dot | 0 .../_images/container_status.png | Bin .../command/README.md | 0 .../command/docker.md | 0 .../command/dockerd.md | 0 {15_appendix => 16_appendix}/faq/README.md | 2 +- {15_appendix => 16_appendix}/faq/errors.md | 0 {15_appendix => 16_appendix}/repo/README.md | 0 {15_appendix => 16_appendix}/repo/centos.md | 0 {15_appendix => 16_appendix}/repo/minio.md | 0 {15_appendix => 16_appendix}/repo/mongodb.md | 0 {15_appendix => 16_appendix}/repo/mysql.md | 0 {15_appendix => 16_appendix}/repo/nginx.md | 0 {15_appendix => 16_appendix}/repo/nodejs.md | 0 {15_appendix => 16_appendix}/repo/php.md | 0 {15_appendix => 16_appendix}/repo/redis.md | 0 {15_appendix => 16_appendix}/repo/ubuntu.md | 0 .../repo/wordpress.md | 0 SUMMARY.md | 248 +++++++++--------- 228 files changed, 326 insertions(+), 271 deletions(-) delete mode 100644 04_image/dockerfile/README.md rename 04_image/dockerfile/workdir.md => 07_dockerfile/7.10_workdir.md (97%) rename 04_image/dockerfile/user.md => 07_dockerfile/7.11_user.md (98%) rename 04_image/dockerfile/healthcheck.md => 07_dockerfile/7.12_healthcheck.md (96%) rename 04_image/dockerfile/onbuild.md => 07_dockerfile/7.13_onbuild.md (97%) rename 04_image/dockerfile/label.md => 07_dockerfile/7.14_label.md (97%) rename 04_image/dockerfile/shell.md => 07_dockerfile/7.15_shell.md (97%) rename 04_image/dockerfile/references.md => 07_dockerfile/7.16_references.md (92%) rename 04_image/dockerfile/run.md => 07_dockerfile/7.1_run.md (97%) rename 04_image/dockerfile/copy.md => 07_dockerfile/7.2_copy.md (98%) rename 04_image/dockerfile/add.md => 07_dockerfile/7.3_add.md (97%) rename 04_image/dockerfile/cmd.md => 07_dockerfile/7.4_cmd.md (98%) rename 04_image/dockerfile/entrypoint.md => 07_dockerfile/7.5_entrypoint.md (98%) rename 04_image/dockerfile/env.md => 07_dockerfile/7.6_env.md (96%) rename 04_image/dockerfile/arg.md => 07_dockerfile/7.7_arg.md (99%) rename 04_image/dockerfile/volume.md => 07_dockerfile/7.8_volume.md (95%) rename 04_image/dockerfile/expose.md => 07_dockerfile/7.9_expose.md (97%) create mode 100644 07_dockerfile/README.md rename {07_data_network => 08_data_network}/README.md (79%) rename {07_data_network => 08_data_network}/data/README.md (100%) rename {07_data_network => 08_data_network}/data/_images/types-of-mounts.png (100%) rename {07_data_network => 08_data_network}/data/bind-mounts.md (98%) rename {07_data_network => 08_data_network}/data/volume.md (99%) rename {07_data_network => 08_data_network}/network/README.md (99%) rename {07_data_network => 08_data_network}/network/dns.md (100%) rename {07_data_network => 08_data_network}/network/port_mapping.md (98%) rename 08_buildx/8.1_buildkit.md => 09_buildx/9.1_buildkit.md (99%) rename 08_buildx/8.2_buildx.md => 09_buildx/9.2_buildx.md (85%) rename 08_buildx/8.3_multi-arch-images.md => 09_buildx/9.3_multi-arch-images.md (98%) rename {08_buildx => 09_buildx}/README.md (53%) rename 09_compose/9.1_introduction.md => 10_compose/10.1_introduction.md (99%) rename 09_compose/9.2_install.md => 10_compose/10.2_install.md (98%) rename 09_compose/9.3_usage.md => 10_compose/10.3_usage.md (99%) rename 09_compose/9.4_commands.md => 10_compose/10.4_commands.md (99%) rename 09_compose/9.5_compose_file.md => 10_compose/10.5_compose_file.md (99%) rename 09_compose/9.6_django.md => 10_compose/10.6_django.md (97%) rename 09_compose/9.7_rails.md => 10_compose/10.7_rails.md (97%) rename 09_compose/9.8_wordpress.md => 10_compose/10.8_wordpress.md (96%) rename 09_compose/9.9_lnmp.md => 10_compose/10.9_lnmp.md (86%) rename {09_compose => 10_compose}/README.md (86%) rename {09_compose => 10_compose}/demo/app/Dockerfile (100%) rename {09_compose => 10_compose}/demo/app/app.py (100%) rename {09_compose => 10_compose}/demo/app/docker-compose.yml (100%) rename {09_compose => 10_compose}/demo/django/.gitignore (100%) rename {09_compose => 10_compose}/demo/django/Dockerfile (100%) rename {09_compose => 10_compose}/demo/django/docker-compose.yml (100%) rename {09_compose => 10_compose}/demo/django/requirements.txt (100%) rename {09_compose => 10_compose}/demo/wordpress/docker-compose.yml (100%) rename {10_ops => 11_ops}/README.md (86%) rename {10_ops => 11_ops}/logs/README.md (100%) rename {10_ops => 11_ops}/logs/elk.md (100%) rename {10_ops => 11_ops}/monitor/README.md (100%) rename {10_ops => 11_ops}/monitor/prometheus.md (100%) rename {10_ops => 11_ops}/security/README.md (97%) rename {10_ops => 11_ops}/security/control_group.md (100%) rename {10_ops => 11_ops}/security/daemon_sec.md (100%) rename {10_ops => 11_ops}/security/kernel_capability.md (100%) rename {10_ops => 11_ops}/security/kernel_ns.md (100%) rename {10_ops => 11_ops}/security/other_feature.md (100%) rename {10_ops => 11_ops}/security/summary.md (100%) rename {11_orchestration => 12_orchestration}/README.md (89%) rename {11_orchestration => 12_orchestration}/etcd/README.md (100%) rename {11_orchestration => 12_orchestration}/etcd/_images/etcd_logo.png (100%) rename {11_orchestration => 12_orchestration}/etcd/cluster.md (100%) rename {11_orchestration => 12_orchestration}/etcd/demo/cluster/docker-compose.yml (100%) rename {11_orchestration => 12_orchestration}/etcd/etcdctl.md (100%) rename {11_orchestration => 12_orchestration}/etcd/install.md (100%) rename {11_orchestration => 12_orchestration}/etcd/intro.md (100%) rename {11_orchestration => 12_orchestration}/kubectl/README.md (100%) rename {11_orchestration => 12_orchestration}/kubernetes/README.md (100%) rename {11_orchestration => 12_orchestration}/kubernetes/_images/k8s-singlenode-docker.png (100%) rename {11_orchestration => 12_orchestration}/kubernetes/_images/k8s_architecture.png (100%) rename {11_orchestration => 12_orchestration}/kubernetes/_images/kube-proxy.png (100%) rename {11_orchestration => 12_orchestration}/kubernetes/_images/kubernetes_design.jpg (100%) rename {11_orchestration => 12_orchestration}/kubernetes/_images/kubernetes_logo.png (100%) rename {11_orchestration => 12_orchestration}/kubernetes/_images/kubernetes_logo.svg (100%) rename {11_orchestration => 12_orchestration}/kubernetes/advanced.md (100%) rename {11_orchestration => 12_orchestration}/kubernetes/concepts.md (100%) rename {11_orchestration => 12_orchestration}/kubernetes/design.md (100%) rename {11_orchestration => 12_orchestration}/kubernetes/intro.md (100%) rename {11_orchestration => 12_orchestration}/kubernetes/practice.md (100%) rename {11_orchestration => 12_orchestration}/setup/README.md (100%) rename {11_orchestration => 12_orchestration}/setup/dashboard.md (100%) rename {11_orchestration => 12_orchestration}/setup/docker-desktop.md (100%) rename {11_orchestration => 12_orchestration}/setup/k3s.md (100%) rename {11_orchestration => 12_orchestration}/setup/kind.md (100%) rename {11_orchestration => 12_orchestration}/setup/kubeadm-docker.md (100%) rename {11_orchestration => 12_orchestration}/setup/kubeadm.md (100%) rename {11_orchestration => 12_orchestration}/setup/systemd.md (100%) rename {12_ecosystem => 13_ecosystem}/README.md (87%) rename {12_ecosystem => 13_ecosystem}/cloud/README.md (100%) rename {12_ecosystem => 13_ecosystem}/cloud/_images/ECS.jpg (100%) rename {12_ecosystem => 13_ecosystem}/cloud/_images/aliyun-logo.png (100%) rename {12_ecosystem => 13_ecosystem}/cloud/_images/aws-logo.jpg (100%) rename {12_ecosystem => 13_ecosystem}/cloud/_images/qcloud-logo.jpg (100%) rename {12_ecosystem => 13_ecosystem}/cloud/alicloud.md (100%) rename {12_ecosystem => 13_ecosystem}/cloud/aws.md (100%) rename {12_ecosystem => 13_ecosystem}/cloud/intro.md (100%) rename {12_ecosystem => 13_ecosystem}/cloud/multicloud.md (100%) rename {12_ecosystem => 13_ecosystem}/cloud/summary.md (100%) rename {12_ecosystem => 13_ecosystem}/cloud/tencentCloud.md (100%) rename {12_ecosystem => 13_ecosystem}/coreos/README.md (100%) rename {12_ecosystem => 13_ecosystem}/coreos/demo/example.fcc (100%) rename {12_ecosystem => 13_ecosystem}/coreos/install.md (100%) rename {12_ecosystem => 13_ecosystem}/coreos/intro.md (100%) rename {12_ecosystem => 13_ecosystem}/podman/README.md (100%) rename 13_implementation/13.1_arch.md => 14_implementation/14.1_arch.md (96%) rename 13_implementation/13.2_namespace.md => 14_implementation/14.2_namespace.md (98%) rename 13_implementation/13.3_cgroups.md => 14_implementation/14.3_cgroups.md (99%) rename 13_implementation/13.4_ufs.md => 14_implementation/14.4_ufs.md (99%) rename 13_implementation/13.5_container_format.md => 14_implementation/14.5_container_format.md (94%) rename 13_implementation/13.6_network.md => 14_implementation/14.6_network.md (99%) rename {13_implementation => 14_implementation}/README.md (98%) rename {13_implementation => 14_implementation}/_images/docker_arch.png (100%) rename {14_cases => 15_cases}/README.md (87%) rename {14_cases => 15_cases}/ci/README.md (100%) rename {14_cases => 15_cases}/ci/actions/README.md (100%) rename {14_cases => 15_cases}/ci/devops_workflow.md (100%) rename {14_cases => 15_cases}/ci/drone/.env.example (100%) rename {14_cases => 15_cases}/ci/drone/.gitignore (100%) rename {14_cases => 15_cases}/ci/drone/README.md (91%) rename {14_cases => 15_cases}/ci/drone/_images/drone-build.png (100%) rename {14_cases => 15_cases}/ci/drone/demo/.drone.yml (100%) rename {14_cases => 15_cases}/ci/drone/demo/README.md (100%) rename {14_cases => 15_cases}/ci/drone/demo/app.go (100%) rename {14_cases => 15_cases}/ci/drone/docker-compose.yml (100%) rename {14_cases => 15_cases}/ci/drone/install.md (100%) rename {14_cases => 15_cases}/ide/README.md (100%) rename {14_cases => 15_cases}/ide/vsCode.md (100%) rename {14_cases => 15_cases}/os/README.md (100%) rename {14_cases => 15_cases}/os/_images/alpinelinux-logo.png (100%) rename {14_cases => 15_cases}/os/_images/busybox-logo.png (100%) rename {14_cases => 15_cases}/os/_images/centos-logo.png (100%) rename {14_cases => 15_cases}/os/_images/coreos-login.png (100%) rename {14_cases => 15_cases}/os/_images/coreos-logo.jpg (100%) rename {14_cases => 15_cases}/os/_images/coreos_crt.png (100%) rename {14_cases => 15_cases}/os/_images/coreos_list.png (100%) rename {14_cases => 15_cases}/os/_images/coreos_run_ip.png (100%) rename {14_cases => 15_cases}/os/_images/debian-logo.png (100%) rename {14_cases => 15_cases}/os/_images/docker_version.png (100%) rename {14_cases => 15_cases}/os/_images/fedora-logo.png (100%) rename {14_cases => 15_cases}/os/_images/php_pulling.png (100%) rename {14_cases => 15_cases}/os/_images/ubuntu-logo.jpg (100%) rename {14_cases => 15_cases}/os/_images/vmware_coreos.png (100%) rename {14_cases => 15_cases}/os/alpine.md (100%) rename {14_cases => 15_cases}/os/busybox.md (100%) rename {14_cases => 15_cases}/os/centos.md (100%) rename {14_cases => 15_cases}/os/debian.md (100%) rename {14_cases => 15_cases}/os/summary.md (100%) rename 15_appendix/15.1_best_practices.md => 16_appendix/16.1_best_practices.md (99%) rename 15_appendix/15.2_debug.md => 16_appendix/16.2_debug.md (98%) rename 15_appendix/15.3_resources.md => 16_appendix/16.3_resources.md (98%) rename {15_appendix => 16_appendix}/README.md (74%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/data.plist (100%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/image10.pdf (100%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/image11.pdf (100%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/image12.pdf (100%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/image13.pdf (100%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/image4.pdf (100%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/image5.pdf (100%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/image6.pdf (100%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/image7.pdf (100%) rename {15_appendix/_images/cmd_logic.graffle => 16_appendix/_images/cmd_logic 2.graffle}/image9.pdf (100%) rename {15_appendix => 16_appendix}/_images/cmd_logic.dot (100%) rename {15_appendix => 16_appendix}/_images/cmd_logic.dot.bak (100%) create mode 100644 16_appendix/_images/cmd_logic.graffle/data.plist create mode 100644 16_appendix/_images/cmd_logic.graffle/image10.pdf create mode 100644 16_appendix/_images/cmd_logic.graffle/image11.pdf create mode 100644 16_appendix/_images/cmd_logic.graffle/image12.pdf create mode 100644 16_appendix/_images/cmd_logic.graffle/image13.pdf create mode 100644 16_appendix/_images/cmd_logic.graffle/image4.pdf create mode 100644 16_appendix/_images/cmd_logic.graffle/image5.pdf create mode 100644 16_appendix/_images/cmd_logic.graffle/image6.pdf create mode 100644 16_appendix/_images/cmd_logic.graffle/image7.pdf create mode 100644 16_appendix/_images/cmd_logic.graffle/image9.pdf rename {15_appendix => 16_appendix}/_images/cmd_logic.png (100%) rename {15_appendix => 16_appendix}/_images/container_status.dot (100%) rename {15_appendix => 16_appendix}/_images/container_status.png (100%) rename {15_appendix => 16_appendix}/command/README.md (100%) rename {15_appendix => 16_appendix}/command/docker.md (100%) rename {15_appendix => 16_appendix}/command/dockerd.md (100%) rename {15_appendix => 16_appendix}/faq/README.md (99%) rename {15_appendix => 16_appendix}/faq/errors.md (100%) rename {15_appendix => 16_appendix}/repo/README.md (100%) rename {15_appendix => 16_appendix}/repo/centos.md (100%) rename {15_appendix => 16_appendix}/repo/minio.md (100%) rename {15_appendix => 16_appendix}/repo/mongodb.md (100%) rename {15_appendix => 16_appendix}/repo/mysql.md (100%) rename {15_appendix => 16_appendix}/repo/nginx.md (100%) rename {15_appendix => 16_appendix}/repo/nodejs.md (100%) rename {15_appendix => 16_appendix}/repo/php.md (100%) rename {15_appendix => 16_appendix}/repo/redis.md (100%) rename {15_appendix => 16_appendix}/repo/ubuntu.md (100%) rename {15_appendix => 16_appendix}/repo/wordpress.md (100%) diff --git a/01_introduction/1.1_quickstart.md b/01_introduction/1.1_quickstart.md index 1961b4a..18eac7e 100644 --- a/01_introduction/1.1_quickstart.md +++ b/01_introduction/1.1_quickstart.md @@ -1,4 +1,4 @@ -## 快速上手(5分钟) +## 1.1 快速上手 本节将通过一个简单的 Web 应用例子,带你快速体验 Docker 的核心流程:构建镜像、运行容器。 diff --git a/01_introduction/1.2_what.md b/01_introduction/1.2_what.md index c072989..ebf82a7 100644 --- a/01_introduction/1.2_what.md +++ b/01_introduction/1.2_what.md @@ -1,4 +1,4 @@ -## 什么是 Docker +## 1.2 什么是 Docker Docker 是彻底改变了软件开发和交付方式的革命性技术。本节将从核心概念、与传统虚拟机的对比、技术基础以及历史生态等多个维度,带你深入理解什么是 Docker。 @@ -77,7 +77,7 @@ Docker 使用 [Go 语言](https://golang.google.cn/) 开发,基于 Linux 内 - **[Cgroups](https://zh.wikipedia.org/wiki/Cgroups)**:实现资源限制(CPU、内存、I/O 等) - **[Union FS](https://en.wikipedia.org/wiki/Union_mount)**:实现分层存储(如 OverlayFS) -> 如果你对这些底层技术感兴趣,可以阅读本书的[底层实现](../13_implementation/README.md)章节。 +> 如果你对这些底层技术感兴趣,可以阅读本书的[底层实现](../14_implementation/README.md)章节。 #### Docker 架构演进 diff --git a/01_introduction/1.3_why.md b/01_introduction/1.3_why.md index cb7ec7b..914cd80 100644 --- a/01_introduction/1.3_why.md +++ b/01_introduction/1.3_why.md @@ -1,4 +1,4 @@ -## 为什么要使用 Docker? +## 1.3 为什么要使用 Docker? 在回答"为什么用 Docker"之前,笔者想先问一个问题:**你有没有经历过这些场景?** @@ -152,7 +152,7 @@ Docker 完美契合 DevOps 的工作流程: 使用 [Dockerfile](../04_image/4.5_build.md) 定义镜像构建过程,使得: - 构建过程**可重复、可追溯** - 任何人都能从代码重建完全相同的镜像 -- 配合 [GitHub Actions](../14_cases/ci/actions/README.md) 等 CI 系统实现自动化 +- 配合 [GitHub Actions](../15_cases/ci/actions/README.md) 等 CI 系统实现自动化 #### 5. 轻松迁移 diff --git a/02_basic_concept/2.1_image.md b/02_basic_concept/2.1_image.md index a24bfb5..5d805d7 100644 --- a/02_basic_concept/2.1_image.md +++ b/02_basic_concept/2.1_image.md @@ -1,4 +1,4 @@ -## Docker 镜像 +## 2.1 Docker 镜像 ## Docker 镜像 @@ -238,5 +238,5 @@ Docker 镜像可以通过以下方式获取: - [获取镜像](../04_image/4.1_pull.md):从 Registry 下载镜像 - [使用 Dockerfile 定制镜像](../04_image/4.5_build.md):创建自己的镜像 -- [Dockerfile 最佳实践](../15_appendix/15.1_best_practices.md):构建高质量镜像的技巧 -- [底层实现 - 联合文件系统](../13_implementation/13.4_ufs.md):深入理解分层存储的技术原理 +- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md):构建高质量镜像的技巧 +- [底层实现 - 联合文件系统](../14_implementation/14.4_ufs.md):深入理解分层存储的技术原理 diff --git a/02_basic_concept/2.2_container.md b/02_basic_concept/2.2_container.md index d53cbbc..3df4169 100644 --- a/02_basic_concept/2.2_container.md +++ b/02_basic_concept/2.2_container.md @@ -1,4 +1,4 @@ -## Docker 容器 +## 2.2 Docker 容器 ## Docker 容器 @@ -137,8 +137,8 @@ $ docker rm abc123 | 方式 | 说明 | 适用场景 | |------|------|---------| -| **[数据卷(Volume)](../07_data_network/data/volume.md)** | Docker 管理的存储 | 数据库、应用数据 | -| **[绑定挂载(Bind Mount)](../07_data_network/data/bind-mounts.md)** | 挂载宿主机目录 | 开发时共享代码 | +| **[数据卷(Volume)](../08_data_network/data/volume.md)** | Docker 管理的存储 | 数据库、应用数据 | +| **[绑定挂载(Bind Mount)](../08_data_network/data/bind-mounts.md)** | 挂载宿主机目录 | 开发时共享代码 | ```bash ## 使用数据卷(推荐) @@ -254,7 +254,7 @@ Docker 容器通过以下 Namespace 实现隔离: | **IPC** | 进程间通信 | 独立的信号量、消息队列 | | **USER** | 用户 | 独立的用户和组 ID | -> 想深入了解?请阅读[底层实现 - 命名空间](../13_implementation/13.2_namespace.md)。 +> 想深入了解?请阅读[底层实现 - 命名空间](../14_implementation/14.2_namespace.md)。 ### 本章小结 @@ -273,4 +273,4 @@ Docker 容器通过以下 Namespace 实现隔离: - [启动容器](../05_container/5.1_run.md):详细的容器启动选项 - [后台运行](../05_container/5.2_daemon.md):理解容器为什么会"立即退出" - [进入容器](../05_container/5.4_attach_exec.md):如何操作运行中的容器 -- [数据管理](../07_data_network/README.md):Volume 和数据持久化详解 +- [数据管理](../08_data_network/README.md):Volume 和数据持久化详解 diff --git a/02_basic_concept/2.3_repository.md b/02_basic_concept/2.3_repository.md index f511549..43383fd 100644 --- a/02_basic_concept/2.3_repository.md +++ b/02_basic_concept/2.3_repository.md @@ -1,4 +1,4 @@ -## Docker Registry +## 2.3 Docker Registry ## Docker Registry diff --git a/03_install/3.10_experimental.md b/03_install/3.10_experimental.md index c8f7bf5..b03eab7 100644 --- a/03_install/3.10_experimental.md +++ b/03_install/3.10_experimental.md @@ -1,4 +1,4 @@ -## 开启实验特性 +## 3.10 开启实验特性 一些 docker 命令或功能仅当 **实验特性** 开启时才能使用,请按照以下方法进行设置。 diff --git a/03_install/3.1_ubuntu.md b/03_install/3.1_ubuntu.md index d1ec12d..3a2399f 100644 --- a/03_install/3.1_ubuntu.md +++ b/03_install/3.1_ubuntu.md @@ -1,4 +1,4 @@ -## Ubuntu 安装 Docker +## 3.1 Ubuntu 安装 Docker ## Ubuntu 安装 Docker diff --git a/03_install/3.2_debian.md b/03_install/3.2_debian.md index b2ebdc4..ab64c0d 100644 --- a/03_install/3.2_debian.md +++ b/03_install/3.2_debian.md @@ -1,4 +1,4 @@ -## Debian 安装 Docker +## 3.2 Debian 安装 Docker ## Debian 安装 Docker diff --git a/03_install/3.3_fedora.md b/03_install/3.3_fedora.md index 38b3720..a7be551 100644 --- a/03_install/3.3_fedora.md +++ b/03_install/3.3_fedora.md @@ -1,4 +1,4 @@ -## Fedora 安装 Docker +## 3.3 Fedora 安装 Docker ## Fedora 安装 Docker diff --git a/03_install/3.4_centos.md b/03_install/3.4_centos.md index caff8ad..98f2116 100644 --- a/03_install/3.4_centos.md +++ b/03_install/3.4_centos.md @@ -1,4 +1,4 @@ -## CentOS 安装 Docker +## 3.4 CentOS 安装 Docker ## CentOS 安装 Docker diff --git a/03_install/3.5_raspberry-pi.md b/03_install/3.5_raspberry-pi.md index ed20285..fb8b289 100644 --- a/03_install/3.5_raspberry-pi.md +++ b/03_install/3.5_raspberry-pi.md @@ -1,4 +1,4 @@ -## 树莓派卡片电脑安装 Docker +## 3.5 树莓派卡片电脑安装 Docker ## 树莓派卡片电脑安装 Docker diff --git a/03_install/3.6_offline.md b/03_install/3.6_offline.md index 329c16b..7ac6687 100644 --- a/03_install/3.6_offline.md +++ b/03_install/3.6_offline.md @@ -1,4 +1,4 @@ -## Linux 离线安装 +## 3.6 Linux 离线安装 \[TOC] diff --git a/03_install/3.7_mac.md b/03_install/3.7_mac.md index 1c9ed93..ecf6e12 100644 --- a/03_install/3.7_mac.md +++ b/03_install/3.7_mac.md @@ -1,4 +1,4 @@ -## macOS +## 3.7 macOS ### 系统要求 diff --git a/03_install/3.8_windows.md b/03_install/3.8_windows.md index a9eb565..dc24480 100644 --- a/03_install/3.8_windows.md +++ b/03_install/3.8_windows.md @@ -1,4 +1,4 @@ -## Windows 10/11 +## 3.8 Windows 10/11 在 Windows 平台上,Docker Desktop 提供了完整的 Docker 开发环境。本节介绍在 Windows 10/11 上的安装和配置。 diff --git a/03_install/3.9_mirror.md b/03_install/3.9_mirror.md index ae337ff..afedc69 100644 --- a/03_install/3.9_mirror.md +++ b/03_install/3.9_mirror.md @@ -1,4 +1,4 @@ -## 镜像加速器 +## 3.9 镜像加速器 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。 diff --git a/04_image/4.1_pull.md b/04_image/4.1_pull.md index 10d9b62..18f0503 100644 --- a/04_image/4.1_pull.md +++ b/04_image/4.1_pull.md @@ -1,4 +1,4 @@ -## 获取镜像 +## 4.1 获取镜像 ## 获取镜像 diff --git a/04_image/4.2_list.md b/04_image/4.2_list.md index cb47e32..040b7b7 100644 --- a/04_image/4.2_list.md +++ b/04_image/4.2_list.md @@ -1,4 +1,4 @@ -## 列出镜像 +## 4.2 列出镜像 ## 列出镜像 diff --git a/04_image/4.3_rm.md b/04_image/4.3_rm.md index 25d3ba5..82a5b7e 100644 --- a/04_image/4.3_rm.md +++ b/04_image/4.3_rm.md @@ -1,4 +1,4 @@ -## 删除本地镜像 +## 4.3 删除本地镜像 当不再需要某个镜像时,我们可以将其删除以释放存储空间。本节介绍删除镜像的常用方法。 @@ -307,4 +307,4 @@ Build Cache 0 0 0B 0B - [列出镜像](4.2_list.md):查看和过滤镜像 - [删除容器](../05_container/4.3_rm.md):清理容器 -- [数据卷](../07_data_network/data/volume.md):清理数据卷 +- [数据卷](../08_data_network/data/volume.md):清理数据卷 diff --git a/04_image/4.4_commit.md b/04_image/4.4_commit.md index 2f2b42c..6cb2e37 100644 --- a/04_image/4.4_commit.md +++ b/04_image/4.4_commit.md @@ -1,4 +1,4 @@ -## 利用 commit 理解镜像构成 +## 4.4 利用 commit 理解镜像构成 > 注意:如果您是初学者,您可以暂时跳过后面的内容,直接学习 [容器](../05_container/) 一节。 diff --git a/04_image/4.5_build.md b/04_image/4.5_build.md index 1fcaffe..1262c33 100644 --- a/04_image/4.5_build.md +++ b/04_image/4.5_build.md @@ -1,4 +1,4 @@ -## 使用 Dockerfile 定制镜像 +## 4.5 使用 Dockerfile 定制镜像 从刚才的 `docker commit` 的学习中,我们可以了解到,镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。 diff --git a/04_image/4.6_other.md b/04_image/4.6_other.md index e304188..360f1e0 100644 --- a/04_image/4.6_other.md +++ b/04_image/4.6_other.md @@ -1,4 +1,4 @@ -## 其它制作镜像的方式 +## 4.6 其它制作镜像的方式 除了标准的使用 `Dockerfile` 生成镜像的方法外,由于各种特殊需求和历史原因,还提供了一些其它方法用以生成镜像。 diff --git a/04_image/4.7_internal.md b/04_image/4.7_internal.md index 4420d7f..0a8633c 100644 --- a/04_image/4.7_internal.md +++ b/04_image/4.7_internal.md @@ -1,4 +1,4 @@ -## 镜像的实现原理 +## 4.7 镜像的实现原理 Docker 镜像是怎么实现增量的修改和维护的? diff --git a/04_image/dockerfile/README.md b/04_image/dockerfile/README.md deleted file mode 100644 index 15f5d4f..0000000 --- a/04_image/dockerfile/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Dockerfile 指令详解 - -我们已经介绍了 `FROM`,`RUN`,还提及了 `COPY`, `ADD`,其实 `Dockerfile` 功能很强大,它提供了十多个指令。下面我们继续讲解其他的指令。 diff --git a/05_container/5.1_run.md b/05_container/5.1_run.md index 88a0aaa..738d758 100644 --- a/05_container/5.1_run.md +++ b/05_container/5.1_run.md @@ -1,4 +1,4 @@ -## 启动容器 +## 5.1 启动容器 本节将详细介绍 Docker 容器的启动方式,包括新建启动和重新启动已停止的容器。 @@ -240,7 +240,7 @@ $ docker run -d -p 80:80 nginx $ docker run -v mydata:/app/data myapp ``` -详见[数据管理](../07_data_network/README.md)。 +详见[数据管理](../08_data_network/README.md)。 ### 本章小结 @@ -256,4 +256,4 @@ $ docker run -v mydata:/app/data myapp - [后台运行](5.2_daemon.md):理解 `-d` 参数和容器生命周期 - [进入容器](5.4_attach_exec.md):操作运行中的容器 - [网络配置](../network/README.md):理解端口映射的原理 -- [数据管理](../07_data_network/README.md):数据持久化方案 +- [数据管理](../08_data_network/README.md):数据持久化方案 diff --git a/05_container/5.2_daemon.md b/05_container/5.2_daemon.md index 80c0083..4d68ada 100644 --- a/05_container/5.2_daemon.md +++ b/05_container/5.2_daemon.md @@ -1,4 +1,4 @@ -## 后台运行 +## 5.2 后台运行 在生产环境中,我们通常需要容器持续运行,不受终端关闭的影响。本节将深入讲解如何让容器在后台运行,以及理解容器生命周期的核心概念。 @@ -240,6 +240,6 @@ $ docker attach mycontainer ### 延伸阅读 - [进入容器](5.4_attach_exec.md):如何进入正在运行的容器执行命令 -- [容器日志](../15_appendix/15.1_best_practices.md):生产环境的日志管理最佳实践 -- [HEALTHCHECK 健康检查](../04_image/dockerfile/healthcheck.md):自动检测容器内服务是否正常 +- [容器日志](../16_appendix/16.1_best_practices.md):生产环境的日志管理最佳实践 +- [HEALTHCHECK 健康检查](../07_dockerfile/7.12_healthcheck.md):自动检测容器内服务是否正常 - [Docker Compose](../compose/README.md):管理多个后台容器的更好方式 diff --git a/05_container/5.3_stop.md b/05_container/5.3_stop.md index 4e2b323..81abd98 100644 --- a/05_container/5.3_stop.md +++ b/05_container/5.3_stop.md @@ -1,4 +1,4 @@ -## 终止容器 +## 5.3 终止容器 本节将介绍如何终止一个运行中的容器,以及几种不同的终止方式及其区别。 diff --git a/05_container/5.4_attach_exec.md b/05_container/5.4_attach_exec.md index 460c946..cd99934 100644 --- a/05_container/5.4_attach_exec.md +++ b/05_container/5.4_attach_exec.md @@ -1,4 +1,4 @@ -## 进入容器 +## 5.4 进入容器 ### 为什么需要进入容器 diff --git a/05_container/5.5_import_export.md b/05_container/5.5_import_export.md index 1cc12e8..1f30bc5 100644 --- a/05_container/5.5_import_export.md +++ b/05_container/5.5_import_export.md @@ -1,4 +1,4 @@ -## 导出和导入容器 +## 5.5 导出和导入容器 当我们需要迁移容器或者备份容器时,可以使用 Docker 的导入和导出功能。本节将介绍这两个命令的使用方法。 diff --git a/05_container/5.6_rm.md b/05_container/5.6_rm.md index e9665de..f727271 100644 --- a/05_container/5.6_rm.md +++ b/05_container/5.6_rm.md @@ -1,4 +1,4 @@ -## 删除容器 +## 5.6 删除容器 随着容器的创建和停止,系统中会积累大量的容器。本节将介绍如何删除不再需要的容器,以及如何清理所有停止的容器。 @@ -280,4 +280,4 @@ $ docker system prune -a --volumes - [终止容器](5.3_stop.md):优雅停止容器 - [删除镜像](../04_image/4.3_rm.md):清理镜像 -- [数据卷](../07_data_network/data/volume.md):数据卷管理 +- [数据卷](../08_data_network/data/volume.md):数据卷管理 diff --git a/06_repository/6.1_dockerhub.md b/06_repository/6.1_dockerhub.md index 702f5bd..9d8f1f8 100644 --- a/06_repository/6.1_dockerhub.md +++ b/06_repository/6.1_dockerhub.md @@ -1,4 +1,4 @@ -## Docker Hub +## 6.1 Docker Hub ### 什么是 Docker Hub diff --git a/06_repository/6.2_registry.md b/06_repository/6.2_registry.md index 1ccef47..92980ef 100644 --- a/06_repository/6.2_registry.md +++ b/06_repository/6.2_registry.md @@ -1,4 +1,4 @@ -## 私有仓库 +## 6.2 私有仓库 有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。 diff --git a/06_repository/6.3_registry_auth.md b/06_repository/6.3_registry_auth.md index 08d4f1c..47db86b 100644 --- a/06_repository/6.3_registry_auth.md +++ b/06_repository/6.3_registry_auth.md @@ -1,4 +1,4 @@ -## 私有仓库高级配置 +## 6.3 私有仓库高级配置 上一节我们搭建了一个具有基础功能的私有仓库,本小节我们来使用 `Docker Compose` 搭建一个拥有权限认证、TLS 的私有仓库。 diff --git a/06_repository/6.4_nexus3_registry.md b/06_repository/6.4_nexus3_registry.md index f254a76..385a42c 100644 --- a/06_repository/6.4_nexus3_registry.md +++ b/06_repository/6.4_nexus3_registry.md @@ -1,4 +1,4 @@ -## Nexus 3 +## 6.4 Nexus 3 使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry。在企业中把内部的一些工具包放入 `Nexus` 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/product/repository-oss-download) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 diff --git a/04_image/dockerfile/workdir.md b/07_dockerfile/7.10_workdir.md similarity index 97% rename from 04_image/dockerfile/workdir.md rename to 07_dockerfile/7.10_workdir.md index d46ca03..616bd6a 100644 --- a/04_image/dockerfile/workdir.md +++ b/07_dockerfile/7.10_workdir.md @@ -1,4 +1,4 @@ -## WORKDIR 指定工作目录 +## 7.10 WORKDIR 指定工作目录 ### 基本语法 @@ -226,4 +226,4 @@ $ docker run -w /tmp myimage pwd - [COPY 复制文件](copy.md):文件复制 - [RUN 执行命令](../../04_image/4.5_build.md):执行构建命令 -- [最佳实践](../../15_appendix/15.1_best_practices.md):Dockerfile 编写指南 +- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南 diff --git a/04_image/dockerfile/user.md b/07_dockerfile/7.11_user.md similarity index 98% rename from 04_image/dockerfile/user.md rename to 07_dockerfile/7.11_user.md index 99aa978..72e09f1 100644 --- a/04_image/dockerfile/user.md +++ b/07_dockerfile/7.11_user.md @@ -1,4 +1,4 @@ -## USER 指定当前用户 +## 7.11 USER 指定当前用户 ### 基本语法 @@ -304,4 +304,4 @@ RUN mkdir -p /app/data && chown appuser:appuser /app/data - [安全](../../security/README.md):容器安全实践 - [ENTRYPOINT](entrypoint.md):入口脚本中的用户切换 -- [最佳实践](../../15_appendix/15.1_best_practices.md):Dockerfile 安全 +- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 安全 diff --git a/04_image/dockerfile/healthcheck.md b/07_dockerfile/7.12_healthcheck.md similarity index 96% rename from 04_image/dockerfile/healthcheck.md rename to 07_dockerfile/7.12_healthcheck.md index e5e79cc..54d2330 100644 --- a/04_image/dockerfile/healthcheck.md +++ b/07_dockerfile/7.12_healthcheck.md @@ -1,4 +1,4 @@ -## HEALTHCHECK 健康检查 +## 7.12 HEALTHCHECK 健康检查 ### 基本语法 @@ -219,5 +219,5 @@ HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1 ### 延伸阅读 - [CMD 容器启动命令](cmd.md):启动主进程 -- [Compose 模板文件](../../compose/9.5_compose_file.md):Compose 中的健康检查 -- [Docker 调试](../../15_appendix/15.2_debug.md):容器排障 +- [Compose 模板文件](../../compose/10.5_compose_file.md):Compose 中的健康检查 +- [Docker 调试](../../16_appendix/16.2_debug.md):容器排障 diff --git a/04_image/dockerfile/onbuild.md b/07_dockerfile/7.13_onbuild.md similarity index 97% rename from 04_image/dockerfile/onbuild.md rename to 07_dockerfile/7.13_onbuild.md index 2aca9a3..d74b633 100644 --- a/04_image/dockerfile/onbuild.md +++ b/07_dockerfile/7.13_onbuild.md @@ -1,4 +1,4 @@ -## ONBUILD 为他人做嫁衣裳 +## 7.13 ONBUILD 为他人做嫁衣裳 ### 基本语法 @@ -166,4 +166,4 @@ python:3.12-onbuild ### 延伸阅读 - [COPY 指令](copy.md):文件复制 -- [Dockerfile 最佳实践](../../15_appendix/15.1_best_practices.md):基础镜像设计 +- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md):基础镜像设计 diff --git a/04_image/dockerfile/label.md b/07_dockerfile/7.14_label.md similarity index 97% rename from 04_image/dockerfile/label.md rename to 07_dockerfile/7.14_label.md index affb587..4431ced 100644 --- a/04_image/dockerfile/label.md +++ b/07_dockerfile/7.14_label.md @@ -1,4 +1,4 @@ -## LABEL 为镜像添加元数据 +## 7.14 LABEL 为镜像添加元数据 ### 基本语法 @@ -164,4 +164,4 @@ $ docker rmi $(docker images -q --filter "label=stage=builder") ### 延伸阅读 - [OCI 标签规范](https://github.com/opencontainers/image-spec/blob/main/annotations.md) -- [Dockerfile 最佳实践](../../15_appendix/15.1_best_practices.md) +- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md) diff --git a/04_image/dockerfile/shell.md b/07_dockerfile/7.15_shell.md similarity index 97% rename from 04_image/dockerfile/shell.md rename to 07_dockerfile/7.15_shell.md index bfce1f4..fb4e92d 100644 --- a/04_image/dockerfile/shell.md +++ b/07_dockerfile/7.15_shell.md @@ -1,4 +1,4 @@ -## SHELL 指令 +## 7.15 SHELL 指令 ### 基本语法 @@ -151,4 +151,4 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"] ### 延伸阅读 - [RUN 指令](../../04_image/4.5_build.md):执行命令 -- [Dockerfile 最佳实践](../../15_appendix/15.1_best_practices.md):错误处理与调试 +- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md):错误处理与调试 diff --git a/04_image/dockerfile/references.md b/07_dockerfile/7.16_references.md similarity index 92% rename from 04_image/dockerfile/references.md rename to 07_dockerfile/7.16_references.md index 5d5974d..a1dfa75 100644 --- a/04_image/dockerfile/references.md +++ b/07_dockerfile/7.16_references.md @@ -1,4 +1,4 @@ -## 参考文档 +## 7.16 参考文档 * `Dockerfile` 官方文档:https://docs.docker.com/engine/reference/builder/ diff --git a/04_image/dockerfile/run.md b/07_dockerfile/7.1_run.md similarity index 97% rename from 04_image/dockerfile/run.md rename to 07_dockerfile/7.1_run.md index 4ed5d96..56b3721 100644 --- a/04_image/dockerfile/run.md +++ b/07_dockerfile/7.1_run.md @@ -1,4 +1,4 @@ -## RUN 执行命令 +## 7.1 RUN 执行命令 ### 基本语法 @@ -191,4 +191,4 @@ RUN --mount=type=secret,id=mysecret \ - [CMD 容器启动命令](cmd.md):容器启动时的命令 - [WORKDIR 指定工作目录](workdir.md):改变目录 -- [Dockerfile 最佳实践](../../15_appendix/15.1_best_practices.md) +- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md) diff --git a/04_image/dockerfile/copy.md b/07_dockerfile/7.2_copy.md similarity index 98% rename from 04_image/dockerfile/copy.md rename to 07_dockerfile/7.2_copy.md index 8b4a631..0121283 100644 --- a/04_image/dockerfile/copy.md +++ b/07_dockerfile/7.2_copy.md @@ -1,4 +1,4 @@ -## COPY 复制文件 +## 7.2 COPY 复制文件 ### 基本语法 @@ -304,4 +304,4 @@ COPY . . - [ADD 指令](add.md):复制和解压 - [WORKDIR 指令](workdir.md):设置工作目录 - [多阶段构建](../multistage-builds.md):优化镜像大小 -- [最佳实践](../../15_appendix/15.1_best_practices.md):Dockerfile 编写指南 +- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南 diff --git a/04_image/dockerfile/add.md b/07_dockerfile/7.3_add.md similarity index 97% rename from 04_image/dockerfile/add.md rename to 07_dockerfile/7.3_add.md index 5a25cb0..23ca6b4 100644 --- a/04_image/dockerfile/add.md +++ b/07_dockerfile/7.3_add.md @@ -1,4 +1,4 @@ -## ADD 更高级的复制文件 +## 7.3 ADD 更高级的复制文件 ### 基本语法 @@ -259,4 +259,4 @@ RUN tar -xzf /tmp/app.tar.gz -C /app && \ - [COPY 复制文件](copy.md):基本复制操作 - [多阶段构建](../multistage-builds.md):减少镜像体积 -- [最佳实践](../../15_appendix/15.1_best_practices.md):Dockerfile 编写指南 +- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南 diff --git a/04_image/dockerfile/cmd.md b/07_dockerfile/7.4_cmd.md similarity index 98% rename from 04_image/dockerfile/cmd.md rename to 07_dockerfile/7.4_cmd.md index 34e1f70..7bddfa2 100644 --- a/04_image/dockerfile/cmd.md +++ b/07_dockerfile/7.4_cmd.md @@ -1,4 +1,4 @@ -## CMD 容器启动命令 +## 7.4 CMD 容器启动命令 ### 什么是 CMD @@ -316,4 +316,4 @@ CMD ["python", "app.py"] - [ENTRYPOINT 入口点](entrypoint.md):固定的启动命令 - [后台运行](../../05_container/5.2_daemon.md):容器前台/后台概念 -- [最佳实践](../../15_appendix/15.1_best_practices.md):Dockerfile 编写指南 +- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南 diff --git a/04_image/dockerfile/entrypoint.md b/07_dockerfile/7.5_entrypoint.md similarity index 98% rename from 04_image/dockerfile/entrypoint.md rename to 07_dockerfile/7.5_entrypoint.md index ed34816..2f1a64f 100644 --- a/04_image/dockerfile/entrypoint.md +++ b/07_dockerfile/7.5_entrypoint.md @@ -1,4 +1,4 @@ -## ENTRYPOINT 入口点 +## 7.5 ENTRYPOINT 入口点 ### 什么是 ENTRYPOINT @@ -347,5 +347,5 @@ wait $PID ### 延伸阅读 - [CMD 容器启动命令](cmd.md):默认命令 -- [最佳实践](../../15_appendix/15.1_best_practices.md):启动命令设计 +- [最佳实践](../../16_appendix/16.1_best_practices.md):启动命令设计 - [后台运行](../../05_container/5.2_daemon.md):前台/后台概念 diff --git a/04_image/dockerfile/env.md b/07_dockerfile/7.6_env.md similarity index 96% rename from 04_image/dockerfile/env.md rename to 07_dockerfile/7.6_env.md index 8050b4a..9a6a425 100644 --- a/04_image/dockerfile/env.md +++ b/07_dockerfile/7.6_env.md @@ -1,4 +1,4 @@ -## ENV 设置环境变量 +## 7.6 ENV 设置环境变量 ### 基本语法 @@ -296,5 +296,5 @@ ENV VAR3=value3 ### 延伸阅读 - [ARG 构建参数](arg.md):构建时变量 -- [Compose 环境变量](../../compose/9.5_compose_file.md):Compose 中的环境变量 -- [最佳实践](../../15_appendix/15.1_best_practices.md):Dockerfile 编写指南 +- [Compose 环境变量](../../compose/10.5_compose_file.md):Compose 中的环境变量 +- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南 diff --git a/04_image/dockerfile/arg.md b/07_dockerfile/7.7_arg.md similarity index 99% rename from 04_image/dockerfile/arg.md rename to 07_dockerfile/7.7_arg.md index 5bc4cd8..7585485 100644 --- a/04_image/dockerfile/arg.md +++ b/07_dockerfile/7.7_arg.md @@ -1,4 +1,4 @@ -## ARG 构建参数 +## 7.7 ARG 构建参数 ### 基本语法 diff --git a/04_image/dockerfile/volume.md b/07_dockerfile/7.8_volume.md similarity index 95% rename from 04_image/dockerfile/volume.md rename to 07_dockerfile/7.8_volume.md index deb6fd6..ac8620c 100644 --- a/04_image/dockerfile/volume.md +++ b/07_dockerfile/7.8_volume.md @@ -1,4 +1,4 @@ -## VOLUME 定义匿名卷 +## 7.8 VOLUME 定义匿名卷 ### 基本语法 @@ -288,6 +288,6 @@ VOLUME /var/lib/mysql ### 延伸阅读 -- [数据卷](../../07_data_network/data/volume.md):卷的管理和使用 -- [挂载主机目录](../../07_data_network/data/bind-mounts.md):Bind Mount -- [Compose 数据管理](../../compose/9.5_compose_file.md):Compose 中的卷配置 +- [数据卷](../../08_data_network/data/volume.md):卷的管理和使用 +- [挂载主机目录](../../08_data_network/data/bind-mounts.md):Bind Mount +- [Compose 数据管理](../../compose/10.5_compose_file.md):Compose 中的卷配置 diff --git a/04_image/dockerfile/expose.md b/07_dockerfile/7.9_expose.md similarity index 97% rename from 04_image/dockerfile/expose.md rename to 07_dockerfile/7.9_expose.md index 2f595e8..3054026 100644 --- a/04_image/dockerfile/expose.md +++ b/07_dockerfile/7.9_expose.md @@ -1,4 +1,4 @@ -## EXPOSE 声明端口 +## 7.9 EXPOSE 声明端口 ### 基本语法 @@ -258,4 +258,4 @@ services: - [网络配置](../../network/README.md):Docker 网络详解 - [端口映射](../../network/port_bindingbindingbinding.md):-p 参数详解 -- [Compose 端口](../../compose/9.5_compose_file.md):Compose 中的端口配置 +- [Compose 端口](../../compose/10.5_compose_file.md):Compose 中的端口配置 diff --git a/07_dockerfile/README.md b/07_dockerfile/README.md new file mode 100644 index 0000000..6827177 --- /dev/null +++ b/07_dockerfile/README.md @@ -0,0 +1,58 @@ +# 第七章 Dockerfile 指令详解 + +## 什么是 Dockerfile + +Dockerfile 是一个文本文件,其內包含了一条条的 **指令(Instruction)**,每一条指令构建一层,therefore 每一条指令的内容,就是描述该层应当如何构建。 + +在 [第四章](04_image/README.md) 中,我们通过 `docker commit` 学习了镜像的构成。但是,手动 `commit` 只能作为临时修补,并不适合作为生产环境镜像的构建方式。 + +使用 Dockerfile 构建镜像有以下优势: + +* **自动化**:可以通过 `docker build` 命令自动构建镜像。 +* **可重复性**:由于 Dockerfile 是文本文件,可以确保每次构建的结果一致。 +* **版本控制**:Dockerfile 可以纳入版本控制系统(如 Git),便于追踪变更。 +* **透明性**:任何人都可以通过阅读 Dockerfile 了解镜像的构建过程。 + +## Dockerfile 基本结构 + +Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。 + +### 指令详解 + +本章将详细讲解 Dockerfile 中的各个指令: + +* [COPY 复制文件](7.2_copy.md) +* [ADD 更高级的复制文件](7.3_add.md) +* [CMD 容器启动命令](7.4_cmd.md) +* [ENTRYPOINT 入口点](7.5_entrypoint.md) +* [ENV 设置环境变量](7.6_env.md) +* [ARG 构建参数](7.7_arg.md) +* [VOLUME 定义匿名卷](7.8_volume.md) +* [EXPOSE 暴露端口](7.9_expose.md) +* [WORKDIR 指定工作目录](7.10_workdir.md) +* [USER 指定当前用户](7.11_user.md) +* [HEALTHCHECK 健康检查](7.12_healthcheck.md) +* [ONBUILD 为他人作嫁衣裳](7.13_onbuild.md) +* [LABEL 为镜像添加元数据](7.14_label.md) +* [SHELL 指令](7.15_shell.md) +* [RUN 执行命令](5.1_run.md) + +此外,我们还将介绍 Dockerfile 的最佳实践和常见问题。 + +* [参考文档](7.16_references.md) + +## 使用 Dockerfile 构建镜像 + +构建镜像的基本命令格式为: + +```bash +docker build [选项] <上下文路径/URL/-> +``` + +例如,在 Dockerfile 所在目录执行: + +```bash +docker build -t my-image:v1 . +``` + +更多关于 `docker build` 的用法,我们在实战中会结合具体指令进行演示。 diff --git a/07_data_network/README.md b/08_data_network/README.md similarity index 79% rename from 07_data_network/README.md rename to 08_data_network/README.md index bf4960f..11686c1 100644 --- a/07_data_network/README.md +++ b/08_data_network/README.md @@ -1,4 +1,4 @@ -# 第七章 数据与网络管理 +# 第八章 数据与网络管理 本章将介绍 Docker 中的数据管理与网络配置。 diff --git a/07_data_network/data/README.md b/08_data_network/data/README.md similarity index 100% rename from 07_data_network/data/README.md rename to 08_data_network/data/README.md diff --git a/07_data_network/data/_images/types-of-mounts.png b/08_data_network/data/_images/types-of-mounts.png similarity index 100% rename from 07_data_network/data/_images/types-of-mounts.png rename to 08_data_network/data/_images/types-of-mounts.png diff --git a/07_data_network/data/bind-mounts.md b/08_data_network/data/bind-mounts.md similarity index 98% rename from 07_data_network/data/bind-mounts.md rename to 08_data_network/data/bind-mounts.md index 616e83f..c775586 100644 --- a/07_data_network/data/bind-mounts.md +++ b/08_data_network/data/bind-mounts.md @@ -329,4 +329,4 @@ $ docker run -v /app/data:/data ... - [数据卷](volume.md):Docker 管理的持久化存储 - [tmpfs 挂载](tmpfs.md):内存临时存储 -- [Compose 数据管理](../compose/9.5_compose_file.md):Compose 中的挂载配置 +- [Compose 数据管理](../compose/10.5_compose_file.md):Compose 中的挂载配置 diff --git a/07_data_network/data/volume.md b/08_data_network/data/volume.md similarity index 99% rename from 07_data_network/data/volume.md rename to 08_data_network/data/volume.md index 69caf7c..ba3b31a 100644 --- a/07_data_network/data/volume.md +++ b/08_data_network/data/volume.md @@ -417,4 +417,4 @@ $ docker volume inspect my-vol - [绑定挂载](bind-mounts.md):挂载宿主机目录 - [tmpfs 挂载](tmpfs.md):内存中的临时存储 -- [存储驱动](../13_implementation/13.4_ufs.md):Docker 存储的底层原理 +- [存储驱动](../14_implementation/14.4_ufs.md):Docker 存储的底层原理 diff --git a/07_data_network/network/README.md b/08_data_network/network/README.md similarity index 99% rename from 07_data_network/network/README.md rename to 08_data_network/network/README.md index 8fd99a8..9cce98e 100644 --- a/07_data_network/network/README.md +++ b/08_data_network/network/README.md @@ -330,4 +330,4 @@ $ docker network prune - [高级网络配置](linking.md):容器互联详解 - [配置 DNS](dns.md):自定义 DNS 设置 - [端口映射](port_mapping.md):高级端口配置 -- [Compose 网络](../compose/9.5_compose_file.md):Compose 中的网络配置 +- [Compose 网络](../compose/10.5_compose_file.md):Compose 中的网络配置 diff --git a/07_data_network/network/dns.md b/08_data_network/network/dns.md similarity index 100% rename from 07_data_network/network/dns.md rename to 08_data_network/network/dns.md diff --git a/07_data_network/network/port_mapping.md b/08_data_network/network/port_mapping.md similarity index 98% rename from 07_data_network/network/port_mapping.md rename to 08_data_network/network/port_mapping.md index 1aa85c9..6eae7d0 100644 --- a/07_data_network/network/port_mapping.md +++ b/08_data_network/network/port_mapping.md @@ -164,5 +164,5 @@ iptables -t nat -A DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0. ### 延伸阅读 -- [EXPOSE 指令](../04_image/dockerfile/expose.md):在 Dockerfile 中声明端口 +- [EXPOSE 指令](../07_dockerfile/7.9_expose.md):在 Dockerfile 中声明端口 - [网络模式](README.md):Host 模式不需要端口映射 diff --git a/08_buildx/8.1_buildkit.md b/09_buildx/9.1_buildkit.md similarity index 99% rename from 08_buildx/8.1_buildkit.md rename to 09_buildx/9.1_buildkit.md index aaad475..1d5cccd 100644 --- a/08_buildx/8.1_buildkit.md +++ b/09_buildx/9.1_buildkit.md @@ -1,4 +1,4 @@ -## 使用 `BuildKit` 构建镜像 +## 9.1 使用 `BuildKit` 构建镜像 **BuildKit** 是下一代的镜像构建组件,在 https://github.com/moby/buildkit 开源。 diff --git a/08_buildx/8.2_buildx.md b/09_buildx/9.2_buildx.md similarity index 85% rename from 08_buildx/8.2_buildx.md rename to 09_buildx/9.2_buildx.md index 31da56e..61f44e2 100644 --- a/08_buildx/8.2_buildx.md +++ b/09_buildx/9.2_buildx.md @@ -1,4 +1,4 @@ -## 使用 Buildx 构建镜像 +## 9.2 使用 Buildx 构建镜像 ### 使用 @@ -12,7 +12,7 @@ $ docker buildx build . => ... ``` -Buildx 使用 [BuildKit 引擎](8.1_buildkit.md) 进行构建,支持许多新的功能,具体参考 [Buildkit](8.1_buildkit.md) 一节。 +Buildx 使用 [BuildKit 引擎](9.1_buildkit.md) 进行构建,支持许多新的功能,具体参考 [Buildkit](9.1_buildkit.md) 一节。 #### 使用 `bake` diff --git a/08_buildx/8.3_multi-arch-images.md b/09_buildx/9.3_multi-arch-images.md similarity index 98% rename from 08_buildx/8.3_multi-arch-images.md rename to 09_buildx/9.3_multi-arch-images.md index be31708..8789138 100644 --- a/08_buildx/8.3_multi-arch-images.md +++ b/09_buildx/9.3_multi-arch-images.md @@ -1,4 +1,4 @@ -## 构建多种系统架构支持的 Docker 镜像 +## 9.3 构建多种系统架构支持的 Docker 镜像 Docker 镜像可以支持多种系统架构,这意味着你可以在 `x86_64`、`arm64` 等不同架构的机器上运行同一个镜像。这是通过一个名为 "manifest list"(或称为 "fat manifest")的文件来实现的。 diff --git a/08_buildx/README.md b/09_buildx/README.md similarity index 53% rename from 08_buildx/README.md rename to 09_buildx/README.md index 70fda46..92aa0ed 100644 --- a/08_buildx/README.md +++ b/09_buildx/README.md @@ -1,6 +1,6 @@ -# 第八章 Docker Buildx +# 第九章 Docker Buildx -Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 [Moby BuildKit](8.1_buildkit.md) 提供的功能。提供了与 docker build 相同的用户体验,并增加了许多新功能。 +Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 [Moby BuildKit](9.1_buildkit.md) 提供的功能。提供了与 docker build 相同的用户体验,并增加了许多新功能。 > 该功能仅适用于 Docker v19.03+ 版本 @@ -8,6 +8,6 @@ Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 本章将详细介绍 Docker Buildx 的使用,包括: -* [使用 BuildKit 构建镜像](8.1_buildkit.md) -* [使用 Buildx 构建镜像](8.2_buildx.md) -* [构建多种系统架构支持的 Docker 镜像](8.3_multi-arch-images.md) +* [使用 BuildKit 构建镜像](9.1_buildkit.md) +* [使用 Buildx 构建镜像](9.2_buildx.md) +* [构建多种系统架构支持的 Docker 镜像](9.3_multi-arch-images.md) diff --git a/09_compose/9.1_introduction.md b/10_compose/10.1_introduction.md similarity index 99% rename from 09_compose/9.1_introduction.md rename to 10_compose/10.1_introduction.md index b13dd86..cc26b9b 100644 --- a/09_compose/9.1_introduction.md +++ b/10_compose/10.1_introduction.md @@ -1,4 +1,4 @@ -## Compose 简介 +## 10.1 Compose 简介 `Compose` 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。从功能上看,跟 `OpenStack` 中的 `Heat` 十分类似。 diff --git a/09_compose/9.2_install.md b/10_compose/10.2_install.md similarity index 98% rename from 09_compose/9.2_install.md rename to 10_compose/10.2_install.md index 51e82a6..a7f455d 100644 --- a/09_compose/9.2_install.md +++ b/10_compose/10.2_install.md @@ -1,4 +1,4 @@ -## 安装与卸载 +## 10.2 安装与卸载 `Compose` 是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。 diff --git a/09_compose/9.3_usage.md b/10_compose/10.3_usage.md similarity index 99% rename from 09_compose/9.3_usage.md rename to 10_compose/10.3_usage.md index f54d765..0284056 100644 --- a/09_compose/9.3_usage.md +++ b/10_compose/10.3_usage.md @@ -1,4 +1,4 @@ -## 使用 +## 10.3 使用 本节将通过一个具体的 Web 应用案例,介绍 Docker Compose 的基本概念和使用方法。 diff --git a/09_compose/9.4_commands.md b/10_compose/10.4_commands.md similarity index 99% rename from 09_compose/9.4_commands.md rename to 10_compose/10.4_commands.md index ac07f18..f0ad198 100644 --- a/09_compose/9.4_commands.md +++ b/10_compose/10.4_commands.md @@ -1,4 +1,4 @@ -## Compose 命令说明 +## 10.4 Compose 命令说明 Docker Compose 提供了丰富的命令来管理项目和容器。本节将详细介绍这些命令的使用格式和常用选项。 diff --git a/09_compose/9.5_compose_file.md b/10_compose/10.5_compose_file.md similarity index 99% rename from 09_compose/9.5_compose_file.md rename to 10_compose/10.5_compose_file.md index 57a37cc..9ccd39c 100644 --- a/09_compose/9.5_compose_file.md +++ b/10_compose/10.5_compose_file.md @@ -1,4 +1,4 @@ -## Compose 模板文件 +## 10.5 Compose 模板文件 模板文件是使用 `Compose` 的核心,涉及到的指令关键字也比较多。但大家不用担心,这里面大部分指令跟 `docker run` 相关参数的含义都是类似的。 diff --git a/09_compose/9.6_django.md b/10_compose/10.6_django.md similarity index 97% rename from 09_compose/9.6_django.md rename to 10_compose/10.6_django.md index 3859ea3..1042bb1 100644 --- a/09_compose/9.6_django.md +++ b/10_compose/10.6_django.md @@ -1,4 +1,4 @@ -## 使用 Django +## 10.6 使用 Django > 本小节内容适合 `Python` 开发人员阅读。 @@ -360,7 +360,7 @@ services: ### 延伸阅读 -- [Compose 模板文件详解](9.5_compose_file.md):深入理解 docker-compose.yml 的所有配置项 -- [使用 WordPress](9.8_wordpress.md):另一个 Compose 实战案例 -- [Dockerfile 最佳实践](../15_appendix/15.1_best_practices.md):构建更小、更安全的镜像 -- [数据管理](../07_data_network/README.md):Volume 和数据持久化详解 +- [Compose 模板文件详解](10.5_compose_file.md):深入理解 docker-compose.yml 的所有配置项 +- [使用 WordPress](10.8_wordpress.md):另一个 Compose 实战案例 +- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md):构建更小、更安全的镜像 +- [数据管理](../08_data_network/README.md):Volume 和数据持久化详解 diff --git a/09_compose/9.7_rails.md b/10_compose/10.7_rails.md similarity index 97% rename from 09_compose/9.7_rails.md rename to 10_compose/10.7_rails.md index 4a6ac3c..631aeb5 100644 --- a/09_compose/9.7_rails.md +++ b/10_compose/10.7_rails.md @@ -1,4 +1,4 @@ -## 使用 Rails +## 10.7 使用 Rails > 本小节内容适合 Ruby 开发人员阅读。 @@ -282,6 +282,6 @@ $ docker compose run --rm web bundle update ### 延伸阅读 -- [使用 Django](9.6_django.md):Python Web 框架实战 -- [Compose 模板文件](9.5_compose_file.md):配置详解 -- [数据管理](../07_data_network/README.md):数据持久化 +- [使用 Django](10.6_django.md):Python Web 框架实战 +- [Compose 模板文件](10.5_compose_file.md):配置详解 +- [数据管理](../08_data_network/README.md):数据持久化 diff --git a/09_compose/9.8_wordpress.md b/10_compose/10.8_wordpress.md similarity index 96% rename from 09_compose/9.8_wordpress.md rename to 10_compose/10.8_wordpress.md index f0a67ae..2fd1788 100644 --- a/09_compose/9.8_wordpress.md +++ b/10_compose/10.8_wordpress.md @@ -1,4 +1,4 @@ -## 实战 WordPress +## 10.8 实战 WordPress WordPress 是全球最流行的内容管理系统(CMS)。使用 Docker Compose 可以在几分钟内搭建一个包含数据库、Web 服务和持久化存储的生产级 WordPress 环境。 @@ -206,6 +206,6 @@ $ docker compose restart wordpress ### 延伸阅读 -- [Compose 模板文件](9.5_compose_file.md):深入了解配置项 -- [数据卷](../07_data_network/data/volume.md):理解数据持久化 +- [Compose 模板文件](10.5_compose_file.md):深入了解配置项 +- [数据卷](../08_data_network/data/volume.md):理解数据持久化 - [Docker Hub WordPress](https://hub.docker.com/_/wordpress):官方镜像文档 diff --git a/09_compose/9.9_lnmp.md b/10_compose/10.9_lnmp.md similarity index 86% rename from 09_compose/9.9_lnmp.md rename to 10_compose/10.9_lnmp.md index 1325534..bc98151 100644 --- a/09_compose/9.9_lnmp.md +++ b/10_compose/10.9_lnmp.md @@ -1,3 +1,3 @@ -## 使用 compose 搭建 LNMP 环境 +## 10.9 使用 compose 搭建 LNMP 环境 本项目的维护者 [khs1994](https://github.com/khs1994) 的开源项目 [khs1994-docker/lnmp](https://github.com/khs1994-docker/lnmp) 使用 Docker Compose 搭建了一套 LNMP 环境,各位开发者可以参考该项目在 Docker 或 Kubernetes 中运行 LNMP。 diff --git a/09_compose/README.md b/10_compose/README.md similarity index 86% rename from 09_compose/README.md rename to 10_compose/README.md index 159f151..cedd276 100644 --- a/09_compose/README.md +++ b/10_compose/README.md @@ -1,4 +1,4 @@ -# 第九章 Docker Compose +# 第十章 Docker Compose `Docker Compose` 是 Docker 官方编排(Orchestration)项目之一,负责快速的部署分布式应用。 diff --git a/09_compose/demo/app/Dockerfile b/10_compose/demo/app/Dockerfile similarity index 100% rename from 09_compose/demo/app/Dockerfile rename to 10_compose/demo/app/Dockerfile diff --git a/09_compose/demo/app/app.py b/10_compose/demo/app/app.py similarity index 100% rename from 09_compose/demo/app/app.py rename to 10_compose/demo/app/app.py diff --git a/09_compose/demo/app/docker-compose.yml b/10_compose/demo/app/docker-compose.yml similarity index 100% rename from 09_compose/demo/app/docker-compose.yml rename to 10_compose/demo/app/docker-compose.yml diff --git a/09_compose/demo/django/.gitignore b/10_compose/demo/django/.gitignore similarity index 100% rename from 09_compose/demo/django/.gitignore rename to 10_compose/demo/django/.gitignore diff --git a/09_compose/demo/django/Dockerfile b/10_compose/demo/django/Dockerfile similarity index 100% rename from 09_compose/demo/django/Dockerfile rename to 10_compose/demo/django/Dockerfile diff --git a/09_compose/demo/django/docker-compose.yml b/10_compose/demo/django/docker-compose.yml similarity index 100% rename from 09_compose/demo/django/docker-compose.yml rename to 10_compose/demo/django/docker-compose.yml diff --git a/09_compose/demo/django/requirements.txt b/10_compose/demo/django/requirements.txt similarity index 100% rename from 09_compose/demo/django/requirements.txt rename to 10_compose/demo/django/requirements.txt diff --git a/09_compose/demo/wordpress/docker-compose.yml b/10_compose/demo/wordpress/docker-compose.yml similarity index 100% rename from 09_compose/demo/wordpress/docker-compose.yml rename to 10_compose/demo/wordpress/docker-compose.yml diff --git a/10_ops/README.md b/11_ops/README.md similarity index 86% rename from 10_ops/README.md rename to 11_ops/README.md index 05671ac..11ffc23 100644 --- a/10_ops/README.md +++ b/11_ops/README.md @@ -1,4 +1,4 @@ -# 第十章 运维管理 +# 第十一章 运维管理 本章将介绍 Docker 的运维管理,包括监控、日志与安全。 diff --git a/10_ops/logs/README.md b/11_ops/logs/README.md similarity index 100% rename from 10_ops/logs/README.md rename to 11_ops/logs/README.md diff --git a/10_ops/logs/elk.md b/11_ops/logs/elk.md similarity index 100% rename from 10_ops/logs/elk.md rename to 11_ops/logs/elk.md diff --git a/10_ops/monitor/README.md b/11_ops/monitor/README.md similarity index 100% rename from 10_ops/monitor/README.md rename to 11_ops/monitor/README.md diff --git a/10_ops/monitor/prometheus.md b/11_ops/monitor/prometheus.md similarity index 100% rename from 10_ops/monitor/prometheus.md rename to 11_ops/monitor/prometheus.md diff --git a/10_ops/security/README.md b/11_ops/security/README.md similarity index 97% rename from 10_ops/security/README.md rename to 11_ops/security/README.md index 4481999..6d5d1df 100644 --- a/10_ops/security/README.md +++ b/11_ops/security/README.md @@ -38,7 +38,7 @@ | IPC | 进程通信 | 隔离共享内存 | | UTS | 主机名 | 独立主机名 | -详见 [命名空间](../13_implementation/13.2_namespace.md) 章节。 +详见 [命名空间](../14_implementation/14.2_namespace.md) 章节。 ### 2. 控制组(Cgroups) @@ -393,6 +393,6 @@ $ cosign verify --key cosign.pub myimage:tag ## 延伸阅读 -- [命名空间](../13_implementation/13.2_namespace.md):隔离机制详解 -- [控制组](../13_implementation/13.3_cgroups.md):资源限制详解 -- [最佳实践](../15_appendix/15.1_best_practices.md):Dockerfile 安全配置 +- [命名空间](../14_implementation/14.2_namespace.md):隔离机制详解 +- [控制组](../14_implementation/14.3_cgroups.md):资源限制详解 +- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 安全配置 diff --git a/10_ops/security/control_group.md b/11_ops/security/control_group.md similarity index 100% rename from 10_ops/security/control_group.md rename to 11_ops/security/control_group.md diff --git a/10_ops/security/daemon_sec.md b/11_ops/security/daemon_sec.md similarity index 100% rename from 10_ops/security/daemon_sec.md rename to 11_ops/security/daemon_sec.md diff --git a/10_ops/security/kernel_capability.md b/11_ops/security/kernel_capability.md similarity index 100% rename from 10_ops/security/kernel_capability.md rename to 11_ops/security/kernel_capability.md diff --git a/10_ops/security/kernel_ns.md b/11_ops/security/kernel_ns.md similarity index 100% rename from 10_ops/security/kernel_ns.md rename to 11_ops/security/kernel_ns.md diff --git a/10_ops/security/other_feature.md b/11_ops/security/other_feature.md similarity index 100% rename from 10_ops/security/other_feature.md rename to 11_ops/security/other_feature.md diff --git a/10_ops/security/summary.md b/11_ops/security/summary.md similarity index 100% rename from 10_ops/security/summary.md rename to 11_ops/security/summary.md diff --git a/11_orchestration/README.md b/12_orchestration/README.md similarity index 89% rename from 11_orchestration/README.md rename to 12_orchestration/README.md index cf2cda0..c57b4c2 100644 --- a/11_orchestration/README.md +++ b/12_orchestration/README.md @@ -1,4 +1,4 @@ -# 第十一章 容器编排 +# 第十二章 容器编排 本章将介绍容器编排相关的技术与工具。 diff --git a/11_orchestration/etcd/README.md b/12_orchestration/etcd/README.md similarity index 100% rename from 11_orchestration/etcd/README.md rename to 12_orchestration/etcd/README.md diff --git a/11_orchestration/etcd/_images/etcd_logo.png b/12_orchestration/etcd/_images/etcd_logo.png similarity index 100% rename from 11_orchestration/etcd/_images/etcd_logo.png rename to 12_orchestration/etcd/_images/etcd_logo.png diff --git a/11_orchestration/etcd/cluster.md b/12_orchestration/etcd/cluster.md similarity index 100% rename from 11_orchestration/etcd/cluster.md rename to 12_orchestration/etcd/cluster.md diff --git a/11_orchestration/etcd/demo/cluster/docker-compose.yml b/12_orchestration/etcd/demo/cluster/docker-compose.yml similarity index 100% rename from 11_orchestration/etcd/demo/cluster/docker-compose.yml rename to 12_orchestration/etcd/demo/cluster/docker-compose.yml diff --git a/11_orchestration/etcd/etcdctl.md b/12_orchestration/etcd/etcdctl.md similarity index 100% rename from 11_orchestration/etcd/etcdctl.md rename to 12_orchestration/etcd/etcdctl.md diff --git a/11_orchestration/etcd/install.md b/12_orchestration/etcd/install.md similarity index 100% rename from 11_orchestration/etcd/install.md rename to 12_orchestration/etcd/install.md diff --git a/11_orchestration/etcd/intro.md b/12_orchestration/etcd/intro.md similarity index 100% rename from 11_orchestration/etcd/intro.md rename to 12_orchestration/etcd/intro.md diff --git a/11_orchestration/kubectl/README.md b/12_orchestration/kubectl/README.md similarity index 100% rename from 11_orchestration/kubectl/README.md rename to 12_orchestration/kubectl/README.md diff --git a/11_orchestration/kubernetes/README.md b/12_orchestration/kubernetes/README.md similarity index 100% rename from 11_orchestration/kubernetes/README.md rename to 12_orchestration/kubernetes/README.md diff --git a/11_orchestration/kubernetes/_images/k8s-singlenode-docker.png b/12_orchestration/kubernetes/_images/k8s-singlenode-docker.png similarity index 100% rename from 11_orchestration/kubernetes/_images/k8s-singlenode-docker.png rename to 12_orchestration/kubernetes/_images/k8s-singlenode-docker.png diff --git a/11_orchestration/kubernetes/_images/k8s_architecture.png b/12_orchestration/kubernetes/_images/k8s_architecture.png similarity index 100% rename from 11_orchestration/kubernetes/_images/k8s_architecture.png rename to 12_orchestration/kubernetes/_images/k8s_architecture.png diff --git a/11_orchestration/kubernetes/_images/kube-proxy.png b/12_orchestration/kubernetes/_images/kube-proxy.png similarity index 100% rename from 11_orchestration/kubernetes/_images/kube-proxy.png rename to 12_orchestration/kubernetes/_images/kube-proxy.png diff --git a/11_orchestration/kubernetes/_images/kubernetes_design.jpg b/12_orchestration/kubernetes/_images/kubernetes_design.jpg similarity index 100% rename from 11_orchestration/kubernetes/_images/kubernetes_design.jpg rename to 12_orchestration/kubernetes/_images/kubernetes_design.jpg diff --git a/11_orchestration/kubernetes/_images/kubernetes_logo.png b/12_orchestration/kubernetes/_images/kubernetes_logo.png similarity index 100% rename from 11_orchestration/kubernetes/_images/kubernetes_logo.png rename to 12_orchestration/kubernetes/_images/kubernetes_logo.png diff --git a/11_orchestration/kubernetes/_images/kubernetes_logo.svg b/12_orchestration/kubernetes/_images/kubernetes_logo.svg similarity index 100% rename from 11_orchestration/kubernetes/_images/kubernetes_logo.svg rename to 12_orchestration/kubernetes/_images/kubernetes_logo.svg diff --git a/11_orchestration/kubernetes/advanced.md b/12_orchestration/kubernetes/advanced.md similarity index 100% rename from 11_orchestration/kubernetes/advanced.md rename to 12_orchestration/kubernetes/advanced.md diff --git a/11_orchestration/kubernetes/concepts.md b/12_orchestration/kubernetes/concepts.md similarity index 100% rename from 11_orchestration/kubernetes/concepts.md rename to 12_orchestration/kubernetes/concepts.md diff --git a/11_orchestration/kubernetes/design.md b/12_orchestration/kubernetes/design.md similarity index 100% rename from 11_orchestration/kubernetes/design.md rename to 12_orchestration/kubernetes/design.md diff --git a/11_orchestration/kubernetes/intro.md b/12_orchestration/kubernetes/intro.md similarity index 100% rename from 11_orchestration/kubernetes/intro.md rename to 12_orchestration/kubernetes/intro.md diff --git a/11_orchestration/kubernetes/practice.md b/12_orchestration/kubernetes/practice.md similarity index 100% rename from 11_orchestration/kubernetes/practice.md rename to 12_orchestration/kubernetes/practice.md diff --git a/11_orchestration/setup/README.md b/12_orchestration/setup/README.md similarity index 100% rename from 11_orchestration/setup/README.md rename to 12_orchestration/setup/README.md diff --git a/11_orchestration/setup/dashboard.md b/12_orchestration/setup/dashboard.md similarity index 100% rename from 11_orchestration/setup/dashboard.md rename to 12_orchestration/setup/dashboard.md diff --git a/11_orchestration/setup/docker-desktop.md b/12_orchestration/setup/docker-desktop.md similarity index 100% rename from 11_orchestration/setup/docker-desktop.md rename to 12_orchestration/setup/docker-desktop.md diff --git a/11_orchestration/setup/k3s.md b/12_orchestration/setup/k3s.md similarity index 100% rename from 11_orchestration/setup/k3s.md rename to 12_orchestration/setup/k3s.md diff --git a/11_orchestration/setup/kind.md b/12_orchestration/setup/kind.md similarity index 100% rename from 11_orchestration/setup/kind.md rename to 12_orchestration/setup/kind.md diff --git a/11_orchestration/setup/kubeadm-docker.md b/12_orchestration/setup/kubeadm-docker.md similarity index 100% rename from 11_orchestration/setup/kubeadm-docker.md rename to 12_orchestration/setup/kubeadm-docker.md diff --git a/11_orchestration/setup/kubeadm.md b/12_orchestration/setup/kubeadm.md similarity index 100% rename from 11_orchestration/setup/kubeadm.md rename to 12_orchestration/setup/kubeadm.md diff --git a/11_orchestration/setup/systemd.md b/12_orchestration/setup/systemd.md similarity index 100% rename from 11_orchestration/setup/systemd.md rename to 12_orchestration/setup/systemd.md diff --git a/12_ecosystem/README.md b/13_ecosystem/README.md similarity index 87% rename from 12_ecosystem/README.md rename to 13_ecosystem/README.md index a3000a7..ba56192 100644 --- a/12_ecosystem/README.md +++ b/13_ecosystem/README.md @@ -1,4 +1,4 @@ -# 第十二章 容器生态 +# 第十三章 容器生态 本章将介绍容器生态圈的相关项目与服务。 diff --git a/12_ecosystem/cloud/README.md b/13_ecosystem/cloud/README.md similarity index 100% rename from 12_ecosystem/cloud/README.md rename to 13_ecosystem/cloud/README.md diff --git a/12_ecosystem/cloud/_images/ECS.jpg b/13_ecosystem/cloud/_images/ECS.jpg similarity index 100% rename from 12_ecosystem/cloud/_images/ECS.jpg rename to 13_ecosystem/cloud/_images/ECS.jpg diff --git a/12_ecosystem/cloud/_images/aliyun-logo.png b/13_ecosystem/cloud/_images/aliyun-logo.png similarity index 100% rename from 12_ecosystem/cloud/_images/aliyun-logo.png rename to 13_ecosystem/cloud/_images/aliyun-logo.png diff --git a/12_ecosystem/cloud/_images/aws-logo.jpg b/13_ecosystem/cloud/_images/aws-logo.jpg similarity index 100% rename from 12_ecosystem/cloud/_images/aws-logo.jpg rename to 13_ecosystem/cloud/_images/aws-logo.jpg diff --git a/12_ecosystem/cloud/_images/qcloud-logo.jpg b/13_ecosystem/cloud/_images/qcloud-logo.jpg similarity index 100% rename from 12_ecosystem/cloud/_images/qcloud-logo.jpg rename to 13_ecosystem/cloud/_images/qcloud-logo.jpg diff --git a/12_ecosystem/cloud/alicloud.md b/13_ecosystem/cloud/alicloud.md similarity index 100% rename from 12_ecosystem/cloud/alicloud.md rename to 13_ecosystem/cloud/alicloud.md diff --git a/12_ecosystem/cloud/aws.md b/13_ecosystem/cloud/aws.md similarity index 100% rename from 12_ecosystem/cloud/aws.md rename to 13_ecosystem/cloud/aws.md diff --git a/12_ecosystem/cloud/intro.md b/13_ecosystem/cloud/intro.md similarity index 100% rename from 12_ecosystem/cloud/intro.md rename to 13_ecosystem/cloud/intro.md diff --git a/12_ecosystem/cloud/multicloud.md b/13_ecosystem/cloud/multicloud.md similarity index 100% rename from 12_ecosystem/cloud/multicloud.md rename to 13_ecosystem/cloud/multicloud.md diff --git a/12_ecosystem/cloud/summary.md b/13_ecosystem/cloud/summary.md similarity index 100% rename from 12_ecosystem/cloud/summary.md rename to 13_ecosystem/cloud/summary.md diff --git a/12_ecosystem/cloud/tencentCloud.md b/13_ecosystem/cloud/tencentCloud.md similarity index 100% rename from 12_ecosystem/cloud/tencentCloud.md rename to 13_ecosystem/cloud/tencentCloud.md diff --git a/12_ecosystem/coreos/README.md b/13_ecosystem/coreos/README.md similarity index 100% rename from 12_ecosystem/coreos/README.md rename to 13_ecosystem/coreos/README.md diff --git a/12_ecosystem/coreos/demo/example.fcc b/13_ecosystem/coreos/demo/example.fcc similarity index 100% rename from 12_ecosystem/coreos/demo/example.fcc rename to 13_ecosystem/coreos/demo/example.fcc diff --git a/12_ecosystem/coreos/install.md b/13_ecosystem/coreos/install.md similarity index 100% rename from 12_ecosystem/coreos/install.md rename to 13_ecosystem/coreos/install.md diff --git a/12_ecosystem/coreos/intro.md b/13_ecosystem/coreos/intro.md similarity index 100% rename from 12_ecosystem/coreos/intro.md rename to 13_ecosystem/coreos/intro.md diff --git a/12_ecosystem/podman/README.md b/13_ecosystem/podman/README.md similarity index 100% rename from 12_ecosystem/podman/README.md rename to 13_ecosystem/podman/README.md diff --git a/13_implementation/13.1_arch.md b/14_implementation/14.1_arch.md similarity index 96% rename from 13_implementation/13.1_arch.md rename to 14_implementation/14.1_arch.md index 9019a35..4b9960a 100644 --- a/13_implementation/13.1_arch.md +++ b/14_implementation/14.1_arch.md @@ -1,4 +1,4 @@ -## 基本架构 +## 14.1 基本架构 Docker 的架构设计简洁而高效,主要由客户端和服务端两部分组成。 @@ -151,6 +151,6 @@ flowchart TD ### 延伸阅读 -- [命名空间](./13.2_namespace.md):Runc 如何隔离容器 -- [控制组](./13.3_cgroups.md):Runc 如何限制资源 -- [联合文件系统](./13.4_ufs.md):镜像如何存储 +- [命名空间](./14.2_namespace.md):Runc 如何隔离容器 +- [控制组](./14.3_cgroups.md):Runc 如何限制资源 +- [联合文件系统](./14.4_ufs.md):镜像如何存储 diff --git a/13_implementation/13.2_namespace.md b/14_implementation/14.2_namespace.md similarity index 98% rename from 13_implementation/13.2_namespace.md rename to 14_implementation/14.2_namespace.md index c794062..d78edec 100644 --- a/13_implementation/13.2_namespace.md +++ b/14_implementation/14.2_namespace.md @@ -1,4 +1,4 @@ -## 命名空间 +## 14.2 命名空间 命名空间(Namespace)是 Linux 内核的一个强大特性,为容器提供了隔离的运行环境。 @@ -303,7 +303,7 @@ Namespace 提供了隔离但不是安全边界: ### 延伸阅读 -- [控制组(Cgroups)](13.3_cgroups.md):资源限制机制 -- [联合文件系统](13.4_ufs.md):分层存储的实现 +- [控制组(Cgroups)](14.3_cgroups.md):资源限制机制 +- [联合文件系统](14.4_ufs.md):分层存储的实现 - [安全](../security/README.md):容器安全实践 - [Linux Namespace 官方文档](https://man7.org/linux/man-pages/man7/namespaces.7.html) diff --git a/13_implementation/13.3_cgroups.md b/14_implementation/14.3_cgroups.md similarity index 99% rename from 13_implementation/13.3_cgroups.md rename to 14_implementation/14.3_cgroups.md index 15dde7e..e7a8a4a 100644 --- a/13_implementation/13.3_cgroups.md +++ b/14_implementation/14.3_cgroups.md @@ -1,4 +1,4 @@ -## 控制组 +## 14.3 控制组 控制组(Cgroups)是 Linux 内核提供的另一种关键机制,主要用于资源的限制和审计。 @@ -298,6 +298,6 @@ $ docker run -d --name cadvisor \ ### 延伸阅读 -- [命名空间](13.2_namespace.md):资源隔离 +- [命名空间](14.2_namespace.md):资源隔离 - [安全](../security/README.md):容器安全概述 - [Docker Stats](../05_container/README.md):监控容器资源 diff --git a/13_implementation/13.4_ufs.md b/14_implementation/14.4_ufs.md similarity index 99% rename from 13_implementation/13.4_ufs.md rename to 14_implementation/14.4_ufs.md index 01889bb..c345cc6 100644 --- a/13_implementation/13.4_ufs.md +++ b/14_implementation/14.4_ufs.md @@ -1,4 +1,4 @@ -## 联合文件系统 +## 14.4 联合文件系统 联合文件系统(UnionFS)是 Docker 镜像分层存储的基础,它允许将多个目录挂载为同一个虚拟文件系统。 diff --git a/13_implementation/13.5_container_format.md b/14_implementation/14.5_container_format.md similarity index 94% rename from 13_implementation/13.5_container_format.md rename to 14_implementation/14.5_container_format.md index 3c0a9e3..97610a1 100644 --- a/13_implementation/13.5_container_format.md +++ b/14_implementation/14.5_container_format.md @@ -1,3 +1,3 @@ -## 容器格式 +## 14.5 容器格式 最初,Docker 采用了 `LXC` 中的容器格式。从 0.7 版本以后开始去除 LXC,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 diff --git a/13_implementation/13.6_network.md b/14_implementation/14.6_network.md similarity index 99% rename from 13_implementation/13.6_network.md rename to 14_implementation/14.6_network.md index 3031912..7c81a49 100644 --- a/13_implementation/13.6_network.md +++ b/14_implementation/14.6_network.md @@ -1,4 +1,4 @@ -## Docker 网络实现 +## 14.6 Docker 网络实现 Docker 的网络实现其实就是利用了 Linux 上的网络命名空间和虚拟网络设备(特别是 veth pair)。建议先熟悉了解这两部分的基本概念再阅读本章。 diff --git a/13_implementation/README.md b/14_implementation/README.md similarity index 98% rename from 13_implementation/README.md rename to 14_implementation/README.md index 608be25..8d9d1f6 100644 --- a/13_implementation/README.md +++ b/14_implementation/README.md @@ -1,4 +1,4 @@ -# 第十三章 底层实现 +# 第十四章 底层实现 Docker 底层的核心技术包括 Linux 上的命名空间(Namespaces)、控制组(Control groups)、Union 文件系统(Union file systems)和容器格式(Container format)。 diff --git a/13_implementation/_images/docker_arch.png b/14_implementation/_images/docker_arch.png similarity index 100% rename from 13_implementation/_images/docker_arch.png rename to 14_implementation/_images/docker_arch.png diff --git a/14_cases/README.md b/15_cases/README.md similarity index 87% rename from 14_cases/README.md rename to 15_cases/README.md index 9064df2..20ca701 100644 --- a/14_cases/README.md +++ b/15_cases/README.md @@ -1,4 +1,4 @@ -# 第十四章 实战案例 +# 第十五章 实战案例 本章将介绍 Docker 在不同场景下的实战案例。 diff --git a/14_cases/ci/README.md b/15_cases/ci/README.md similarity index 100% rename from 14_cases/ci/README.md rename to 15_cases/ci/README.md diff --git a/14_cases/ci/actions/README.md b/15_cases/ci/actions/README.md similarity index 100% rename from 14_cases/ci/actions/README.md rename to 15_cases/ci/actions/README.md diff --git a/14_cases/ci/devops_workflow.md b/15_cases/ci/devops_workflow.md similarity index 100% rename from 14_cases/ci/devops_workflow.md rename to 15_cases/ci/devops_workflow.md diff --git a/14_cases/ci/drone/.env.example b/15_cases/ci/drone/.env.example similarity index 100% rename from 14_cases/ci/drone/.env.example rename to 15_cases/ci/drone/.env.example diff --git a/14_cases/ci/drone/.gitignore b/15_cases/ci/drone/.gitignore similarity index 100% rename from 14_cases/ci/drone/.gitignore rename to 15_cases/ci/drone/.gitignore diff --git a/14_cases/ci/drone/README.md b/15_cases/ci/drone/README.md similarity index 91% rename from 14_cases/ci/drone/README.md rename to 15_cases/ci/drone/README.md index 5a388d6..4e7fa98 100644 --- a/14_cases/ci/drone/README.md +++ b/15_cases/ci/drone/README.md @@ -10,7 +10,7 @@ 在 Github 新建一个名为 `drone-demo` 的仓库。 -打开我们已经 [部署好的 Drone 网站](9.2_install.md) 或者 [Drone Cloud](https://cloud.drone.io),使用 GitHub 账号登录,在界面中关联刚刚新建的 `drone-demo` 仓库。 +打开我们已经 [部署好的 Drone 网站](10.2_install.md) 或者 [Drone Cloud](https://cloud.drone.io),使用 GitHub 账号登录,在界面中关联刚刚新建的 `drone-demo` 仓库。 ## 编写项目源代码 diff --git a/14_cases/ci/drone/_images/drone-build.png b/15_cases/ci/drone/_images/drone-build.png similarity index 100% rename from 14_cases/ci/drone/_images/drone-build.png rename to 15_cases/ci/drone/_images/drone-build.png diff --git a/14_cases/ci/drone/demo/.drone.yml b/15_cases/ci/drone/demo/.drone.yml similarity index 100% rename from 14_cases/ci/drone/demo/.drone.yml rename to 15_cases/ci/drone/demo/.drone.yml diff --git a/14_cases/ci/drone/demo/README.md b/15_cases/ci/drone/demo/README.md similarity index 100% rename from 14_cases/ci/drone/demo/README.md rename to 15_cases/ci/drone/demo/README.md diff --git a/14_cases/ci/drone/demo/app.go b/15_cases/ci/drone/demo/app.go similarity index 100% rename from 14_cases/ci/drone/demo/app.go rename to 15_cases/ci/drone/demo/app.go diff --git a/14_cases/ci/drone/docker-compose.yml b/15_cases/ci/drone/docker-compose.yml similarity index 100% rename from 14_cases/ci/drone/docker-compose.yml rename to 15_cases/ci/drone/docker-compose.yml diff --git a/14_cases/ci/drone/install.md b/15_cases/ci/drone/install.md similarity index 100% rename from 14_cases/ci/drone/install.md rename to 15_cases/ci/drone/install.md diff --git a/14_cases/ide/README.md b/15_cases/ide/README.md similarity index 100% rename from 14_cases/ide/README.md rename to 15_cases/ide/README.md diff --git a/14_cases/ide/vsCode.md b/15_cases/ide/vsCode.md similarity index 100% rename from 14_cases/ide/vsCode.md rename to 15_cases/ide/vsCode.md diff --git a/14_cases/os/README.md b/15_cases/os/README.md similarity index 100% rename from 14_cases/os/README.md rename to 15_cases/os/README.md diff --git a/14_cases/os/_images/alpinelinux-logo.png b/15_cases/os/_images/alpinelinux-logo.png similarity index 100% rename from 14_cases/os/_images/alpinelinux-logo.png rename to 15_cases/os/_images/alpinelinux-logo.png diff --git a/14_cases/os/_images/busybox-logo.png b/15_cases/os/_images/busybox-logo.png similarity index 100% rename from 14_cases/os/_images/busybox-logo.png rename to 15_cases/os/_images/busybox-logo.png diff --git a/14_cases/os/_images/centos-logo.png b/15_cases/os/_images/centos-logo.png similarity index 100% rename from 14_cases/os/_images/centos-logo.png rename to 15_cases/os/_images/centos-logo.png diff --git a/14_cases/os/_images/coreos-login.png b/15_cases/os/_images/coreos-login.png similarity index 100% rename from 14_cases/os/_images/coreos-login.png rename to 15_cases/os/_images/coreos-login.png diff --git a/14_cases/os/_images/coreos-logo.jpg b/15_cases/os/_images/coreos-logo.jpg similarity index 100% rename from 14_cases/os/_images/coreos-logo.jpg rename to 15_cases/os/_images/coreos-logo.jpg diff --git a/14_cases/os/_images/coreos_crt.png b/15_cases/os/_images/coreos_crt.png similarity index 100% rename from 14_cases/os/_images/coreos_crt.png rename to 15_cases/os/_images/coreos_crt.png diff --git a/14_cases/os/_images/coreos_list.png b/15_cases/os/_images/coreos_list.png similarity index 100% rename from 14_cases/os/_images/coreos_list.png rename to 15_cases/os/_images/coreos_list.png diff --git a/14_cases/os/_images/coreos_run_ip.png b/15_cases/os/_images/coreos_run_ip.png similarity index 100% rename from 14_cases/os/_images/coreos_run_ip.png rename to 15_cases/os/_images/coreos_run_ip.png diff --git a/14_cases/os/_images/debian-logo.png b/15_cases/os/_images/debian-logo.png similarity index 100% rename from 14_cases/os/_images/debian-logo.png rename to 15_cases/os/_images/debian-logo.png diff --git a/14_cases/os/_images/docker_version.png b/15_cases/os/_images/docker_version.png similarity index 100% rename from 14_cases/os/_images/docker_version.png rename to 15_cases/os/_images/docker_version.png diff --git a/14_cases/os/_images/fedora-logo.png b/15_cases/os/_images/fedora-logo.png similarity index 100% rename from 14_cases/os/_images/fedora-logo.png rename to 15_cases/os/_images/fedora-logo.png diff --git a/14_cases/os/_images/php_pulling.png b/15_cases/os/_images/php_pulling.png similarity index 100% rename from 14_cases/os/_images/php_pulling.png rename to 15_cases/os/_images/php_pulling.png diff --git a/14_cases/os/_images/ubuntu-logo.jpg b/15_cases/os/_images/ubuntu-logo.jpg similarity index 100% rename from 14_cases/os/_images/ubuntu-logo.jpg rename to 15_cases/os/_images/ubuntu-logo.jpg diff --git a/14_cases/os/_images/vmware_coreos.png b/15_cases/os/_images/vmware_coreos.png similarity index 100% rename from 14_cases/os/_images/vmware_coreos.png rename to 15_cases/os/_images/vmware_coreos.png diff --git a/14_cases/os/alpine.md b/15_cases/os/alpine.md similarity index 100% rename from 14_cases/os/alpine.md rename to 15_cases/os/alpine.md diff --git a/14_cases/os/busybox.md b/15_cases/os/busybox.md similarity index 100% rename from 14_cases/os/busybox.md rename to 15_cases/os/busybox.md diff --git a/14_cases/os/centos.md b/15_cases/os/centos.md similarity index 100% rename from 14_cases/os/centos.md rename to 15_cases/os/centos.md diff --git a/14_cases/os/debian.md b/15_cases/os/debian.md similarity index 100% rename from 14_cases/os/debian.md rename to 15_cases/os/debian.md diff --git a/14_cases/os/summary.md b/15_cases/os/summary.md similarity index 100% rename from 14_cases/os/summary.md rename to 15_cases/os/summary.md diff --git a/15_appendix/15.1_best_practices.md b/16_appendix/16.1_best_practices.md similarity index 99% rename from 15_appendix/15.1_best_practices.md rename to 16_appendix/16.1_best_practices.md index d0cc115..1959392 100644 --- a/15_appendix/15.1_best_practices.md +++ b/16_appendix/16.1_best_practices.md @@ -1,4 +1,4 @@ -## Dockerfile 最佳实践 +## 16.1 Dockerfile 最佳实践 本附录是笔者对 Docker 官方文档中 [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) 的理解与翻译。 diff --git a/15_appendix/15.2_debug.md b/16_appendix/16.2_debug.md similarity index 98% rename from 15_appendix/15.2_debug.md rename to 16_appendix/16.2_debug.md index 10e2020..9478d24 100644 --- a/15_appendix/15.2_debug.md +++ b/16_appendix/16.2_debug.md @@ -1,4 +1,4 @@ -## 如何调试 Docker +## 16.2 如何调试 Docker ### 开启 Debug 模式 diff --git a/15_appendix/15.3_resources.md b/16_appendix/16.3_resources.md similarity index 98% rename from 15_appendix/15.3_resources.md rename to 16_appendix/16.3_resources.md index cba5f1c..06743dc 100644 --- a/15_appendix/15.3_resources.md +++ b/16_appendix/16.3_resources.md @@ -1,4 +1,4 @@ -## 资源链接 +## 16.3 资源链接 ### 官方网站 diff --git a/15_appendix/README.md b/16_appendix/README.md similarity index 74% rename from 15_appendix/README.md rename to 16_appendix/README.md index 9d9af59..51764dc 100644 --- a/15_appendix/README.md +++ b/16_appendix/README.md @@ -1,4 +1,4 @@ -# 第十五章 附录 +# 第十六章 附录 本章包含了 Docker 相关的参考资料、常见问题解答以及最佳实践指南,旨在为读者提供便捷的查阅工具。 @@ -7,6 +7,6 @@ * [**常见问题总结 (FAQ)**](faq/README.md):汇总了学习和使用 Docker 过程中的常见问题与错误解决方案。 * [**热门镜像介绍**](repo/README.md):详细介绍了 Nginx, MySQL, Redis 等常用官方镜像的使用方法。 * [**Docker 命令查询**](command/README.md):速查 Docker 客户端和服务端的常用命令。 -* [**Dockerfile 最佳实践**](15.1_best_practices.md):提供编写高效、安全 Dockerfile 的指导原则。 -* [**如何调试 Docker**](15.2_debug.md):介绍 Docker 调试技巧和工具。 -* [**资源链接**](15.3_resources.md):推荐更多 Docker 相关的学习资源。 +* [**Dockerfile 最佳实践**](16.1_best_practices.md):提供编写高效、安全 Dockerfile 的指导原则。 +* [**如何调试 Docker**](16.2_debug.md):介绍 Docker 调试技巧和工具。 +* [**资源链接**](16.3_resources.md):推荐更多 Docker 相关的学习资源。 diff --git a/15_appendix/_images/cmd_logic.graffle/data.plist b/16_appendix/_images/cmd_logic 2.graffle/data.plist similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/data.plist rename to 16_appendix/_images/cmd_logic 2.graffle/data.plist diff --git a/15_appendix/_images/cmd_logic.graffle/image10.pdf b/16_appendix/_images/cmd_logic 2.graffle/image10.pdf similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/image10.pdf rename to 16_appendix/_images/cmd_logic 2.graffle/image10.pdf diff --git a/15_appendix/_images/cmd_logic.graffle/image11.pdf b/16_appendix/_images/cmd_logic 2.graffle/image11.pdf similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/image11.pdf rename to 16_appendix/_images/cmd_logic 2.graffle/image11.pdf diff --git a/15_appendix/_images/cmd_logic.graffle/image12.pdf b/16_appendix/_images/cmd_logic 2.graffle/image12.pdf similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/image12.pdf rename to 16_appendix/_images/cmd_logic 2.graffle/image12.pdf diff --git a/15_appendix/_images/cmd_logic.graffle/image13.pdf b/16_appendix/_images/cmd_logic 2.graffle/image13.pdf similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/image13.pdf rename to 16_appendix/_images/cmd_logic 2.graffle/image13.pdf diff --git a/15_appendix/_images/cmd_logic.graffle/image4.pdf b/16_appendix/_images/cmd_logic 2.graffle/image4.pdf similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/image4.pdf rename to 16_appendix/_images/cmd_logic 2.graffle/image4.pdf diff --git a/15_appendix/_images/cmd_logic.graffle/image5.pdf b/16_appendix/_images/cmd_logic 2.graffle/image5.pdf similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/image5.pdf rename to 16_appendix/_images/cmd_logic 2.graffle/image5.pdf diff --git a/15_appendix/_images/cmd_logic.graffle/image6.pdf b/16_appendix/_images/cmd_logic 2.graffle/image6.pdf similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/image6.pdf rename to 16_appendix/_images/cmd_logic 2.graffle/image6.pdf diff --git a/15_appendix/_images/cmd_logic.graffle/image7.pdf b/16_appendix/_images/cmd_logic 2.graffle/image7.pdf similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/image7.pdf rename to 16_appendix/_images/cmd_logic 2.graffle/image7.pdf diff --git a/15_appendix/_images/cmd_logic.graffle/image9.pdf b/16_appendix/_images/cmd_logic 2.graffle/image9.pdf similarity index 100% rename from 15_appendix/_images/cmd_logic.graffle/image9.pdf rename to 16_appendix/_images/cmd_logic 2.graffle/image9.pdf diff --git a/15_appendix/_images/cmd_logic.dot b/16_appendix/_images/cmd_logic.dot similarity index 100% rename from 15_appendix/_images/cmd_logic.dot rename to 16_appendix/_images/cmd_logic.dot diff --git a/15_appendix/_images/cmd_logic.dot.bak b/16_appendix/_images/cmd_logic.dot.bak similarity index 100% rename from 15_appendix/_images/cmd_logic.dot.bak rename to 16_appendix/_images/cmd_logic.dot.bak diff --git a/16_appendix/_images/cmd_logic.graffle/data.plist b/16_appendix/_images/cmd_logic.graffle/data.plist new file mode 100644 index 0000000000000000000000000000000000000000..26324d3c498156be59e5c1096d3a51c419c0250b GIT binary patch literal 6461 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 XnCSFhJ0Uz}Z(sdCLcS;J4NJ%KDD2+&WH_{?4 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ΞFRFk z!M(C6jV9riO2tZ4N^>9$sW+cJUYmUjn$J&+P0Zrp$?whYv<)ubFYlLTK}D2aH{lUu ztA>5#&4SB(XtNz$*Q0nY*&C~lgl5r4IWzN#v==k>h+q=q} zt2O$lTdwBkZDXur%8_}mtCdUa6b5s@W`7N$i%DIq{_6K`Ep4oMe7JVnF`yqe8t)UK z_!UZqs(_X~P5UA#$4{t-x+$AkOB*7?;ttIvkbyUQNf#DrGJzAn@u@^l=hl0Ax}qimrG%U{W$K*e5l-fLVS(^`dcyJL zw*?x0K>`FvxRRrI=M_b-og=XD8{MrdSJDaNEKpMP`_g#+8tWRq-b|&Z1)ENz@%Mvv zp=qHdktNe{Sur!)H>tFG50VRu)4G|H5^|{%)72vS$_7;M1`3zex#HS8FLKvY?RBlp zT#g`WUyED+slLlp>l-=I8_uXv=R|ecpLU;At7E|atqNr=;o-jRJA#RAhRuF{FsKle z;{WubcW*PBnEEvd;)gw)D^x{9RRp3{Bi68YC^NiEEeSJvPV^rbt>emy;!$qhGq4!f zcZgr-xu1CKteV_6IDDG(-m>C+_|)}X-I{QT;Ws-Bn<}MdCGV9`0r>kd2Yq)y-dDAD z^5gw6Q%eeFW<``!1XK8ay)L;VYKL|n2tS5PuX?|;tUPLA5*+rhxmcD>6S$$jUp`{_ zB`&W;$M!SobG@>E!DF*jSN+A{$@Vg%#~mQ17^~Xc&iO#XK#B6AsyzJ8K4Af#=hWX+ zZrVE)=Sz(hry6RJ93vl#n8vhlI94V#BwlSN`{0>L+fJ?A)Vs_YP-N|Eb75=*zcQU> zEH-1ZZxusu$!A2ON*K0Cz%Xtypl$Ist4`sItSpl{HJ8O;zOqQRW;!ylv09#Alm*!m z9P+Upg<#a^yXY|KBNQ{&931tUrkd-yR*pz>iA!zkD+39gQQV`e7G&Q_X zBx3Fxk(}AK>DfT+&2(AJ7`LD0+=}yO!=5qiu~%6+Uw;JkFtOH4w1{`~y`SkR`1$;2 zzEhrA9?ihCh+QzP$O~qFPXFu2?EY;2uw&H-jNu2yV`h`2nmBHJp~{Ww43-hU5;GLV zWQ57>LHi6oHXZdgzj>O4#G|UC*P`^Ll<&>1B;?LlZ>|#Wc9I@nuD*nUl-a4h@#ES8 zU*bK_LXbu<+@$*{xDZ2aIG&O4LYu#(X=H~f*VFjvLUM$+aC!urV)#a+Mq~3V59nQb z)xPOIYv~KT?>`eL;KIV69dD?zwD8QP3A^gc?LaV3dOA(+5=@glS1R-z;%}q6Ia*Rs z!a;netpaH>s1Qcg$xGF}z|QYgQQZ)k#awfr@!=P#slysM&q-3p^;@!GzZyhV^l#tF zqwrrN|6WTs7P_f^XOZW5B;ofD)w4@kit_|M#XhnJUCW+yT4dc6bp^t#z(MXn0a z{VEoq6ES1_Mcs?umN3L|_5Kfa>kNQFz zmla0B5qxkSxDXrx=i}u!g2UN><1fxLMyz!Jj%MXy380iGIsrgQ1^_29fK9U4t%nnt zSYXcC>YxAr-p25DLt8`OP$Uup|LX_k=i}qygIYs>(*$_4F9%8050$+4GI54hX7LG51R#ekiZ-MOdiG! zW$S=;JAtotY<+<>M?zuR&dxxFW3%`KVzhP!(*5*a7D#we0U>KNFWQP9Da4PkK%@Ei t;6j3EBofUd#KX^nLRg4H{yPf*%>rrUjsep7B#8ugc>!RZMNUH=@;|YuP+b53 literal 0 HcmV?d00001 diff --git a/16_appendix/_images/cmd_logic.graffle/image11.pdf b/16_appendix/_images/cmd_logic.graffle/image11.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0d4a6323e366d5da1825edd11fa479cd1fa07d4f GIT binary patch literal 8218 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 literal 0 HcmV?d00001 diff --git a/16_appendix/_images/cmd_logic.graffle/image12.pdf b/16_appendix/_images/cmd_logic.graffle/image12.pdf new file mode 100644 index 0000000000000000000000000000000000000000..61d01d3a1ec3be7ae739a71bf970ad9fe7adc66a GIT binary patch literal 17786 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 literal 0 HcmV?d00001 diff --git a/16_appendix/_images/cmd_logic.graffle/image13.pdf b/16_appendix/_images/cmd_logic.graffle/image13.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ed7078a1916009e858c1bc8e3fc4deff894d52f7 GIT binary patch literal 14933 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 IH94&R1B^cy7XSbN literal 0 HcmV?d00001 diff --git a/16_appendix/_images/cmd_logic.graffle/image5.pdf b/16_appendix/_images/cmd_logic.graffle/image5.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a193b9977b7a353949485f210e04481c7ee0c0e1 GIT binary patch literal 12025 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 R0s^@?`EVE*WK?8v{twJV2{Qly literal 0 HcmV?d00001 diff --git a/16_appendix/_images/cmd_logic.graffle/image6.pdf b/16_appendix/_images/cmd_logic.graffle/image6.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3ba6c48a52af83cfabcb7810cf201ce61a1250c4 GIT binary patch literal 11523 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 HmGZv;^fH-a literal 0 HcmV?d00001 diff --git a/16_appendix/_images/cmd_logic.graffle/image7.pdf b/16_appendix/_images/cmd_logic.graffle/image7.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0bff3b5ea3f57acf2918d8ca8b0f625e363b2da3 GIT binary patch literal 9792 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 v2@$9Lg|H3smgl5HZQ-};G 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