diff --git a/.docker/docker-entrypoint.sh b/.docker/docker-entrypoint.sh new file mode 100755 index 000000000..18b1687f4 --- /dev/null +++ b/.docker/docker-entrypoint.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env sh + +echo +echo +echo "Please open your browser: 127.0.0.1:4000" +echo +echo "欢迎加入 QQ 群:【 145983035 】 分享 Docker 资源,交流 Docker 技术" +echo +echo + +exec nginx -g "daemon off;" diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 000000000..d4ced5486 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,15 @@ +kind: pipeline +type: docker +name: build +steps: + - name: build + image: yeasy/docker_practice:latest + pull: if-not-exists # always never + environment: + TZ: Asia/Shanghai + commands: + - docker-entrypoint.sh build + +trigger: + branch: + - master diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..f57159a73 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,29 @@ +# EditorConfig is awesome: https://EditorConfig.org + +root = true + +[*] + +indent_style = space + +indent_size = 2 + +end_of_line = lf + +charset = utf-8 + +trim_trailing_whitespace = true + +insert_final_newline = true + +[*.md] + +trim_trailing_whitespace = false + +[*.py] + +indent_size = 4 + +[Makefile] + +indent_style = tab diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..5308bd51f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +* text=auto + +*.sh text eol=lf + +* linguist-language=go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..fb7faa903 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,40 @@ +* @yeasy @khs1994 +/.github/* @khs1994 +/.travis/* @khs1994 +/.vuepress/* @khs1994 +/advanced_network/* @yeasy @khs1994 +/appendix/* @yeasy @khs1994 +/archive/* @khs1994 +/basic_concept/* @yeasy @khs1994 +/buildx/* @khs1994 +/cases/* @yeasy @khs1994 +/cloud/* @khs1994 +/compose/* @yeasy @khs1994 +/container/* @yeasy @khs1994 +/coreos/* @khs1994 +/data_management/* @khs1994 +/etcd/* @khs1994 +/IDE/* @khs1994 +/image/* @yeasy @khs1994 +/install/* @khs1994 +/introduction/* @yeasy @khs1994 +/kubernetes/* @yeasy @khs1994 +/network/* @yeasy @khs1994 +/opensource/* @khs1994 +/repository/* @khs1994 +/security/* @yeasy @khs1994 +/underly/* @yeasy @khs1994 +/.drone.yml @khs1994 +/.editorconfig/ @khs1994 +/.gitattributes @khs1994 +/.gitignore @khs1994 +/.travis.yml @khs1994 +/_config.yml @yeasy @khs1994 +/book.json @yeasy @khs1994 +/CHANGELOG.md @yeasy @khs1994 +/CONTRIBUTING.md @yeasy @khs1994 +/docker-compose.yml @khs1994 +/manifest @khs1994 +/package.json @khs1994 +/README.md @yeasy @khs1994 +/SUMMARY.md @yeasy @khs1994 diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md new file mode 100644 index 000000000..8528cd1f5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -0,0 +1,41 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +* [ ] Have u googled the problem? If no, pls do that first! + +### Environment + + + +* [x] Linux + * [x] CentOS 7 + * [x] Fedora + * [x] Ubuntu 16.04 + + * [x] Debian 9 + +* [x] macOS +* [x] Windows 10 +* [x] Raspberry Pi (ARM) +* [x] Others (Pls describe below) + +### Docker Version + + + +* [x] Edge (v19.03) +* [x] Stable (v19.03) +* [x] 1.13.0 or Before + +### Problem Description + + + + + + + + + + diff --git a/.github/ISSUE_TEMPLATE/Custom.md b/.github/ISSUE_TEMPLATE/Custom.md new file mode 100644 index 000000000..650a860b6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Custom.md @@ -0,0 +1,41 @@ +--- +name: Custom issue template +about: Create a issue about Docker + +--- + +* [ ] Have u googled the problem? If no, pls do that first! + +### Environment + + + +* [x] Linux + * [x] CentOS 7 + * [x] Fedora + * [x] Ubuntu 16.04 + + * [x] Debian 9 + +* [x] macOS +* [x] Windows 10 +* [x] Raspberry Pi (ARM) +* [x] Others (Pls describe below) + +### Docker Version + + + +* [x] Edge (v19.03) +* [x] Stable (v19.03) +* [x] 1.13.0 or Before + +### Problem Description + + + + + + + + + + diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md new file mode 100644 index 000000000..b7414799c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -0,0 +1,5 @@ +--- +name: Feature request +about: Suggest an idea for docker_practice + +--- diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..39d35fdc7 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,20 @@ + + +### Proposed changes (Mandatory) + + + +### Fix issues (Optional) + + diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml new file mode 100644 index 000000000..7ebcd1843 --- /dev/null +++ b/.github/workflows/check-link.yml @@ -0,0 +1,69 @@ +name: check-link + +on: + push: + pull_request: + +jobs: + check-link: + name: check-link + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + with: + fetch-depth: 1 + # search Issues :-( + - run: | + docker run -i --rm \ + -v $PWD:/mnt:ro \ + dkhamsing/awesome_bot \ + --white-list "localhost","0.0.0.0",\ + "server","example.com","docker",\ + "docker.domain.com","YourIP","register",\ + "172.16.238.100","172.16.238.101","172.16.238.102",\ + "192.168.199.100",\ + "github.com/settings",\ + "github.com/docker/compose/releases/download",\ + "github.com/docker/machine/releases/download",\ + "github.com/etcd-io/etcd/releases/download",\ + "github.com/tianon/gosu/releases/download",\ + "github.com/yeasy/docker_practice",\ + "github.com/twang2218/gitlab-ce-zh.git",\ + "github.com/AliyunContainerService/k8s-for-docker-desktop/raw",\ + "dl-cdn.alpinelinux.org/alpine/edge/testing",\ + "www.w3.org/1999/xhtml",\ + "cr.console.aliyun.com",\ + "cloud.tencent.com",\ + "nodejs.org/dist/",\ + "c.163.com/hub",\ + "drone.yeasy.com",\ + "mirrors.ustc.edu.cn",\ + "docs.docker.com",\ + "dockerhub.azk8s.cn",\ + "mirror.ccs.tencentyun.com",\ + "vuepress.mirror.docker-practice.com",\ + "mc.qcloudimg.com/static/img",\ + "www.daocloud.io/mirror",\ + "download.docker.com",\ + "www.ubuntu.com",\ + "archive.ubuntu.com",\ + "security.ubuntu.com/ubuntu",\ + "nginx.com",\ + "img.shields.io/github/release/yeasy/docker_practice",\ + "travis-ci.org/yeasy/docker_practice.svg",\ + "launchpad.net",\ + "www.w3.org/1999",\ + "chat.freenode.net",\ + "en.wikipedia.org/wiki/UnionFS",\ + "product.china-pub.com",\ + "union-click.jd.com",\ + "x.x.x.x/base",\ + "x.x.x.x:9000/minio/",\ + "https://www.freedesktop.org/wiki/Software/systemd/",\ + "www.aliyun.com" \ + --allow-dupe \ + --skip-save-results \ + -t 10 \ + `find . \( -path "./mesos" -o -path "./machine" -o -path "./swarm_mode" \) -prune -o -name "*.md" -exec ls {} \;` + name: check-link + timeout-minutes: 25 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000..cb310cb57 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,97 @@ +on: + push: + pull_request: + +name: CI + +jobs: + build: + name: Build GitBook + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + with: + fetch-depth: 2 + - name: Build + uses: docker://yeasy/docker_practice + with: + args: build + - name: vuepress + run: | + sudo rm -rf _book + npm i vuepress --save-dev + npm i + npm run vuepress:build + echo "vuepress.docker-practice.com" > .vuepress/dist/CNAME + + cp -r _images .vuepress/dist + cp -r advanced_network/_images .vuepress/dist/advanced_network + cp -r appendix/_images .vuepress/dist/appendix + cp -r cases/ci/drone/_images .vuepress/dist/cases/ci/drone + cp -r cases/os/_images .vuepress/dist/cases/os + cp -r cloud/_images .vuepress/dist/cloud + cp -r data_management/_images .vuepress/dist/data_management + cp -r etcd/_images .vuepress/dist/etcd + cp -r image/_images .vuepress/dist/image + cp -r install/_images .vuepress/dist/install + cp -r introduction/_images .vuepress/dist/introduction + cp -r kubernetes/_images .vuepress/dist/kubernetes + cp -r mesos/_images .vuepress/dist/mesos + cp -r underly/_images .vuepress/dist/underly + + echo "include: [_images]" > .vuepress/dist/_config + - name: Upload Vuepress dist + uses: docker://pcit/pages + if: github.repository == 'docker-practice/docker_practice' + env: + PCIT_EMAIL: khs1994@khs1994.com + PCIT_GIT_TOKEN: ${{ secrets.PCIT_GIT_TOKEN }} + PCIT_GIT_URL: github.com/docker-practice/vuepress + PCIT_KEEP_HISTORY: "true" + PCIT_LOCAL_DIR: .vuepress/dist + PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT + PCIT_TARGET_BRANCH: master + PCIT_USERNAME: khs1994 + - name: Set coding.net CNAME + run: | + echo "vuepress.mirror.docker-practice.com" > .vuepress/dist/CNAME + - name: Upload Vuepress dist to coding.net + uses: docker://pcit/pages + if: github.repository == 'docker-practice/docker_practice' + env: + PCIT_EMAIL: khs1994@khs1994.com + PCIT_GIT_TOKEN: ${{ secrets.CODING_GIT_TOKEN }} + PCIT_GIT_URL: e.coding.net/dpsigs/docker_practice + PCIT_KEEP_HISTORY: "true" + PCIT_LOCAL_DIR: .vuepress/dist + PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT + PCIT_TARGET_BRANCH: master + PCIT_USERNAME: ptt0xjqzbke3 + - name: Build vuepress docker image + if: github.repository == 'docker-practice/docker_practice' + run: | + sudo rm -rf .vuepress/dist/.git + + echo "FROM nginx:alpine" >> Dockerfile + echo "COPY .vuepress/dist /usr/share/nginx/html" >> Dockerfile + echo "COPY .docker/docker-entrypoint.sh /" >> Dockerfile + echo "ENTRYPOINT [\"/docker-entrypoint.sh\"]" >> Dockerfile + + echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + + VCS_REF=`git rev-parse --short HEAD` + + docker build -t dockerpracticesig/docker_practice:vuepress \ + --label org.opencontainers.image.revision=$VCS_REF \ + --label org.opencontainers.image.source="https://github.com/yeasy/docker_practice" \ + --label maintainer="https://github.com/docker-practice" \ + . + + docker push dockerpracticesig/docker_practice:vuepress + + docker run -it --rm -d -p 4000:80 dockerpracticesig/docker_practice:vuepress + + curl 127.0.0.1:4000 + env: + DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} + DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} diff --git a/.gitignore b/.gitignore index d126aa1f5..4d197531a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,7 @@ _book/ *.edx .DS_Store - node_modules/ +package-lock.json + +.vuepress/dist diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..3f12f43f0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,65 @@ +language: bash + +services: +- docker + +before_install: +- openssl aes-256-cbc -K $encrypted_6cc8cff04075_key -iv $encrypted_6cc8cff04075_iv + -in .travis/id_rsa.enc -out ~/.ssh/id_rsa -d +- chmod 600 ~/.ssh/id_rsa +- export TZ='Asia/Shanghai' +- date +- git config --global user.name "khs1994" +- git config --global user.email "khs1994@khs1994.com" + +script: +- docker run -it --rm -v $PWD:/srv/gitbook-src yeasy/docker_practice build + +after_success: +- sudo chmod -R 777 _book + +- echo "FROM nginx:alpine" >> Dockerfile +- echo "COPY _book /usr/share/nginx/html" >> Dockerfile +- echo "COPY .docker/docker-entrypoint.sh /" >> Dockerfile +- echo "ENTRYPOINT [\"/docker-entrypoint.sh\"]" >> Dockerfile + +- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin +- export VCS_REF=`git rev-parse --short HEAD` +- | + docker build \ + -t dockerpracticesig/docker_practice \ + -t dockerpracticesig/docker_practice:gitbook \ + --label org.opencontainers.image.revision=$VCS_REF \ + --label org.opencontainers.image.source="https://github.com/yeasy/docker_practice" \ + --label maintainer="https://github.com/docker-practice" \ + . + +- docker run -dit --rm -p 4000:80 dockerpracticesig/docker_practice + +- sleep 5 +- curl 127.0.0.1:4000 + +- docker push dockerpracticesig/docker_practice +- docker push dockerpracticesig/docker_practice:gitbook + +- cd _book +- rm -rf .github/workflows +- git init +- git remote add origin "$DEPLOY_REPO" +- git add . +- COMMIT=`date "+%F %T"` +- git commit -m "Travis CI Site updated $COMMIT yeasy/docker_practice@${TRAVIS_COMMIT}" +- git push -f origin master:"$DEPLOY_BRANCH" + +env: + global: + - DEPLOY_BRANCH: master + - DEPLOY_REPO: git@github.com:docker-practice/zh-cn.git + +addons: + ssh_known_hosts: + - github.com + +branches: + only: + - master diff --git a/.travis/Dockerfile b/.travis/Dockerfile new file mode 100644 index 000000000..cb4c7f36d --- /dev/null +++ b/.travis/Dockerfile @@ -0,0 +1,26 @@ +FROM node:14.4.0-alpine + +ENV TZ=Asia/Shanghai + +WORKDIR /srv/gitbook + +COPY book.json book.json + +COPY docker-entrypoint.sh /usr/local/bin/ + +RUN set -x && apk add --no-cache \ + tzdata \ + && npm install -g gitbook-cli \ + && gitbook install \ + && ln -s /usr/local/bin/docker-entrypoint.sh / \ + && rm -rf /root/.npm /tmp/* + +EXPOSE 4000 + +VOLUME /srv/gitbook-src + +WORKDIR /srv/gitbook-src + +ENTRYPOINT ["docker-entrypoint.sh"] + +CMD server diff --git a/.travis/book.json b/.travis/book.json new file mode 100644 index 000000000..95d0b6758 --- /dev/null +++ b/.travis/book.json @@ -0,0 +1,37 @@ +{ + "title": "Docker -- 从入门到实践", + "author": "yeasy", + "language": "zh-hans", + "links": { + "sidebar": { + "GitHub": "https://github.com/yeasy/docker_practice" + } + }, + "plugins": [ + "-livereload", + "image-captions", + "github", + "page-treeview@2.9.8", + "editlink" + ], + "pluginsConfig": { + "image-captions": { + "attributes": { + "width": "600" + }, + "caption": "图 _PAGE_LEVEL_._PAGE_IMAGE_NUMBER_ - _CAPTION_" + }, + "github": { + "url": "https://github.com/yeasy/docker_practice" + }, + "editlink": { + "base": "https://github.com/yeasy/docker_practice/blob/master/", + "label": "编辑本页" + }, + "page-treeview": { + "copyright": "Copyright © yeasy", + "minHeaderCount": "2", + "minHeaderDeep": "2" + } + } +} diff --git a/.travis/conf.d/nginx.conf b/.travis/conf.d/nginx.conf new file mode 100644 index 000000000..4d09a3738 --- /dev/null +++ b/.travis/conf.d/nginx.conf @@ -0,0 +1,43 @@ +user root; +worker_processes auto; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + index index.html index.php; + + server { + + server_name localhost; + + listen 4000; + + root /srv/www/; + + index index.html; + + } +} diff --git a/.travis/docker-compose.test.yml b/.travis/docker-compose.test.yml new file mode 100644 index 000000000..2e0c11726 --- /dev/null +++ b/.travis/docker-compose.test.yml @@ -0,0 +1,5 @@ +sut: + build: . + volumes: + - ../:/srv/gitbook-src + command: build diff --git a/.travis/docker-entrypoint.sh b/.travis/docker-entrypoint.sh new file mode 100755 index 000000000..21d66fc9a --- /dev/null +++ b/.travis/docker-entrypoint.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +START=`date "+%F %T"` + +if [ $1 = "sh" ];then sh ; exit 0; fi + +rm -rf node_modules _book + +srcDir=$PWD + +cp -a . /srv/gitbook + +cd /srv/gitbook + +main(){ + if [ "$1" = build ];then + gitbook build && cp -a _book $srcDir && echo $START && date "+%F %T" && exit 0 + else + exec gitbook serve + fi +} + +main $1 $2 $3 diff --git a/.travis/id_rsa.enc b/.travis/id_rsa.enc new file mode 100644 index 000000000..5e4575408 Binary files /dev/null and b/.travis/id_rsa.enc differ diff --git a/.travis/update.sh b/.travis/update.sh new file mode 100755 index 000000000..713934380 --- /dev/null +++ b/.travis/update.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# cd .travis +# ./update.sh + +if [ ! -f Dockerfile ];then exit 1; fi + +cp -a ../book.json book.json diff --git a/.vuepress/config.js b/.vuepress/config.js new file mode 100644 index 000000000..ce8fed5ed --- /dev/null +++ b/.vuepress/config.js @@ -0,0 +1,398 @@ +module.exports = { + title: 'Docker 从入门到实践', + base: '/', + head: [['script', {}, ` + var _hmt = _hmt || []; + (function() { + var hm = document.createElement("script"); + hm.src = "//hm.baidu.com/hm.js?81a3490c9cd141dbcf6d00bc18b6edae"; + var s = document.getElementsByTagName("script")[0]; + s.parentNode.insertBefore(hm, s); + })(); +`], + [ + 'script', {}, ` + (function(){ + var bp = document.createElement('script'); + var curProtocol = window.location.protocol.split(':')[0]; + if (curProtocol === 'https') { + bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; + } + else { + bp.src = 'http://push.zhanzhang.baidu.com/push.js'; + } + var s = document.getElementsByTagName("script")[0]; + s.parentNode.insertBefore(bp, s); +})(); + ` + ] + ], + plugins: { + sitemap: { + hostname: 'https://vuepress.mirror.docker-practice.com' + }, + }, + themeConfig: { + docsRepo: 'yeasy/docker_practice', + docsDir: '/', + editLinks: true, + nav: [{ + text: '安装 Docker', + link: '/install/', + }, + { + text: 'Docker 入门', + link: '/' + }, + { + text: 'Docker 实战', + link: '/cases/os/' + }, + { + text: 'CI/CD', + link: '/cases/ci/' + }, + { + text: 'Docker 仓库', + link: '/repository/' + }, + { + text: '底层实现', + link: '/underly/', + }, + { + text: 'Compose', + link: '/compose/', + }, + { + text: 'Kubernetes', + link: '/kubernetes/', + }, + { + text: "云计算", + link: "/cloud/", + }, + { + text: 'GitHub', + link: 'https://github.com/yeasy/docker_practice' + }, + // { + // text: '捐赠', + // link: '' + // }, + { + text: '腾讯云容器服务', + link: 'https://cloud.tencent.com/redirect.php?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61' + }, + // { + // text: '语言', + // items: [{ + // text: 'English', + // link: '' + // }] + // } + ], + sidebar: { + '/cloud/': [ + 'intro', + 'tencentCloud', + 'alicloud', + 'aws', + 'summary', + ], + '/kubernetes/': [ + 'intro', + 'concepts', + 'design', + { + title: "部署 Kubernetes", + collapsable: false, + children: [ + "setup/", + "setup/kubeadm", + "setup/docker-desktop", + "setup/systemd", + "setup/dashboard", + ] + }, + { + title: "Kubernetes 命令行 kubectl", + collapsable: false, + children: [ + 'kubectl/' + ] + } + ], + '/compose/': [ + 'introduction', + 'install', + 'usage', + 'commands', + 'compose_file', + 'django', + 'rails', + 'wordpress', + 'lnmp', + ], + '/install/': [ + 'ubuntu', + 'debian', + 'fedora', + 'centos', + 'raspberry-pi', + 'offline', + 'mac', + 'windows', + 'mirror', + 'experimental', + ], + '/underly/': [ + 'arch', + 'namespace', + 'cgroups', + 'ufs', + 'container_format', + 'network', + ], + '/repository/': [ + 'dockerhub', + 'registry', + 'registry_auth', + 'nexus3_registry', + ], + '/cases/os/': [ + { + title: "操作系统", + collapsable: false, + children: [ + 'busybox', + 'alpine', + 'debian', + 'centos', + 'summary', + ], + }, + { + title: "在 IDE 中使用 Docker", + collapsable: false, + children: [ + '/ide/', + '/ide/vsCode', + ], + }, + ], + '/cases/ci/': [ + 'actions/', + { + title: "Drone", + collapsable: false, + children: [ + 'drone/', + 'drone/install' + ] + }, + 'travis/' + ], + '/': [ + '/', + '/CHANGELOG', + '/CONTRIBUTING', + { + title: "Docker 简介", + collapsable: false, + children: [ + 'introduction/', + 'introduction/what', + 'introduction/why', + ] + }, { + title: "基本概念", + collapsable: false, + children: [ + 'basic_concept/', + 'basic_concept/image', + 'basic_concept/container', + 'basic_concept/repository' + ] + }, + { + title: "使用镜像", + collapsable: false, + children: [ + 'image/', + 'image/pull', + 'image/list', + 'image/rm', + 'image/commit', + 'image/build', + 'image/other.md', + 'image/internal.md', + ] + }, + { + title: 'Dockerfile', + collapsable: false, + children: [ + "image/dockerfile/", + 'image/dockerfile/copy', + 'image/dockerfile/add', + 'image/dockerfile/cmd', + 'image/dockerfile/entrypoint', + 'image/dockerfile/env', + 'image/dockerfile/arg', + 'image/dockerfile/volume', + 'image/dockerfile/expose', + 'image/dockerfile/workdir', + 'image/dockerfile/user', + 'image/dockerfile/healthcheck', + 'image/dockerfile/onbuild', + 'image/dockerfile/references', + 'image/multistage-builds/', + 'image/multistage-builds/laravel', + 'image/manifest', + ] + }, { + title: "操作容器", + collapsable: false, + children: [ + 'container/', + 'container/run', + 'container/daemon', + 'container/stop', + 'container/attach_exec', + 'container/import_export', + 'container/rm', + ], + }, + { + title: "数据管理", + collapsable: false, + children: [ + 'data_management/', + 'data_management/volume', + 'data_management/bind-mounts', + ], + }, { + title: "使用网络", + collapsable: false, + children: [ + 'network/', + 'network/port_mapping', + 'network/linking', + 'network/dns', + ], + }, + { + title: "高级网络配置", + collapsable: false, + children: [ + 'advanced_network/', + 'advanced_network/quick_guide', + 'advanced_network/access_control', + 'advanced_network/port_mapping', + 'advanced_network/bridge', + 'advanced_network/example', + 'advanced_network/config_file', + 'advanced_network/ptp', + ], + }, + { + title: "Swarm mode", + collapsable: false, + children: [ + 'swarm_mode/', + 'swarm_mode/overview', + 'swarm_mode/create', + 'swarm_mode/deploy', + 'swarm_mode/stack', + 'swarm_mode/secret', + 'swarm_mode/config', + 'swarm_mode/rolling_update', + ], + }, + { + title: "安全", + collapsable: false, + children: [ + 'security/', + 'security/kernel_ns', + 'security/control_group', + 'security/daemon_sec', + 'security/kernel_capability', + 'security/other_feature', + 'security/summary', + ], + }, + { + title: "Docker Buildx", + collapsable: false, + children: [ + "buildx/", + "buildx/buildkit", + "buildx/buildx", + "buildx/multi-arch-images", + ], + }, + { + title: "Etcd", + collapsable: false, + children: [ + 'etcd/', + 'etcd/intro', + 'etcd/install', + 'etcd/cluster', + 'etcd/etcdctl', + ], + }, + { + title: "Fedora CoreOS", + collapsable: false, + children: [ + 'coreos/', + 'coreos/intro', + 'coreos/install', + ], + }, + { + title: "Docker 开源项目", + collapsable: false, + children: [ + 'opensource/', + 'opensource/linuxkit', + ], + }, + 'podman/', + 'appendix/faq/', + { + title: "热门镜像介绍", + collapsable: false, + children: [ + 'appendix/repo/', + 'appendix/repo/ubuntu', + 'appendix/repo/centos', + 'appendix/repo/nginx', + 'appendix/repo/php', + 'appendix/repo/nodejs', + 'appendix/repo/mysql', + 'appendix/repo/wordpress', + 'appendix/repo/mongodb', + 'appendix/repo/redis', + 'appendix/repo/minio', + ], + }, + { + title: "Docker 命令", + collapsable: false, + children: [ + 'appendix/command/', + 'appendix/command/docker', + 'appendix/command/dockerd', + ] + }, + 'appendix/best_practices', + 'appendix/debug', + 'appendix/resources', + ], + }, + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..2e04a3d6b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,123 @@ +# 修订记录 + +* 1.2.0 2020-12-31 + +* 1.1.0 2019-12-31 + * 全面支持 v19.x 新版本 + * 增加 `BuildKit` + * 增加 `docker buildx` 命令使用说明 + * 增加 `docker manifest` 命令使用说明 + * 移除 `Ubuntu 14.04` `Debian 8` `Debian 7` + +* 1.0.0: 2018-12-31 + * 全面支持 v18.x 新版本 + * 添加如何调试 Docker + * 错误修正 + +* 0.9.0: 2017-12-31 + * 对 v1.13.x 旧版本的最后支持 + +* 0.9.0-rc2: 2017-12-10 + + * 增加 Docker 中文资源链接 + * 增加介绍基于 Docker 的 CI/CD 工具 `Drone` + * 增加 `docker secret` 相关内容 + * 增加 `docker config` 相关内容 + * 增加 `LinuxKit` 相关内容 + + * 更新 `CoreOS` 章节 + * 更新 `etcd` 章节,基于 3.x 版本 + + * 删除 `Docker Compose` 中的 `links`指令 + + * 替换 `docker daemon` 命令为 `dockerd` + * 替换 `docker ps` 命令为 `docker container ls` + * 替换 `docker images` 命令为 `docker image ls` + + * 修改 `安装 Docker` 一节中部分文字表述 + + * 移除历史遗留文件和错误的文件 + * 优化文字排版 + * 调整目录结构 + * 修复内容逻辑错误 + * 修复`404` 链接 + +* 0.9.0-rc1: 2017-11-29 + + * 根据最新版本(v17.09)修订内容 + + * 增加 `Dockerfile` 多阶段构建( `multistage builds` ) `Docker 17.05` 新增特性 + * 增加 `docker exec` 子命令介绍 + * 增加 `docker` 管理子命令 `container` `image` `network` `volume` 介绍 + * 增加 `树莓派单片电脑` 安装 Docker + * 增加 Docker 存储驱动 `OverlayFS` 相关内容 + + * 更新 `Docker CE` `v17.x` 安装说明 + * 更新 `Docker 网络` 一节 + * 更新 `Docker Machine` 基于 0.13.0 版本 + * 更新 `Docker Compose` 基于 3 文件格式 + + * 删除 `Docker Swarm` 相关内容,替换为 `Swarm mode` `Docker 1.12.0` 新增特性 + * 删除 `docker run` `--link` 参数 + + * 精简 `Docker Registry` 一节 + + * 替换 `docker run` `-v` 参数为 `--mount` + + * 修复 `404` 链接 + * 优化文字排版 + * 增加离线阅读功能 + +* 0.8.0: 2017-01-08 + + * 修正文字内容 + * 根据最新版本(1.12)修订安装使用 + * 补充附录章节 + +* 0.7.0: 2016-06-12 + + * 根据最新版本进行命令调整 + * 修正若干文字描述 + +* 0.6.0: 2015-12-24 + + * 补充 Machine 项目 + * 修正若干 bug + +* 0.5.0: 2015-06-29 + + * 添加 Compose 项目 + * 添加 Machine 项目 + * 添加 Swarm 项目 + * 完善 Kubernetes 项目内容 + * 添加 Mesos 项目内容 + +* 0.4.0: 2015-05-08 + + * 添加 Etcd 项目 + * 添加 Fig 项目 + * 添加 CoreOS 项目 + * 添加 Kubernetes 项目 + +* 0.3.0: 2014-11-25 + + * 完成仓库章节 + * 重写安全章节 + * 修正底层实现章节的架构、命名空间、控制组、文件系统、容器格式等内容 + * 添加对常见仓库和镜像的介绍 + * 添加 Dockerfile 的介绍 + * 重新校订中英文混排格式 + * 修订文字表达 + * 发布繁体版本分支:zh-Hant + +* 0.2.0: 2014-09-18 + + * 对照官方文档重写介绍、基本概念、安装、镜像、容器、仓库、数据管理、网络等章节 + * 添加底层实现章节 + * 添加命令查询和资源链接章节 + * 其它修正 + +* 0.1.0: 2014-09-05 + + * 添加基本内容 + * 修正错别字和表达不通顺的地方 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..65162c145 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,41 @@ +# 如何贡献 + +领取或创建新的 [Issue](https://github.com/yeasy/docker_practice/issues),如 [issue 235](https://github.com/yeasy/docker_practice/issues/235),添加自己为 `Assignee`。 + +在 [GitHub](https://github.com/yeasy/docker_practice/fork) 上 `fork` 到自己的仓库,如 `docker_user/docker_practice`,然后 `clone` 到本地,并设置用户信息。 + +```bash +$ git clone git@github.com:docker_user/docker_practice.git + +$ cd docker_practice +``` + +修改代码后提交,并推送到自己的仓库,注意修改提交消息为对应 Issue 号和描述。 + +```bash +# Update the content + +$ git commit -a -s + +# In commit msg dialog, add content like "Fix issue #235: describe ur change" + +$ git push +``` + +在 [GitHub](https://github.com/yeasy/docker_practice/pulls) 上提交 `Pull Request`,添加标签,并邀请维护者进行 `Review`。 + +定期使用项目仓库内容更新自己仓库内容。 + +```bash +$ git remote add upstream https://github.com/yeasy/docker_practice + +$ git fetch upstream + +$ git rebase upstream/master + +$ git push -f origin master +``` + +## 排版规范 + +本开源书籍遵循 [中文排版指南](https://github.com/mzlogin/chinese-copywriting-guidelines) 规范。 diff --git a/README.md b/README.md index 53ea0b797..a2bda5734 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,40 @@ # Docker — 从入门到实践 -0.7.6 +[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v19.x-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)][1] -[Docker](http://www.docker.com) 是个划时代的开源项目,它彻底释放了虚拟化的威力,极大提高了应用的运行效率,降低了云计算资源供应的成本,同时让应用的部署、测试和分发都变得前所未有的高效和轻松! +**v1.2.0** -无论是应用开发者,运维人员,还是云计算从业人员,都有必要认识和掌握 Docker,以在有限的时间内做更多有意义的事。 +| 语言 | 构建状态 | - | +| :------------- | :------------- | :--- | +| [zh-hans](https://github.com/yeasy/docker_practice) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://vuepress.mirror.docker-practice.com/) | +| [us-en](https://github.com/yeasy/docker_practice/tree/english) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=english)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/us-en) | +| [zh-hant](https://github.com/yeasy/docker_practice/tree/zh-Hant) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=zh-hant)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/zh-hant) | -本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍一些高级操作;第 10 章给出典型的应用场景和实践案例;11 ~ 13 章介绍关于 Docker 实现的相关细节技术。后续章节则分别介绍一些相关的热门开源项目。 +[Docker](https://www.docker.com) 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松! -在线阅读:[GitBook](https://www.gitbook.io/book/yeasy/docker_practice) 或 [Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md)。 +无论是应用开发者、运维人员、还是其他信息技术从业人员,都有必要认识和掌握 Docker,节约有限的生命。 -* pdf 版本 [下载](https://www.gitbook.com/download/pdf/book/yeasy/docker_practice) -* epub 版本 [下载](https://www.gitbook.com/download/epub/book/yeasy/docker_practice) +本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 12 章介绍了容器生态中的几个核心项目;13、14 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、Fedora CoreOS、Kubernetes、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 -欢迎关注 DockerPool 社区微博 [@dockerpool](http://weibo.com/u/5345404432),或加入 Docker 技术交流 QQ 群或微信组,分享 Docker 资源,交流 Docker 技术。 +* 在线阅读:[docker-practice.com](https://vuepress.mirror.docker-practice.com/),[GitBook](https://yeasy.gitbook.io/docker_practice/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) +* [离线阅读 `$ docker run -it --rm -p 4000:80 ccr.ccs.tencentyun.com/dockerpracticesig/docker_practice:vuepress`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) + +Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初学者使用最新稳定版本的 Docker 进行学习实践。欢迎 [参与项目维护](CONTRIBUTING.md)。 + +* [修订记录](CHANGELOG.md) +* [贡献者名单](https://github.com/yeasy/docker_practice/graphs/contributors) + +## 微信小程序 + +

+ +

+ +

微信扫码 随时随地阅读~

+ +## 技术交流 + +欢迎加入 Docker 技术交流 QQ 群,分享 Docker 资源,交流 Docker 技术。 * QQ 群 I (已满):341410255 * QQ 群 II (已满):419042067 @@ -24,93 +45,31 @@ * QQ 群 VII (已满):252403484 * QQ 群 VIII(已满):544818750 * QQ 群 IX (已满):571502246 -* QQ 群 X (可加):366203473 - -![Docker 技术入门与实战](docker_primer.png) - -《[Docker 技术入门与实战](http://item.jd.com/11598400.html)》一书已经正式出版,包含大量第一手实战案例和更为深入的技术剖析,欢迎大家阅读使用并反馈建议。 - -* [China-Pub](http://product.china-pub.com/3770833) -* [京东图书](http://item.jd.com/11598400.html) -* [当当图书](http://product.dangdang.com/23620853.html) -* [亚马逊图书](http://www.amazon.cn/%E5%9B%BE%E4%B9%A6/dp/B00R5MYI7C/ref=lh_ni_t?ie=UTF8&psc=1&smid=A1AJ19PSB66TGU) - -## 主要版本历史 - -* 0.8.0: 2016-MM-DD - * 修正文字内容 - * 根据最新版本修订安装使用 - * 补充附录章节 - -* 0.7.0: 2016-06-12 - * 根据最新版本进行命令调整 - * 修正若干文字描述 - -* 0.6.0: 2015-12-24 - * 补充 Machine 项目 - * 修正若干 bug - -* 0.5.0: 2015-06-29 - * 添加 Compose 项目 - * 添加 Machine 项目 - * 添加 Swarm 项目 - * 完善 Kubernetes 项目内容 - * 添加 Mesos 项目内容 - -* 0.4.0: 2015-05-08 - * 添加 Etcd 项目 - * 添加 Fig 项目 - * 添加 CoreOS 项目 - * 添加 Kubernetes 项目 - -* 0.3.0: 2014-11-25 - * 完成仓库章节; - * 重写安全章节; - * 修正底层实现章节的架构、命名空间、控制组、文件系统、容器格式等内容; - * 添加对常见仓库和镜像的介绍; - * 添加 Dockerfile 的介绍; - * 重新校订中英文混排格式。 - * 修订文字表达。 - * 发布繁体版本分支:zh-Hant。 - -* 0.2.0: 2014-09-18 - * 对照官方文档重写介绍、基本概念、安装、镜像、容器、仓库、数据管理、网络等章节; - * 添加底层实现章节; - * 添加命令查询和资源链接章节; - * 其它修正。 - -* 0.1.0: 2014-09-05 - * 添加基本内容; - * 修正错别字和表达不通顺的地方。 - - -Docker 自身仍在快速发展中,生态环境也在蓬勃成长。源码开源托管在 Github 上,欢迎参与维护:[https:\/\/github.com\/yeasy\/docker\_practice](https://github.com/yeasy/docker_practice)。贡献者 [名单](https://github.com/yeasy/docker_practice/graphs/contributors)。 - -## 参加步骤 - -* 在 GitHub 上 `fork` 到自己的仓库,如 `docker_user/docker_practice`,然后 `clone` 到本地,并设置用户信息。 - ``` - $ git clone git@github.com:docker_user/docker_practice.git - $ cd docker_practice - $ git config user.name "yourname" - $ git config user.email "your email" - ``` - -* 修改代码后提交,并推送到自己的仓库。 - ``` - $ #do some change on the content - $ git commit -am "Fix issue #1: change helo to hello" - $ git push - ``` - -* 在 GitHub 网站上提交 pull request。 -* 定期使用项目仓库内容更新自己仓库内容。 - ``` - $ git remote add upstream https://github.com/yeasy/docker_practice - $ git fetch upstream - $ git checkout master - $ git rebase upstream/master - $ git push -f origin master - ``` +* QQ 群 X (可加):145983035 + +>如果有容器相关的疑问,请通过 [Issues](https://github.com/yeasy/docker_practice/issues/new/choose) 来提出。 + +

+ +

+ +

微信扫码 加入群聊~ 或者微信添加 dpsigs 邀请入群

+ +## 进阶学习 + +[![](https://github.com/yeasy/docker_practice/raw/master/_images/docker_primer3.png)][1] + +《[Docker 技术入门与实战][1]》第三版已经面世,介绍最新的容器技术栈,欢迎大家阅读使用并反馈建议。 + +* [京东图书][1] +* [China-Pub](http://product.china-pub.com/8052127) + +## 鼓励项目 + +

+ +

+

欢迎鼓励项目一杯 coffee~

+[1]: https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS diff --git a/SUMMARY.md b/SUMMARY.md index 4694c1f15..3fba08427 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,6 +1,8 @@ -# Summary +# [Docker — 从入门到实践](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) * [前言](README.md) +* [修订记录](CHANGELOG.md) +* [如何贡献](CONTRIBUTING.md) * [Docker 简介](introduction/README.md) * [什么是 Docker](introduction/what.md) * [为什么要用 Docker](introduction/why.md) @@ -8,14 +10,21 @@ * [镜像](basic_concept/image.md) * [容器](basic_concept/container.md) * [仓库](basic_concept/repository.md) -* [安装](install/README.md) - * [Ubuntu、Debian](install/ubuntu.md) +* [安装 Docker](install/README.md) + * [Ubuntu](install/ubuntu.md) + * [Debian](install/debian.md) + * [Fedora](install/fedora.md) * [CentOS](install/centos.md) + * [Raspberry Pi](install/raspberry-pi.md) + * [Linux 离线安装](install/offline.md) * [macOS](install/mac.md) + * [Windows 10](install/windows.md) * [镜像加速器](install/mirror.md) -* [镜像](image/README.md) + * [开启实验特性](install/experimental.md) +* [使用镜像](image/README.md) * [获取镜像](image/pull.md) * [列出镜像](image/list.md) + * [删除本地镜像](image/rm.md) * [利用 commit 理解镜像构成](image/commit.md) * [使用 Dockerfile 定制镜像](image/build.md) * [Dockerfile 指令详解](image/dockerfile/README.md) @@ -32,30 +41,32 @@ * [HEALTHCHECK 健康检查](image/dockerfile/healthcheck.md) * [ONBUILD 为他人作嫁衣裳](image/dockerfile/onbuild.md) * [参考文档](image/dockerfile/references.md) + * [Dockerfile 多阶段构建](image/multistage-builds/README.md) + * [实战多阶段构建 Laravel 镜像](image/multistage-builds/laravel.md) + * [构建多种系统架构支持的 Docker 镜像](image/manifest.md) * [其它制作镜像的方式](image/other.md) - * [删除本地镜像](image/rmi.md) * [实现原理](image/internal.md) -* [容器](container/README.md) +* [操作容器](container/README.md) * [启动](container/run.md) * [守护态运行](container/daemon.md) * [终止](container/stop.md) - * [进入容器](container/enter.md) + * [进入容器](container/attach_exec.md) * [导出和导入](container/import_export.md) * [删除](container/rm.md) -* [仓库](repository/README.md) +* [访问仓库](repository/README.md) * [Docker Hub](repository/dockerhub.md) - * [私有仓库](repository/local_repo.md) - * [配置文件](repository/config.md) + * [私有仓库](repository/registry.md) + * [私有仓库高级配置](repository/registry_auth.md) + * [Nexus 3](repository/nexus3_registry.md) * [数据管理](data_management/README.md) * [数据卷](data_management/volume.md) - * [数据卷容器](data_management/container.md) - * [备份、恢复、迁移数据卷](data_management/management.md) + * [挂载主机目录](data_management/bind-mounts.md) * [使用网络](network/README.md) * [外部访问容器](network/port_mapping.md) * [容器互联](network/linking.md) + * [配置 DNS](network/dns.md) * [高级网络配置](advanced_network/README.md) * [快速配置指南](advanced_network/quick_guide.md) - * [配置 DNS](advanced_network/dns.md) * [容器访问控制](advanced_network/access_control.md) * [端口映射实现](advanced_network/port_mapping.md) * [配置 docker0 网桥](advanced_network/docker0.md) @@ -63,11 +74,28 @@ * [工具和示例](advanced_network/example.md) * [编辑网络配置文件](advanced_network/config_file.md) * [实例:创建一个点到点连接](advanced_network/ptp.md) -* [实战案例](cases/README.md) - * [使用 Supervisor 来管理进程](cases/supervisor.md) - * [创建 tomcat\/weblogic 集群](cases/tomcat.md) - * [多台物理主机之间的容器互联](cases/container_connect.md) - * [标准化开发测试和生产环境](cases/environment.md) +* [Docker Buildx](buildx/README.md) + * [BuildKit](buildx/buildkit.md) + * [使用 buildx 构建镜像](buildx/buildx.md) + * [使用 buildx 构建多种系统架构支持的 Docker 镜像](buildx/multi-arch-images.md) +* [Docker Compose](compose/README.md) + * [简介](compose/introduction.md) + * [安装与卸载](compose/install.md) + * [使用](compose/usage.md) + * [命令说明](compose/commands.md) + * [Compose 模板文件](compose/compose_file.md) + * [实战 Django](compose/django.md) + * [实战 Rails](compose/rails.md) + * [实战 WordPress](compose/wordpress.md) + * [实战 LNMP](compose/lnmp.md) +* [Swarm mode](swarm_mode/README.md) + * [基本概念](swarm_mode/overview.md) + * [创建 Swarm 集群](swarm_mode/create.md) + * [部署服务](swarm_mode/deploy.md) + * [使用 compose 文件](swarm_mode/stack.md) + * [管理密钥](swarm_mode/secret.md) + * [管理配置信息](swarm_mode/config.md) + * [滚动升级](swarm_mode/rolling_update.md) * [安全](security/README.md) * [内核命名空间](security/kernel_ns.md) * [控制组](security/control_group.md) @@ -82,55 +110,75 @@ * [联合文件系统](underly/ufs.md) * [容器格式](underly/container_format.md) * [网络](underly/network.md) -* [Docker Compose 项目](compose/README.md) - * [简介](compose/intro.md) - * [安装](compose/install.md) - * [使用](compose/usage.md) - * [命令说明](compose/commands.md) - * [YAML 模板文件](compose/yaml_file.md) - * [实战 Django](compose/django.md) - * [实战 Rails](compose/rails.md) - * [实战 wordpress](compose/wordpress.md) -* [Docker Machine 项目](machine/README.md) - * [简介](machine/intro.md) - * [安装](machine/install.md) - * [使用](machine/usage.md) -* [Docker Swarm 项目](swarm/README.md) - * [简介](swarm/intro.md) - * [安装](swarm/install.md) - * [使用](swarm/usage.md) - * [调度器](swarm/scheduling.md) - * [过滤器](swarm/filter.md) * [Etcd 项目](etcd/README.md) * [简介](etcd/intro.md) * [安装](etcd/install.md) + * [集群](etcd/cluster.md) * [使用 etcdctl](etcd/etcdctl.md) -* [CoreOS 项目](coreos/README.md) +* [Fedora CoreOS](coreos/README.md) * [简介](coreos/intro.md) - * [工具](coreos/intro_tools.md) - * [快速搭建CoreOS集群](coreos/quickstart.md) -* [Kubernetes 项目](kubernetes/README.md) + * [安装](coreos/install.md) +* [Kubernetes - 开源容器编排引擎](kubernetes/README.md) * [简介](kubernetes/intro.md) - * [快速上手](kubernetes/quickstart.md) * [基本概念](kubernetes/concepts.md) - * [kubectl 使用](kubernetes/kubectl.md) * [架构设计](kubernetes/design.md) -* [Mesos 项目](mesos/README.md) - * [简介](mesos/intro.md) - * [安装与使用](mesos/installation.md) - * [原理与架构](mesos/architecture.md) - * [配置项解析](mesos/configuration.md) - * [常见框架](mesos/framework.md) +* [部署 Kubernetes](kubernetes/setup/README.md) + * [使用 kubeadm 部署 kubernetes](kubernetes/setup/kubeadm.md) + * [在 Docker Desktop 使用](kubernetes/setup/docker-desktop.md) + * [一步步部署 kubernetes 集群](kubernetes/setup/systemd.md) + * [部署 Dashboard](kubernetes/setup/dashboard.md) +* [Kubernetes 命令行 kubectl](kubernetes/kubectl/README.md) +* [容器与云计算](cloud/README.md) + * [简介](cloud/intro.md) + * [腾讯云](cloud/tencentCloud.md) + * [阿里云](cloud/alicloud.md) + * [亚马逊云](cloud/aws.md) + * [小结](cloud/summary.md) +* [实战案例 - 操作系统](cases/os/README.md) + * [Busybox](cases/os/busybox.md) + * [Alpine](cases/os/alpine.md) + * [Debian Ubuntu](cases/os/debian.md) + * [CentOS Fedora](cases/os/centos.md) + * [本章小结](cases/os/summary.md) +* [实战案例 - CI/CD](cases/ci/README.md) + * [GitHub Actions](cases/ci/actions/README.md) + * [Drone](cases/ci/drone/README.md) + * [部署 Drone](cases/ci/drone/install.md) + * [Travis CI](cases/ci/travis/README.md) +* [在 IDE 中使用 Docker](ide/README.md) + * [VS Code](ide/vsCode.md) +* [Docker 开源项目](opensource/README.md) + * [LinuxKit](opensource/linuxkit.md) +* [podman - 下一代 Linux 容器工具](podman/README.md) * [附录](appendix/README.md) * [附录一:常见问题总结](appendix/faq/README.md) * [附录二:热门镜像介绍](appendix/repo/README.md) * [Ubuntu](appendix/repo/ubuntu.md) * [CentOS](appendix/repo/centos.md) + * [Nginx](appendix/repo/nginx.md) + * [PHP](appendix/repo/php.md) + * [Node.js](appendix/repo/nodejs.md) * [MySQL](appendix/repo/mysql.md) + * [WordPress](appendix/repo/wordpress.md) * [MongoDB](appendix/repo/mongodb.md) * [Redis](appendix/repo/redis.md) - * [Nginx](appendix/repo/nginx.md) - * [WordPress](appendix/repo/wordpress.md) - * [Node.js](appendix/repo/nodejs.md) + * [Minio](appendix/repo/minio.md) * [附录三:Docker 命令查询](appendix/command/README.md) - * [附录四:资源链接](appendix/resources/README.md) + * [客户端命令 - docker](appendix/command/docker.md) + * [服务端命令 - dockerd](appendix/command/dockerd.md) + * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) + * [附录五:如何调试 Docker](appendix/debug.md) + * [附录六:资源链接](appendix/resources.md) +* [归档](archive/README.md) + * [Mesos - 优秀的集群资源调度平台](mesos/README.md) + * [Mesos 简介](mesos/intro.md) + * [安装与使用](mesos/installation.md) + * [原理与架构](mesos/architecture.md) + * [Mesos 配置项解析](mesos/configuration.md) + * [日志与监控](mesos/monitor.md) + * [常见应用框架](mesos/framework.md) + * [本章小结](mesos/summary.md) + * [Docker Machine](machine/README.md) + * [安装](machine/install.md) + * [使用](machine/usage.md) + * [Docker Swarm](swarm/README.md) diff --git a/_config.yml b/_config.yml new file mode 100644 index 000000000..dbc839919 --- /dev/null +++ b/_config.yml @@ -0,0 +1,2 @@ +theme: jekyll-theme-slate +include: [_images] diff --git a/_images/compose.png b/_images/compose.png deleted file mode 100644 index d753482d1..000000000 Binary files a/_images/compose.png and /dev/null differ diff --git a/_images/container_connect_topology.png b/_images/container_connect_topology.png deleted file mode 100644 index 5419d5653..000000000 Binary files a/_images/container_connect_topology.png and /dev/null differ diff --git a/_images/cover.jpg b/_images/cover.jpg new file mode 100644 index 000000000..ad6fa3281 Binary files /dev/null and b/_images/cover.jpg differ diff --git a/cover.sketch b/_images/cover.sketch similarity index 100% rename from cover.sketch rename to _images/cover.sketch diff --git a/cover_small.jpg b/_images/cover_small.jpg similarity index 100% rename from cover_small.jpg rename to _images/cover_small.jpg diff --git a/_images/docker_compose.jpg b/_images/docker_compose.jpg deleted file mode 100644 index d5fa64a1c..000000000 Binary files a/_images/docker_compose.jpg and /dev/null differ diff --git a/_images/docker_machine.png b/_images/docker_machine.png deleted file mode 100644 index e8c5632e2..000000000 Binary files a/_images/docker_machine.png and /dev/null differ diff --git a/docker_primer.png b/_images/docker_primer.png similarity index 100% rename from docker_primer.png rename to _images/docker_primer.png diff --git a/_images/docker_primer2.png b/_images/docker_primer2.png new file mode 100644 index 000000000..52c8c480d Binary files /dev/null and b/_images/docker_primer2.png differ diff --git a/_images/docker_primer3.png b/_images/docker_primer3.png new file mode 100644 index 000000000..83878f259 Binary files /dev/null and b/_images/docker_primer3.png differ diff --git a/_images/donate.jpeg b/_images/donate.jpeg new file mode 100644 index 000000000..6fcfa7ab9 Binary files /dev/null and b/_images/donate.jpeg differ diff --git a/_images/enterprise_usage.png b/_images/enterprise_usage.png deleted file mode 100644 index 5682892cf..000000000 Binary files a/_images/enterprise_usage.png and /dev/null differ diff --git a/_images/fig-example-large.gif b/_images/fig-example-large.gif deleted file mode 100644 index 27a82a444..000000000 Binary files a/_images/fig-example-large.gif and /dev/null differ diff --git a/_images/fig-example-large.png b/_images/fig-example-large.png deleted file mode 100644 index dc26d4fbc..000000000 Binary files a/_images/fig-example-large.png and /dev/null differ diff --git a/_images/fig-rails-screenshot.png b/_images/fig-rails-screenshot.png deleted file mode 100644 index f5f9cb517..000000000 Binary files a/_images/fig-rails-screenshot.png and /dev/null differ diff --git a/_images/install-mac-preference-advanced.png b/_images/install-mac-preference-advanced.png deleted file mode 100644 index d19c06264..000000000 Binary files a/_images/install-mac-preference-advanced.png and /dev/null differ diff --git a/_images/swarm.png b/_images/swarm.png deleted file mode 100644 index 4af7b271a..000000000 Binary files a/_images/swarm.png and /dev/null differ diff --git a/_layouts/website/page.html b/_layouts/website/page.html deleted file mode 100644 index cabab1bde..000000000 --- a/_layouts/website/page.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends template.self %} - -{% block head %} - {{ super() }} - -{% endblock %} diff --git a/_local/.bashrc_docker b/_local/.bashrc_docker deleted file mode 100644 index ed0df3ca1..000000000 --- a/_local/.bashrc_docker +++ /dev/null @@ -1,49 +0,0 @@ -# Some useful commands to use docker. -# Author: yeasy@github -# Created:2014-09-25 - -alias docker-pid="sudo docker inspect --format '{{.State.Pid}}'" -alias docker-ip="sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}'" - -#the implementation refs from https://github.com/jpetazzo/nsenter/blob/master/docker-enter -function docker-enter() { - #if [ -e $(dirname "$0")/nsenter ]; then - #Change for centos bash running - if [ -e $(dirname '$0')/nsenter ]; then - # with boot2docker, nsenter is not in the PATH but it is in the same folder - NSENTER=$(dirname "$0")/nsenter - else - # if nsenter has already been installed with path notified, here will be clarified - NSENTER=$(which nsenter) - #NSENTER=nsenter - fi - [ -z "$NSENTER" ] && echo "WARN Cannot find nsenter" && return - - if [ -z "$1" ]; then - echo "Usage: `basename "$0"` CONTAINER [COMMAND [ARG]...]" - echo "" - echo "Enters the Docker CONTAINER and executes the specified COMMAND." - echo "If COMMAND is not specified, runs an interactive shell in CONTAINER." - else - PID=$(sudo docker inspect --format "{{.State.Pid}}" "$1") - if [ -z "$PID" ]; then - echo "WARN Cannot find the given container" - return - fi - shift - - OPTS="--target $PID --mount --uts --ipc --net --pid" - - if [ -z "$1" ]; then - # No command given. - # Use su to clear all host environment variables except for TERM, - # initialize the environment variables HOME, SHELL, USER, LOGNAME, PATH, - # and start a login shell. - #sudo $NSENTER "$OPTS" su - root - sudo $NSENTER --target $PID --mount --uts --ipc --net --pid su - root - else - # Use env to clear all host environment variables. - sudo $NSENTER --target $PID --mount --uts --ipc --net --pid env -i $@ - fi - fi -} diff --git a/_local/docker_manual_waitfish.pdf b/_local/docker_manual_waitfish.pdf deleted file mode 100644 index add8577a3..000000000 Binary files a/_local/docker_manual_waitfish.pdf and /dev/null differ diff --git a/_local/pull_all.sh b/_local/pull_all.sh deleted file mode 100644 index 8240c0802..000000000 --- a/_local/pull_all.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -# This script will update all local images -# See: https://github.com/yeasy/docker_practice/blob/master/_local/pull_all.sh -# Usage: pull_all -# Author: yeasy@github -# Create: 2014-09-23 - -for image in `sudo docker images|grep -v "REPOSITORY"|grep -v ""|awk '{print $1":"$2}'` -do - sudo docker pull $image -done - diff --git a/_local/push_all.sh b/_local/push_all.sh deleted file mode 100644 index 2ec1aee00..000000000 --- a/_local/push_all.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# This script will upload all local images to a registry server ($registry is the default value). -# This script requires the push_images, which can be found at https://github.com/yeasy/docker_practice/blob/master/_local/push_images.sh -# Usage: push_all -# Author: yeasy@github -# Create: 2014-09-23 - -for image in `sudo docker images|grep -v "REPOSITORY"|grep -v ""|awk '{print $1":"$2}'` -do - push_images $image -done - diff --git a/_local/push_images.sh b/_local/push_images.sh deleted file mode 100644 index 5e7516f27..000000000 --- a/_local/push_images.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh - -# This script will upload the given local images to a registry server ($registry is the default value). -# See: https://github.com/yeasy/docker_practice/blob/master/_local/push_images.sh -# Usage: push_images image1 [image2...] -# Author: yeasy@github -# Create: 2014-09-23 - -#The registry server address where you want push the images into -registry=127.0.0.1:5000 - -### DO NOT MODIFY THE FOLLOWING PART, UNLESS YOU KNOW WHAT IT MEANS ### -echo_r () { - [ $# -ne 1 ] && return 0 - echo -e "\033[31m$1\033[0m" -} -echo_g () { - [ $# -ne 1 ] && return 0 - echo -e "\033[32m$1\033[0m" -} -echo_y () { - [ $# -ne 1 ] && return 0 - echo -e "\033[33m$1\033[0m" -} -echo_b () { - [ $# -ne 1 ] && return 0 - echo -e "\033[34m$1\033[0m" -} - -usage() { - sudo docker images - echo "Usage: $0 registry1:tag1 [registry2:tag2...]" -} - -[ $# -lt 1 ] && usage && exit - -echo_b "The registry server is $registry" - - -for image in "$@" -do - echo_b "Uploading $image..." - sudo docker tag $image $registry/$image - sudo docker push $registry/$image - sudo docker rmi $registry/$image - echo_g "Done" -done diff --git a/advanced_network/README.md b/advanced_network/README.md index f92c3aaf4..e21d4b3cf 100644 --- a/advanced_network/README.md +++ b/advanced_network/README.md @@ -1,12 +1,15 @@ # 高级网络配置 + +>注意:本章属于 `Docker` 高级配置,如果您是初学者,您可以暂时跳过本章节,直接学习 [Docker Compose](../compose) 一节。 + 本章将介绍 Docker 的一些高级网络配置和选项。 当 Docker 启动时,会自动在主机上创建一个 `docker0` 虚拟网桥,实际上是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。 -同时,Docker 随机分配一个本地未占用的私有网段(在 [RFC1918](http://tools.ietf.org/html/rfc1918) 中定义)中的一个地址给 `docker0` 接口。比如典型的 `172.17.42.1`,掩码为 `255.255.0.0`。此后启动的容器内的网口也会自动分配一个同一网段(`172.17.0.0/16`)的地址。 +同时,Docker 随机分配一个本地未占用的私有网段(在 [RFC1918](https://tools.ietf.org/html/rfc1918) 中定义)中的一个地址给 `docker0` 接口。比如典型的 `172.17.42.1`,掩码为 `255.255.0.0`。此后启动的容器内的网口也会自动分配一个同一网段(`172.17.0.0/16`)的地址。 当创建一个 Docker 容器的时候,同时会创建了一对 `veth pair` 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 `eth0`;另一端在本地并被挂载到 `docker0` 网桥,名称以 `veth` 开头(例如 `vethAQI2QT`)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。 -![Docker 网络](../_images/network.png) +![Docker 网络](_images/network.png) 接下来的部分将介绍在一些场景中,Docker 所有的网络定制配置。以及通过 Linux 命令来调整、补充、甚至替换 Docker 默认的网络配置。 diff --git a/_images/network.png b/advanced_network/_images/network.png similarity index 100% rename from _images/network.png rename to advanced_network/_images/network.png diff --git a/advanced_network/access_control.md b/advanced_network/access_control.md index acc204776..c382b5d7b 100644 --- a/advanced_network/access_control.md +++ b/advanced_network/access_control.md @@ -1,36 +1,36 @@ -## 容器访问控制 +# 容器访问控制 容器的访问控制,主要通过 Linux 上的 `iptables` 防火墙来进行管理和实现。`iptables` 是 Linux 上默认的防火墙软件,在大部分发行版中都自带。 -### 容器访问外部网络 +## 容器访问外部网络 容器要想访问外部网络,需要本地系统的转发支持。在Linux 系统中,检查转发是否打开。 -``` +```bash $sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1 ``` 如果为 0,说明没有开启转发,则需要手动打开。 -``` +```bash $sysctl -w net.ipv4.ip_forward=1 ``` 如果在启动 Docker 服务的时候设定 `--ip-forward=true`, Docker 就会自动设定系统的 `ip_forward` 参数为 1。 -### 容器之间访问 +## 容器之间访问 容器之间相互访问,需要两方面的支持。 * 容器的网络拓扑是否已经互联。默认情况下,所有容器都会被连接到 `docker0` 网桥上。 * 本地系统的防火墙软件 -- `iptables` 是否允许通过。 -#### 访问所有端口 -当启动 Docker 服务时候,默认会添加一条转发策略到 iptables 的 FORWARD 链上。策略为通过(`ACCEPT`)还是禁止(`DROP`)取决于配置`--icc=true`(缺省值)还是 `--icc=false`。当然,如果手动指定 `--iptables=false` 则不会添加 `iptables` 规则。 +### 访问所有端口 +当启动 Docker 服务(即 dockerd)的时候,默认会添加一条转发策略到本地主机 iptables 的 FORWARD 链上。策略为通过(`ACCEPT`)还是禁止(`DROP`)取决于配置`--icc=true`(缺省值)还是 `--icc=false`。当然,如果手动指定 `--iptables=false` 则不会添加 `iptables` 规则。 -可见,默认情况下,不同容器之间是允许网络互通的。如果为了安全考虑,可以在 `/etc/default/docker` 文件中配置 `DOCKER_OPTS=--icc=false` 来禁止它。 +可见,默认情况下,不同容器之间是允许网络互通的。如果为了安全考虑,可以在 `/etc/docker/daemon.json` 文件中配置 `{"icc": false}` 来禁止它。 -#### 访问指定端口 +### 访问指定端口 在通过 `-icc=false` 关闭网络访问后,还可以通过 `--link=CONTAINER_NAME:ALIAS` 选项来访问容器的开放端口。 例如,在启动 Docker 服务时,可以同时使用 `icc=false --iptables=true` 参数来关闭允许相互的网络访问,并让 Docker 可以修改系统中的 `iptables` 规则。 此时,系统中的 `iptables` 规则可能是类似 -``` +```bash $ sudo iptables -nL ... Chain FORWARD (policy ACCEPT) @@ -39,10 +39,10 @@ DROP all -- 0.0.0.0/0 0.0.0.0/0 ... ``` -之后,启动容器(`docker run`)时使用 `--link=CONTAINER_NAME:ALIAS` 选项。Docker 会在 `iptable` 中为 两个容器分别添加一条 `ACCEPT` 规则,允许相互访问开放的端口(取决于 Dockerfile 中的 EXPOSE 行)。 +之后,启动容器(`docker run`)时使用 `--link=CONTAINER_NAME:ALIAS` 选项。Docker 会在 `iptable` 中为 两个容器分别添加一条 `ACCEPT` 规则,允许相互访问开放的端口(取决于 `Dockerfile` 中的 `EXPOSE` 指令)。 当添加了 `--link=CONTAINER_NAME:ALIAS` 选项后,添加了 `iptables` 规则。 -``` +```bash $ sudo iptables -nL ... Chain FORWARD (policy ACCEPT) diff --git a/advanced_network/bridge.md b/advanced_network/bridge.md index 40d1f019d..0ce6a5298 100644 --- a/advanced_network/bridge.md +++ b/advanced_network/bridge.md @@ -1,34 +1,45 @@ -## 自定义网桥 +# 自定义网桥 + 除了默认的 `docker0` 网桥,用户也可以指定网桥来连接各个容器。 在启动 Docker 服务的时候,使用 `-b BRIDGE`或`--bridge=BRIDGE` 来指定使用的网桥。 如果服务已经运行,那需要先停止服务,并删除旧的网桥。 -``` -$ sudo service docker stop + +```bash +$ sudo systemctl stop docker $ sudo ip link set dev docker0 down $ sudo brctl delbr docker0 ``` + 然后创建一个网桥 `bridge0`。 -``` + +```bash $ sudo brctl addbr bridge0 $ sudo ip addr add 192.168.5.1/24 dev bridge0 $ sudo ip link set dev bridge0 up ``` + 查看确认网桥创建并启动。 -``` + +```bash $ ip addr show bridge0 4: bridge0: mtu 1500 qdisc noop state UP group default link/ether 66:38:d0:0d:76:18 brd ff:ff:ff:ff:ff:ff inet 192.168.5.1/24 scope global bridge0 valid_lft forever preferred_lft forever ``` -配置 Docker 服务,默认桥接到创建的网桥上。 -``` -$ echo 'DOCKER_OPTS="-b=bridge0"' >> /etc/default/docker -$ sudo service docker start + +在 Docker 配置文件 `/etc/docker/daemon.json` 中添加如下内容,即可将 Docker 默认桥接到创建的网桥上。 + +```json +{ + "bridge": "bridge0", +} ``` + 启动 Docker 服务。 + 新建一个容器,可以看到它已经桥接到了 `bridge0` 上。 可以继续用 `brctl show` 命令查看桥接的信息。另外,在容器中可以使用 `ip addr` 和 `ip route` 命令来查看 IP 地址配置和路由信息。 diff --git a/advanced_network/config_file.md b/advanced_network/config_file.md index 0cd476c57..b084c79ad 100644 --- a/advanced_network/config_file.md +++ b/advanced_network/config_file.md @@ -1,5 +1,5 @@ -## 编辑网络配置文件 +# 编辑网络配置文件 -Docker 1.2.0 开始支持在运行中的容器里编辑 `/etc/hosts`, `/etc/hostname` 和 `/etc/resolve.conf` 文件。 +Docker 1.2.0 开始支持在运行中的容器里编辑 `/etc/hosts`, `/etc/hostname` 和 `/etc/resolv.conf` 文件。 -但是这些修改是临时的,只在运行的容器中保留,容器终止或重启后并不会被保存下来。也不会被 `docker commit` 提交。 +但是这些修改是临时的,只在运行的容器中保留,容器终止或重启后并不会被保存下来,也不会被 `docker commit` 提交。 diff --git a/advanced_network/dns.md b/advanced_network/dns.md deleted file mode 100644 index 9d32700cf..000000000 --- a/advanced_network/dns.md +++ /dev/null @@ -1,29 +0,0 @@ -## 配置 DNS -Docker 没有为每个容器专门定制镜像,那么怎么自定义配置容器的主机名和 DNS 配置呢? -秘诀就是它利用虚拟文件来挂载到来容器的 3 个相关配置文件。 - -在容器中使用 mount 命令可以看到挂载信息: -``` -$ mount -... -/dev/disk/by-uuid/1fec...ebdf on /etc/hostname type ext4 ... -/dev/disk/by-uuid/1fec...ebdf on /etc/hosts type ext4 ... -tmpfs on /etc/resolv.conf type tmpfs ... -... -``` -这种机制可以让宿主主机 DNS 信息发生更新后,所有 Docker 容器的 dns 配置通过 `/etc/resolv.conf` 文件立刻得到更新。 - -如果用户想要手动指定容器的配置,可以利用下面的选项。 - -`-h HOSTNAME or --hostname=HOSTNAME` -设定容器的主机名,它会被写到容器内的 `/etc/hostname` 和 `/etc/hosts`。但它在容器外部看不到,既不会在 `docker ps` 中显示,也不会在其他的容器的 `/etc/hosts` 看到。 - -`--link=CONTAINER_NAME:ALIAS` -选项会在创建容器的时候,添加一个其他容器的主机名到 `/etc/hosts` 文件中,让新容器的进程可以使用主机名 ALIAS 就可以连接它。 - -`--dns=IP_ADDRESS` -添加 DNS 服务器到容器的 `/etc/resolv.conf` 中,让容器用这个服务器来解析所有不在 `/etc/hosts` 中的主机名。 - -`--dns-search=DOMAIN` -设定容器的搜索域,当设定搜索域为 `.example.com` 时,在搜索一个名为 host 的主机时,DNS 不仅搜索host,还会搜索 `host.example.com`。 -注意:如果没有上述最后 2 个选项,Docker 会默认用主机上的 `/etc/resolv.conf` 来配置容器。 diff --git a/advanced_network/docker0.md b/advanced_network/docker0.md index 9e56d3e40..c21ce8b70 100644 --- a/advanced_network/docker0.md +++ b/advanced_network/docker0.md @@ -1,13 +1,17 @@ -## 配置 docker0 网桥 +# 配置 docker0 网桥 + Docker 服务默认会创建一个 `docker0` 网桥(其上有一个 `docker0` 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。 Docker 默认指定了 `docker0` 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。 -* `--bip=CIDR` -- IP 地址加掩码格式,例如 192.168.1.5/24 -* `--mtu=BYTES` -- 覆盖默认的 Docker mtu 配置 + +* `--bip=CIDR` IP 地址加掩码格式,例如 192.168.1.5/24 +* `--mtu=BYTES` 覆盖默认的 Docker mtu 配置 也可以在配置文件中配置 DOCKER_OPTS,然后重启服务。 + 由于目前 Docker 网桥是 Linux 网桥,用户可以使用 `brctl show` 来查看网桥和端口连接信息。 -``` + +```bash $ sudo brctl show bridge name bridge id STP enabled interfaces docker0 8000.3a1d7362b4ee no veth65f9 @@ -17,7 +21,8 @@ docker0 8000.3a1d7362b4ee no veth65f9 每次创建一个新容器的时候,Docker 从可用的地址段中选择一个空闲的 IP 地址分配给容器的 eth0 端口。使用本地主机上 `docker0` 接口的 IP 作为所有容器的默认网关。 -``` + +```bash $ sudo docker run -i -t --rm base /bin/bash $ ip addr show eth0 24: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 @@ -29,5 +34,4 @@ $ ip addr show eth0 $ ip route default via 172.17.42.1 dev eth0 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.3 -$ exit ``` diff --git a/advanced_network/example.md b/advanced_network/example.md index 2bad70204..f7ca843b1 100644 --- a/advanced_network/example.md +++ b/advanced_network/example.md @@ -1,8 +1,8 @@ -## 工具和示例 +# 工具和示例 在介绍自定义网络拓扑之前,你可能会对一些外部工具和例子感兴趣: -### pipework +## pipework Jérôme Petazzoni 编写了一个叫 [pipework](https://github.com/jpetazzo/pipework) 的 shell 脚本,可以帮助用户在比较复杂的场景中完成容器的连接。 -### playground -Brandon Rhodes 创建了一个提供完整的 Docker 容器网络拓扑管理的 [Python库](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墙;以及一些提供 HTTP, SMTP, POP, IMAP, Telnet, SSH, FTP 的服务器。 +## playground +Brandon Rhodes 创建了一个提供完整的 Docker 容器网络拓扑管理的 [Python库](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墙;以及一些提供 `HTTP` `SMTP` `POP` `IMAP` `Telnet` `SSH` `FTP` 的服务器。 diff --git a/advanced_network/port_mapping.md b/advanced_network/port_mapping.md index c683456c8..dc6f92d30 100644 --- a/advanced_network/port_mapping.md +++ b/advanced_network/port_mapping.md @@ -1,11 +1,14 @@ -## 映射容器端口到宿主主机的实现 +# 映射容器端口到宿主主机的实现 默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。 -### 容器访问外部实现 -容器所有到外部网络的连接,源地址都会被NAT成本地系统的IP地址。这是使用 `iptables` 的源地址伪装操作实现的。 + +## 容器访问外部实现 + +容器所有到外部网络的连接,源地址都会被 NAT 成本地系统的 IP 地址。这是使用 `iptables` 的源地址伪装操作实现的。 查看主机的 NAT 规则。 -``` + +```bash $ sudo iptables -t nat -nL ... Chain POSTROUTING (policy ACCEPT) @@ -13,16 +16,18 @@ target prot opt source destination MASQUERADE all -- 172.17.0.0/16 !172.17.0.0/16 ... ``` + 其中,上述规则将所有源地址在 `172.17.0.0/16` 网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE 跟传统 SNAT 的好处是它能动态从网卡获取地址。 -### 外部访问容器实现 +## 外部访问容器实现 容器允许外部访问,可以在 `docker run` 时候通过 `-p` 或 `-P` 参数来启用。 不管用那种办法,其实也是在本地的 `iptable` 的 nat 表中添加相应的规则。 使用 `-P` 时: -``` + +```bash $ iptables -t nat -nL ... Chain DOCKER (2 references) @@ -31,13 +36,22 @@ DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49153 to:1 ``` 使用 `-p 80:80` 时: -``` + +```bash $ iptables -t nat -nL Chain DOCKER (2 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80 ``` + 注意: -* 这里的规则映射了 0.0.0.0,意味着将接受主机来自所有接口的流量。用户可以通过 `-p IP:host_port:container_port` 或 `-p -IP::port` 来指定允许访问容器的主机上的 IP、接口等,以制定更严格的规则。 -* 如果希望永久绑定到某个固定的 IP 地址,可以在 Docker 配置文件 `/etc/default/docker` 中指定 `DOCKER_OPTS="--ip=IP_ADDRESS"`,之后重启 Docker 服务即可生效。 + +* 这里的规则映射了 `0.0.0.0`,意味着将接受主机来自所有接口的流量。用户可以通过 `-p IP:host_port:container_port` 或 `-p IP::port` 来指定允许访问容器的主机上的 IP、接口等,以制定更严格的规则。 + +* 如果希望永久绑定到某个固定的 IP 地址,可以在 Docker 配置文件 `/etc/docker/daemon.json` 中添加如下内容。 + +```json +{ + "ip": "0.0.0.0" +} +``` diff --git a/advanced_network/ptp.md b/advanced_network/ptp.md index cf66adc4c..738a75171 100644 --- a/advanced_network/ptp.md +++ b/advanced_network/ptp.md @@ -1,4 +1,4 @@ -## 示例:创建一个点到点连接 +# 示例:创建一个点到点连接 默认情况下,Docker 会将所有容器连接到由 `docker0` 提供的虚拟子网中。 用户有时候需要两个容器之间可以直连通信,而不用通过主机网桥进行桥接。 @@ -6,18 +6,18 @@ 解决办法很简单:创建一对 `peer` 接口,分别放到两个容器中,配置成点到点链路类型即可。 首先启动 2 个容器: -``` -$ sudo docker run -i -t --rm --net=none base /bin/bash +```bash +$ docker run -i -t --rm --net=none base /bin/bash root@1f1f4c1f931a:/# -$ sudo docker run -i -t --rm --net=none base /bin/bash +$ docker run -i -t --rm --net=none base /bin/bash root@12e343489d2f:/# ``` 找到进程号,然后创建网络命名空间的跟踪文件。 -``` -$ sudo docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a +```bash +$ docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a 2989 -$ sudo docker inspect -f '{{.State.Pid}}' 12e343489d2f +$ docker inspect -f '{{.State.Pid}}' 12e343489d2f 3004 $ sudo mkdir -p /var/run/netns $ sudo ln -s /proc/2989/ns/net /var/run/netns/2989 @@ -25,7 +25,7 @@ $ sudo ln -s /proc/3004/ns/net /var/run/netns/3004 ``` 创建一对 `peer` 接口,然后配置路由 -``` +```bash $ sudo ip link add A type veth peer name B $ sudo ip link set A netns 2989 diff --git a/advanced_network/quick_guide.md b/advanced_network/quick_guide.md index c7db03089..455a81814 100644 --- a/advanced_network/quick_guide.md +++ b/advanced_network/quick_guide.md @@ -1,23 +1,26 @@ -## 快速配置指南 +# 快速配置指南 下面是一个跟 Docker 网络相关的命令列表。 其中有些命令选项只有在 Docker 服务启动的时候才能配置,而且不能马上生效。 -* `-b BRIDGE or --bridge=BRIDGE` --指定容器挂载的网桥 -* `--bip=CIDR` --定制 docker0 的掩码 -* `-H SOCKET... or --host=SOCKET...` --Docker 服务端接收命令的通道 -* `--icc=true|false` --是否支持容器之间进行通信 -* `--ip-forward=true|false` --请看下文容器之间的通信 -* `--iptables=true|false` --是否允许 Docker 添加 iptables 规则 -* `--mtu=BYTES` --容器网络中的 MTU -下面2个命令选项既可以在启动服务时指定,也可以 Docker 容器启动(`docker run`)时候指定。在 Docker 服务启动的时候指定则会成为默认值,后面执行 `docker run` 时可以覆盖设置的默认值。 -* `--dns=IP_ADDRESS...` --使用指定的DNS服务器 -* `--dns-search=DOMAIN...` --指定DNS搜索域 +* `-b BRIDGE` 或 `--bridge=BRIDGE` 指定容器挂载的网桥 +* `--bip=CIDR` 定制 docker0 的掩码 +* `-H SOCKET...` 或 `--host=SOCKET...` Docker 服务端接收命令的通道 +* `--icc=true|false` 是否支持容器之间进行通信 +* `--ip-forward=true|false` 请看下文容器之间的通信 +* `--iptables=true|false` 是否允许 Docker 添加 iptables 规则 +* `--mtu=BYTES` 容器网络中的 MTU + +下面2个命令选项既可以在启动服务时指定,也可以在启动容器时指定。在 Docker 服务启动的时候指定则会成为默认值,后面执行 `docker run` 时可以覆盖设置的默认值。 + +* `--dns=IP_ADDRESS...` 使用指定的DNS服务器 +* `--dns-search=DOMAIN...` 指定DNS搜索域 最后这些选项只有在 `docker run` 执行时使用,因为它是针对容器的特性内容。 -* `-h HOSTNAME or --hostname=HOSTNAME` --配置容器主机名 -* `--link=CONTAINER_NAME:ALIAS` --添加到另一个容器的连接 -* `--net=bridge|none|container:NAME_or_ID|host` --配置容器的桥接模式 -* `-p SPEC or --publish=SPEC` --映射容器端口到宿主主机 -* `-P or --publish-all=true|false` --映射容器所有端口到宿主主机 + +* `-h HOSTNAME` 或 `--hostname=HOSTNAME` 配置容器主机名 +* `--link=CONTAINER_NAME:ALIAS` 添加到另一个容器的连接 +* `--net=bridge|none|container:NAME_or_ID|host` 配置容器的桥接模式 +* `-p SPEC` 或 `--publish=SPEC` 映射容器端口到宿主主机 +* `-P or --publish-all=true|false` 映射容器所有端口到宿主主机 diff --git a/appendix/best_practices.md b/appendix/best_practices.md new file mode 100644 index 000000000..e93f8e2ec --- /dev/null +++ b/appendix/best_practices.md @@ -0,0 +1,344 @@ +# Dockerfile 最佳实践 + +本附录是笔者对 Docker 官方文档中 [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) 的理解与翻译。 + +## 一般性的指南和建议 + +### 容器应该是短暂的 + +通过 `Dockerfile` 构建的镜像所启动的容器应该尽可能短暂(生命周期短)。「短暂」意味着可以停止和销毁容器,并且创建一个新容器并部署好所需的设置和配置工作量应该是极小的。 + +### 使用 `.dockerignore` 文件 + +使用 `Dockerfile` 构建镜像时最好是将 `Dockerfile` 放置在一个新建的空目录下。然后将构建镜像所需要的文件添加到该目录中。为了提高构建镜像的效率,你可以在目录下新建一个 `.dockerignore` 文件来指定要忽略的文件和目录。`.dockerignore` 文件的排除模式语法和 Git 的 `.gitignore` 文件相似。 + +### 使用多阶段构建 + +在 `Docker 17.05` 以上版本中,你可以使用 [多阶段构建](../image/multistage-builds.md) 来减少所构建镜像的大小。 + +### 避免安装不必要的包 + +为了降低复杂性、减少依赖、减小文件大小、节约构建时间,你应该避免安装任何不必要的包。例如,不要在数据库镜像中包含一个文本编辑器。 + +### 一个容器只运行一个进程 + +应该保证在一个容器中只运行一个进程。将多个应用解耦到不同容器中,保证了容器的横向扩展和复用。例如 web 应用应该包含三个容器:web应用、数据库、缓存。 + +如果容器互相依赖,你可以使用 [Docker 自定义网络](../network/linking.md) 来把这些容器连接起来。 + +### 镜像层数尽可能少 + +你需要在 `Dockerfile` 可读性(也包括长期的可维护性)和减少层数之间做一个平衡。 + +### 将多行参数排序 + +将多行参数按字母顺序排序(比如要安装多个包时)。这可以帮助你避免重复包含同一个包,更新包列表时也更容易。也便于 `PRs` 阅读和审查。建议在反斜杠符号 `\` 之前添加一个空格,以增加可读性。 + +下面是来自 `buildpack-deps` 镜像的例子: + +```docker +RUN apt-get update && apt-get install -y \ + bzr \ + cvs \ + git \ + mercurial \ + subversion +``` + +### 构建缓存 + +在镜像的构建过程中,Docker 会遍历 `Dockerfile` 文件中的指令,然后按顺序执行。在执行每条指令之前,Docker 都会在缓存中查找是否已经存在可重用的镜像,如果有就使用现存的镜像,不再重复创建。如果你不想在构建过程中使用缓存,你可以在 `docker build` 命令中使用 `--no-cache=true` 选项。 + +但是,如果你想在构建的过程中使用缓存,你得明白什么时候会,什么时候不会找到匹配的镜像,遵循的基本规则如下: + +* 从一个基础镜像开始(`FROM` 指令指定),下一条指令将和该基础镜像的所有子镜像进行匹配,检查这些子镜像被创建时使用的指令是否和被检查的指令完全一样。如果不是,则缓存失效。 +* 在大多数情况下,只需要简单地对比 `Dockerfile` 中的指令和子镜像。然而,有些指令需要更多的检查和解释。 +* 对于 `ADD` 和 `COPY` 指令,镜像中对应文件的内容也会被检查,每个文件都会计算出一个校验和。文件的最后修改时间和最后访问时间不会纳入校验。在缓存的查找过程中,会将这些校验和和已存在镜像中的文件校验和进行对比。如果文件有任何改变,比如内容和元数据,则缓存失效。 +* 除了 `ADD` 和 `COPY` 指令,缓存匹配过程不会查看临时容器中的文件来决定缓存是否匹配。例如,当执行完 `RUN apt-get -y update` 指令后,容器中一些文件被更新,但 Docker 不会检查这些文件。这种情况下,只有指令字符串本身被用来匹配缓存。 + +一旦缓存失效,所有后续的 `Dockerfile` 指令都将产生新的镜像,缓存不会被使用。 + +## Dockerfile 指令 + +下面针对 `Dockerfile` 中各种指令的最佳编写方式给出建议。 + +### FROM + +尽可能使用当前官方仓库作为你构建镜像的基础。推荐使用 [Alpine](https://hub.docker.com/_/alpine/) 镜像,因为它被严格控制并保持最小尺寸(目前小于 5 MB),但它仍然是一个完整的发行版。 + +### LABEL + +你可以给镜像添加标签来帮助组织镜像、记录许可信息、辅助自动化构建等。每个标签一行,由 `LABEL` 开头加上一个或多个标签对。下面的示例展示了各种不同的可能格式。`#` 开头的行是注释内容。 + +>注意:如果你的字符串中包含空格,必须将字符串放入引号中或者对空格使用转义。如果字符串内容本身就包含引号,必须对引号使用转义。 + +```docker +# Set one or more individual labels +LABEL com.example.version="0.0.1-beta" + +LABEL vendor="ACME Incorporated" + +LABEL com.example.release-date="2015-02-12" + +LABEL com.example.version.is-production="" +``` + +一个镜像可以包含多个标签,但建议将多个标签放入到一个 `LABEL` 指令中。 + +```docker +# Set multiple labels at once, using line-continuation characters to break long lines +LABEL vendor=ACME\ Incorporated \ + com.example.is-beta= \ + com.example.is-production="" \ + com.example.version="0.0.1-beta" \ + com.example.release-date="2015-02-12" +``` + +关于标签可以接受的键值对,参考 [Understanding object labels](https://docs.docker.com/config/labels-custom-metadata/)。关于查询标签信息,参考 [Managing labels on objects](https://docs.docker.com/config/labels-custom-metadata/)。 + +### RUN + +为了保持 `Dockerfile` 文件的可读性,可理解性,以及可维护性,建议将长的或复杂的 `RUN` 指令用反斜杠 `\` 分割成多行。 + +#### apt-get + +`RUN` 指令最常见的用法是安装包用的 `apt-get`。因为 `RUN apt-get` 指令会安装包,所以有几个问题需要注意。 + +不要使用 `RUN apt-get upgrade` 或 `dist-upgrade`,因为许多基础镜像中的「必须」包不会在一个非特权容器中升级。如果基础镜像中的某个包过时了,你应该联系它的维护者。如果你确定某个特定的包,比如 `foo`,需要升级,使用 `apt-get install -y foo` 就行,该指令会自动升级 `foo` 包。 + +永远将 `RUN apt-get update` 和 `apt-get install` 组合成一条 `RUN` 声明,例如: + +```docker +RUN apt-get update && apt-get install -y \ + package-bar \ + package-baz \ + package-foo +``` + +将 `apt-get update` 放在一条单独的 `RUN` 声明中会导致缓存问题以及后续的 `apt-get install` 失败。比如,假设你有一个 `Dockerfile` 文件: + +```docker +FROM ubuntu:18.04 + +RUN apt-get update + +RUN apt-get install -y curl +``` + +构建镜像后,所有的层都在 Docker 的缓存中。假设你后来又修改了其中的 `apt-get install` 添加了一个包: + +```docker +FROM ubuntu:18.04 + +RUN apt-get update + +RUN apt-get install -y curl nginx +``` + +Docker 发现修改后的 `RUN apt-get update` 指令和之前的完全一样。所以,`apt-get update` 不会执行,而是使用之前的缓存镜像。因为 `apt-get update` 没有运行,后面的 `apt-get install` 可能安装的是过时的 `curl` 和 `nginx` 版本。 + +使用 `RUN apt-get update && apt-get install -y` 可以确保你的 Dockerfiles 每次安装的都是包的最新的版本,而且这个过程不需要进一步的编码或额外干预。这项技术叫作 `cache busting`。你也可以显示指定一个包的版本号来达到 `cache-busting`,这就是所谓的固定版本,例如: + +```docker +RUN apt-get update && apt-get install -y \ + package-bar \ + package-baz \ + package-foo=1.3.* +``` + +固定版本会迫使构建过程检索特定的版本,而不管缓存中有什么。这项技术也可以减少因所需包中未预料到的变化而导致的失败。 + +下面是一个 `RUN` 指令的示例模板,展示了所有关于 `apt-get` 的建议。 + +```docker +RUN apt-get update && apt-get install -y \ + aufs-tools \ + automake \ + build-essential \ + curl \ + dpkg-sig \ + libcap-dev \ + libsqlite3-dev \ + mercurial \ + reprepro \ + ruby1.9.1 \ + ruby1.9.1-dev \ + s3cmd=1.1.* \ + && rm -rf /var/lib/apt/lists/* +``` + +其中 `s3cmd` 指令指定了一个版本号 `1.1.*`。如果之前的镜像使用的是更旧的版本,指定新的版本会导致 `apt-get udpate` 缓存失效并确保安装的是新版本。 + +另外,清理掉 apt 缓存 `var/lib/apt/lists` 可以减小镜像大小。因为 `RUN` 指令的开头为 `apt-get udpate`,包缓存总是会在 `apt-get install` 之前刷新。 + +> 注意:官方的 Debian 和 Ubuntu 镜像会自动运行 apt-get clean,所以不需要显式的调用 apt-get clean。 + +### CMD + +`CMD` 指令用于执行目标镜像中包含的软件,可以包含参数。`CMD` 大多数情况下都应该以 `CMD ["executable", "param1", "param2"...]` 的形式使用。因此,如果创建镜像的目的是为了部署某个服务(比如 `Apache`),你可能会执行类似于 `CMD ["apache2", "-DFOREGROUND"]` 形式的命令。我们建议任何服务镜像都使用这种形式的命令。 + +多数情况下,`CMD` 都需要一个交互式的 `shell` (bash, Python, perl 等),例如 `CMD ["perl", "-de0"]`,或者 `CMD ["PHP", "-a"]`。使用这种形式意味着,当你执行类似 `docker run -it python` 时,你会进入一个准备好的 `shell` 中。`CMD` 应该在极少的情况下才能以 `CMD ["param", "param"]` 的形式与 `ENTRYPOINT` 协同使用,除非你和你的镜像使用者都对 `ENTRYPOINT` 的工作方式十分熟悉。 + +### EXPOSE + +`EXPOSE` 指令用于指定容器将要监听的端口。因此,你应该为你的应用程序使用常见的端口。例如,提供 `Apache` web 服务的镜像应该使用 `EXPOSE 80`,而提供 `MongoDB` 服务的镜像使用 `EXPOSE 27017`。 + +对于外部访问,用户可以在执行 `docker run` 时使用一个标志来指示如何将指定的端口映射到所选择的端口。 + +### ENV + +为了方便新程序运行,你可以使用 `ENV` 来为容器中安装的程序更新 `PATH` 环境变量。例如使用 `ENV PATH /usr/local/nginx/bin:$PATH` 来确保 `CMD ["nginx"]` 能正确运行。 + +`ENV` 指令也可用于为你想要容器化的服务提供必要的环境变量,比如 Postgres 需要的 `PGDATA`。 + +最后,`ENV` 也能用于设置常见的版本号,比如下面的示例: + +```docker +ENV PG_MAJOR 9.3 + +ENV PG_VERSION 9.3.4 + +RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && … + +ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH +``` + +类似于程序中的常量,这种方法可以让你只需改变 `ENV` 指令来自动的改变容器中的软件版本。 + +### ADD 和 COPY + +虽然 `ADD` 和 `COPY` 功能类似,但一般优先使用 `COPY`。因为它比 `ADD` 更透明。`COPY` 只支持简单将本地文件拷贝到容器中,而 `ADD` 有一些并不明显的功能(比如本地 tar 提取和远程 URL 支持)。因此,`ADD` 的最佳用例是将本地 tar 文件自动提取到镜像中,例如 `ADD rootfs.tar.xz`。 + +如果你的 `Dockerfile` 有多个步骤需要使用上下文中不同的文件。单独 `COPY` 每个文件,而不是一次性的 `COPY` 所有文件,这将保证每个步骤的构建缓存只在特定的文件变化时失效。例如: + +```docker +COPY requirements.txt /tmp/ + +RUN pip install --requirement /tmp/requirements.txt + +COPY . /tmp/ +``` + +如果将 `COPY . /tmp/` 放置在 `RUN` 指令之前,只要 `.` 目录中任何一个文件变化,都会导致后续指令的缓存失效。 + +为了让镜像尽量小,最好不要使用 `ADD` 指令从远程 URL 获取包,而是使用 `curl` 和 `wget`。这样你可以在文件提取完之后删掉不再需要的文件来避免在镜像中额外添加一层。比如尽量避免下面的用法: + +```docker +ADD http://example.com/big.tar.xz /usr/src/things/ + +RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things + +RUN make -C /usr/src/things all +``` + +而是应该使用下面这种方法: + +```docker +RUN mkdir -p /usr/src/things \ + && curl -SL http://example.com/big.tar.xz \ + | tar -xJC /usr/src/things \ + && make -C /usr/src/things all +``` + +上面使用的管道操作,所以没有中间文件需要删除。 + +对于其他不需要 `ADD` 的自动提取功能的文件或目录,你应该使用 `COPY`。 + +### ENTRYPOINT + +`ENTRYPOINT` 的最佳用处是设置镜像的主命令,允许将镜像当成命令本身来运行(用 `CMD` 提供默认选项)。 + +例如,下面的示例镜像提供了命令行工具 `s3cmd`: + +```docker +ENTRYPOINT ["s3cmd"] + +CMD ["--help"] +``` + +现在直接运行该镜像创建的容器会显示命令帮助: + +```bash +$ docker run s3cmd +``` + +或者提供正确的参数来执行某个命令: + +```bash +$ docker run s3cmd ls s3://mybucket +``` + +这样镜像名可以当成命令行的参考。 + +`ENTRYPOINT` 指令也可以结合一个辅助脚本使用,和前面命令行风格类似,即使启动工具需要不止一个步骤。 + +例如,`Postgres` 官方镜像使用下面的脚本作为 `ENTRYPOINT`: + +```bash +#!/bin/bash +set -e + +if [ "$1" = 'postgres' ]; then + chown -R postgres "$PGDATA" + + if [ -z "$(ls -A "$PGDATA")" ]; then + gosu postgres initdb + fi + + exec gosu postgres "$@" +fi + +exec "$@" +``` + +>注意:该脚本使用了 Bash 的内置命令 exec,所以最后运行的进程就是容器的 PID 为 1 的进程。这样,进程就可以接收到任何发送给容器的 Unix 信号了。 + +该辅助脚本被拷贝到容器,并在容器启动时通过 `ENTRYPOINT` 执行: + +```docker +COPY ./docker-entrypoint.sh / + +ENTRYPOINT ["/docker-entrypoint.sh"] +``` + +该脚本可以让用户用几种不同的方式和 `Postgres` 交互。 + +你可以很简单地启动 `Postgres`: + +```bash +$ docker run postgres +``` + +也可以执行 `Postgres` 并传递参数: + +```bash +$ docker run postgres postgres --help +``` + +最后,你还可以启动另外一个完全不同的工具,比如 `Bash`: + +```bash +$ docker run --rm -it postgres bash +``` + +### VOLUME + +`VOLUME` 指令用于暴露任何数据库存储文件,配置文件,或容器创建的文件和目录。强烈建议使用 `VOLUME` 来管理镜像中的可变部分和用户可以改变的部分。 + +### USER + +如果某个服务不需要特权执行,建议使用 `USER` 指令切换到非 root 用户。先在 `Dockerfile` 中使用类似 `RUN groupadd -r postgres && useradd -r -g postgres postgres` 的指令创建用户和用户组。 + +>注意:在镜像中,用户和用户组每次被分配的 UID/GID 都是不确定的,下次重新构建镜像时被分配到的 UID/GID 可能会不一样。如果要依赖确定的 UID/GID,你应该显示的指定一个 UID/GID。 + +你应该避免使用 `sudo`,因为它不可预期的 TTY 和信号转发行为可能造成的问题比它能解决的问题还多。如果你真的需要和 `sudo` 类似的功能(例如,以 root 权限初始化某个守护进程,以非 root 权限执行它),你可以使用 [gosu](https://github.com/tianon/gosu)。 + +最后,为了减少层数和复杂度,避免频繁地使用 `USER` 来回切换用户。 + +### WORKDIR + +为了清晰性和可靠性,你应该总是在 `WORKDIR` 中使用绝对路径。另外,你应该使用 `WORKDIR` 来替代类似于 `RUN cd ... && do-something` 的指令,后者难以阅读、排错和维护。 + +## 官方镜像示例 + +这些官方镜像的 Dockerfile 都是参考典范:https://github.com/docker-library/docs diff --git a/appendix/command/README.md b/appendix/command/README.md index 092340644..5bea7319c 100644 --- a/appendix/command/README.md +++ b/appendix/command/README.md @@ -1,126 +1,13 @@ # Docker 命令查询 ## 基本语法 -Docker 命令有两大类,客户端命令和服务端命令。前者是主要的操作接口,后者用来启动 Docker daemon。 -* 客户端命令:基本命令格式为 `docker [OPTIONS] COMMAND [arg...]`; -* 服务端命令:基本命令格式为 `docker daemon [OPTIONS]`。 - -可以通过 `man docker` 或 `docker help` 来查看这些命令。 - -## 客户端命令选项 +Docker 命令有两大类,客户端命令和服务端命令。前者是主要的操作接口,后者用来启动 Docker Daemon。 -* --config="":指定客户端配置文件,默认为 `/.docker`; -* -D=true|false:是否使用 debug 模式。默认不开启; -* -H, --host=[]:指定命令对应 Docker daemon 的监听接口,可以为 unix 套接字(unix:///path/to/socket),文件句柄(fd://socketfd)或 tcp 套接字(tcp://[host[:port]]),默认为 unix:///var/run/docker.sock; -* -l, --log-level="debug|info|warn|error|fatal":指定日志输出级别; -* --tls=true|false:是否对 Docker daemon 启用 TLS 安全机制,默认为否; -* --tlscacert= /.docker/ca.pem:TLS CA 签名的可信证书文件路径; -* --tlscert= /.docker/cert.pem:TLS 可信证书文件路径; -* --tlscert= /.docker/key.pem:TLS 密钥文件路径; -* --tlsverify=true|false:启用 TLS 校验,默认为否。 - -## daemon 命令选项 -* --api-cors-header="":CORS 头部域,默认不允许 CORS,要允许任意的跨域访问,可以指定为 “*”; -* --authorization-plugin="":载入认证的插件; -* -b="":将容器挂载到一个已存在的网桥上。指定为 'none' 时则禁用容器的网络,与 --bip 选项互斥; -* --bip="":让动态创建的 docker0 网桥采用给定的 CIDR 地址; 与 -b 选项互斥; -* --cgroup-parent="":指定 cgroup 的父组,默认 fs cgroup 驱动为 `/docker`,systemd cgroup 驱动为 `system.slice`; -* --cluster-store="":构成集群(如 Swarm)时,集群键值数据库服务地址; -* --cluster-advertise="":构成集群时,自身的被访问地址,可以为 `host:port` 或 `interface:port`; -* --cluster-store-opt="":构成集群时,键值数据库的配置选项; -* --config-file="/etc/docker/daemon.json":daemon 配置文件路径; -* --containerd="":containerd 文件的路径; -* -D, --debug=true|false:是否使用 Debug 模式。缺省为 false; -* --default-gateway="":容器的 IPv4 网关地址,必须在网桥的子网段内; -* --default-gateway-v6="":容器的 IPv6 网关地址; -* --default-ulimit=[]:默认的 ulimit 值; -* --disable-legacy-registry=true|false:是否允许访问旧版本的镜像仓库服务器; -* --dns="":指定容器使用的 DNS 服务器地址; -* --dns-opt="":DNS 选项; -* --dns-search=[]:DNS 搜索域; -* --exec-opt=[]:运行时的执行选项; -* --exec-root="":容器执行状态文件的根路径,默认为 `/var/run/docker`; -* --fixed-cidr="":限定分配 IPv4 地址范围; -* --fixed-cidr-v6="":限定分配 IPv6 地址范围; -* -G, --group="":分配给 unix 套接字的组,默认为 `docker`; -* -g, --graph="":Docker 运行时的根路径,默认为 `/var/lib/docker`; -* -H, --host=[]:指定命令对应 Docker daemon 的监听接口,可以为 unix 套接字(unix:///path/to/socket),文件句柄(fd://socketfd)或 tcp 套接字(tcp://[host[:port]]),默认为 unix:///var/run/docker.sock; -* --icc=true|false:是否启用容器间以及跟 daemon 所在主机的通信。默认为 true。 -* --insecure-registry=[]:允许访问给定的非安全仓库服务; -* --ip="":绑定容器端口时候的默认 IP 地址。缺省为 0.0.0.0; -* --ip-forward=true|false:是否检查启动在 Docker 主机上的启用 IP 转发服务,默认开启。注意关闭该选项将不对系统转发能力进行任何检查修改; -* --ip-masq=true|false:是否进行地址伪装,用于容器访问外部网络,默认开启; -* --iptables=true|false:是否允许 Docker 添加 iptables 规则。缺省为 true; -* --ipv6=true|false:是否启用 IPv6 支持,默认关闭; -* -l, --log-level="debug|info|warn|error|fatal":指定日志输出级别; -* --label="[]":添加指定的键值对标注; -* --log-driver="json-file|syslog|journald|gelf|fluentd|awslogs|splunk|etwlogs|gcplogs|none":指定日志后端驱动,默认为 json-file; -* --log-opt=[]:日志后端的选项; -* --mtu=VALUE:指定容器网络的 mtu; -* -p="":指定 daemon 的 PID 文件路径。缺省为 `/var/run/docker.pid`; -* --raw-logs:输出原始,未加色彩的日志信息; -* --registry-mirror=://:指定 `docker pull` 时使用的注册服务器镜像地址; -* -s, --storage-driver="":指定使用给定的存储后端; -* --selinux-enabled=true|false:是否启用 SELinux 支持。缺省值为 false。SELinux 目前尚不支持 overlay 存储驱动; -* --storage-opt=[]:驱动后端选项; -* --tls=true|false:是否对 Docker daemon 启用 TLS 安全机制,默认为否; -* --tlscacert= /.docker/ca.pem:TLS CA 签名的可信证书文件路径; -* --tlscert= /.docker/cert.pem:TLS 可信证书文件路径; -* --tlscert= /.docker/key.pem:TLS 密钥文件路径; -* --tlsverify=true|false:启用 TLS 校验,默认为否; -* --userland-proxy=true|false:是否使用用户态代理来实现容器间和出容器的回环通信,默认为 true; -* --userns-remap=default|uid:gid|user:group|user|uid:指定容器的用户命名空间,默认是创建新的 UID 和 GID 映射到容器内进程。 - -## 客户端命令 +* 客户端命令:基本命令格式为 `docker [OPTIONS] COMMAND [arg...]`; -可以通过 `man docker-COMMAND` 或 `docker help COMMAND` 来查看这些命令的具体用法。 +* 服务端命令:基本命令格式为 `dockerd [OPTIONS]`。 -* attach:依附到一个正在运行的容器中; -* build:从一个 Dockerfile 创建一个镜像; -* commit:从一个容器的修改中创建一个新的镜像; -* cp:在容器和本地宿主系统之间复制文件中; -* create:创建一个新容器,但并不运行它; -* diff:检查一个容器内文件系统的修改,包括修改和增加; -* events:从服务端获取实时的事件; -* exec:在运行的容器内执行命令; -* export:导出容器内容为一个 tar 包; -* history:显示一个镜像的历史信息; -* images:列出存在的镜像; -* import:导入一个文件(典型为 tar 包)路径或目录来创建一个本地镜像; -* info:显示一些相关的系统信息; -* inspect:显示一个容器的具体配置信息; -* kill:关闭一个运行中的容器 (包括进程和所有相关资源); -* load:从一个 tar 包中加载一个镜像; -* login:注册或登录到一个 Docker 的仓库服务器; -* logout:从 Docker 的仓库服务器登出; -* logs:获取容器的 log 信息; -* network:管理 Docker 的网络,包括查看、创建、删除、挂载、卸载等; -* node:管理 swarm 集群中的节点,包括查看、更新、删除、提升/取消管理节点等; -* pause:暂停一个容器中的所有进程; -* port:查找一个 nat 到一个私有网口的公共口; -* ps:列出主机上的容器; -* pull:从一个Docker的仓库服务器下拉一个镜像或仓库; -* push:将一个镜像或者仓库推送到一个 Docker 的注册服务器; -* rename:重命名一个容器; -* restart:重启一个运行中的容器; -* rm:删除给定的若干个容器; -* rmi:删除给定的若干个镜像; -* run:创建一个新容器,并在其中运行给定命令; -* save:保存一个镜像为 tar 包文件; -* search:在 Docker index 中搜索一个镜像; -* service:管理 Docker 所启动的应用服务,包括创建、更新、删除等; -* start:启动一个容器; -* stats:输出(一个或多个)容器的资源使用统计信息; -* stop:终止一个运行中的容器; -* swarm:管理 Docker swarm 集群,包括创建、加入、退出、更新等; -* tag:为一个镜像打标签; -* top:查看一个容器中的正在运行的进程信息; -* unpause:将一个容器内所有的进程从暂停状态中恢复; -* update:更新指定的若干容器的配置信息; -* version:输出 Docker 的版本信息; -* volume:管理 Docker volume,包括查看、创建、删除等; -* wait:阻塞直到一个容器终止,然后输出它的退出符。 +可以通过 `man docker` 或 `docker help` 来查看这些命令。 -## 一张图总结 Docker 的命令 -![Docker 命令总结](../_images/cmd_logic.png) +接下来的小节对这两个命令进行介绍。 diff --git a/appendix/command/docker.md b/appendix/command/docker.md new file mode 100644 index 000000000..6c2463a63 --- /dev/null +++ b/appendix/command/docker.md @@ -0,0 +1,70 @@ +# 客户端命令(docker) + +## 客户端命令选项 + +* `--config=""`:指定客户端配置文件,默认为 `~/.docker`; +* `-D=true|false`:是否使用 debug 模式。默认不开启; +* `-H, --host=[]`:指定命令对应 Docker 守护进程的监听接口,可以为 unix 套接字 `unix:///path/to/socket`,文件句柄 `fd://socketfd` 或 tcp 套接字 `tcp://[host[:port]]`,默认为 `unix:///var/run/docker.sock`; +* `-l, --log-level="debug|info|warn|error|fatal"`:指定日志输出级别; +* `--tls=true|false`:是否对 Docker 守护进程启用 TLS 安全机制,默认为否; +* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径; +* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径; +* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径; +* `--tlsverify=true|false`:启用 TLS 校验,默认为否。 + +## 客户端命令 + +可以通过 `docker COMMAND --help` 来查看这些命令的具体用法。 + +* `attach`:依附到一个正在运行的容器中; +* `build`:从一个 Dockerfile 创建一个镜像; +* `commit`:从一个容器的修改中创建一个新的镜像; +* `cp`:在容器和本地宿主系统之间复制文件中; +* `create`:创建一个新容器,但并不运行它; +* `diff`:检查一个容器内文件系统的修改,包括修改和增加; +* `events`:从服务端获取实时的事件; +* `exec`:在运行的容器内执行命令; +* `export`:导出容器内容为一个 `tar` 包; +* `history`:显示一个镜像的历史信息; +* `images`:列出存在的镜像; +* `import`:导入一个文件(典型为 `tar` 包)路径或目录来创建一个本地镜像; +* `info`:显示一些相关的系统信息; +* `inspect`:显示一个容器的具体配置信息; +* `kill`:关闭一个运行中的容器 (包括进程和所有相关资源); +* `load`:从一个 tar 包中加载一个镜像; +* `login`:注册或登录到一个 Docker 的仓库服务器; +* `logout`:从 Docker 的仓库服务器登出; +* `logs`:获取容器的 log 信息; +* `network`:管理 Docker 的网络,包括查看、创建、删除、挂载、卸载等; +* `node`:管理 swarm 集群中的节点,包括查看、更新、删除、提升/取消管理节点等; +* `pause`:暂停一个容器中的所有进程; +* `port`:查找一个 nat 到一个私有网口的公共口; +* `ps`:列出主机上的容器; +* `pull`:从一个Docker的仓库服务器下拉一个镜像或仓库; +* `push`:将一个镜像或者仓库推送到一个 Docker 的注册服务器; +* `rename`:重命名一个容器; +* `restart`:重启一个运行中的容器; +* `rm`:删除给定的若干个容器; +* `rmi`:删除给定的若干个镜像; +* `run`:创建一个新容器,并在其中运行给定命令; +* `save`:保存一个镜像为 tar 包文件; +* `search`:在 Docker index 中搜索一个镜像; +* `service`:管理 Docker 所启动的应用服务,包括创建、更新、删除等; +* `start`:启动一个容器; +* `stats`:输出(一个或多个)容器的资源使用统计信息; +* `stop`:终止一个运行中的容器; +* `swarm`:管理 Docker swarm 集群,包括创建、加入、退出、更新等; +* `tag`:为一个镜像打标签; +* `top`:查看一个容器中的正在运行的进程信息; +* `unpause`:将一个容器内所有的进程从暂停状态中恢复; +* `update`:更新指定的若干容器的配置信息; +* `version`:输出 Docker 的版本信息; +* `volume`:管理 Docker volume,包括查看、创建、删除等; +* `wait`:阻塞直到一个容器终止,然后输出它的退出符。 + +## 一张图总结 Docker 的命令 +![Docker 命令总结](../_images/cmd_logic.png) + +## 参考 + +* [官方文档](https://docs.docker.com/engine/reference/commandline/cli/) diff --git a/appendix/command/dockerd.md b/appendix/command/dockerd.md new file mode 100644 index 000000000..7b30c7989 --- /dev/null +++ b/appendix/command/dockerd.md @@ -0,0 +1,58 @@ +# 服务端命令(dockerd) + +## dockerd 命令选项 + +* `--api-cors-header=""`:CORS 头部域,默认不允许 CORS,要允许任意的跨域访问,可以指定为 "*"; +* `--authorization-plugin=""`:载入认证的插件; +* `-b=""`:将容器挂载到一个已存在的网桥上。指定为 `none` 时则禁用容器的网络,与 `--bip` 选项互斥; +* `--bip=""`:让动态创建的 `docker0` 网桥采用给定的 CIDR 地址; 与 `-b` 选项互斥; +* `--cgroup-parent=""`:指定 cgroup 的父组,默认 fs cgroup 驱动为 `/docker`,systemd cgroup 驱动为 `system.slice`; +* `--cluster-store=""`:构成集群(如 `Swarm`)时,集群键值数据库服务地址; +* `--cluster-advertise=""`:构成集群时,自身的被访问地址,可以为 `host:port` 或 `interface:port`; +* `--cluster-store-opt=""`:构成集群时,键值数据库的配置选项; +* `--config-file="/etc/docker/daemon.json"`:daemon 配置文件路径; +* `--containerd=""`:containerd 文件的路径; +* `-D, --debug=true|false`:是否使用 Debug 模式。缺省为 false; +* `--default-gateway=""`:容器的 IPv4 网关地址,必须在网桥的子网段内; +* `--default-gateway-v6=""`:容器的 IPv6 网关地址; +* `--default-ulimit=[]`:默认的 ulimit 值; +* `--disable-legacy-registry=true|false`:是否允许访问旧版本的镜像仓库服务器; +* `--dns=""`:指定容器使用的 DNS 服务器地址; +* `--dns-opt=""`:DNS 选项; +* `--dns-search=[]`:DNS 搜索域; +* `--exec-opt=[]`:运行时的执行选项; +* `--exec-root=""`:容器执行状态文件的根路径,默认为 `/var/run/docker`; +* `--fixed-cidr=""`:限定分配 IPv4 地址范围; +* `--fixed-cidr-v6=""`:限定分配 IPv6 地址范围; +* `-G, --group=""`:分配给 unix 套接字的组,默认为 `docker`; +* `-g, --graph=""`:Docker 运行时的根路径,默认为 `/var/lib/docker`; +* `-H, --host=[]`:指定命令对应 Docker daemon 的监听接口,可以为 unix 套接字 `unix:///path/to/socket`,文件句柄 `fd://socketfd` 或 tcp 套接字 `tcp://[host[:port]]`,默认为 `unix:///var/run/docker.sock`; +* `--icc=true|false`:是否启用容器间以及跟 daemon 所在主机的通信。默认为 true。 +* `--insecure-registry=[]`:允许访问给定的非安全仓库服务; +* `--ip=""`:绑定容器端口时候的默认 IP 地址。缺省为 `0.0.0.0`; +* `--ip-forward=true|false`:是否检查启动在 Docker 主机上的启用 IP 转发服务,默认开启。注意关闭该选项将不对系统转发能力进行任何检查修改; +* `--ip-masq=true|false`:是否进行地址伪装,用于容器访问外部网络,默认开启; +* `--iptables=true|false`:是否允许 Docker 添加 iptables 规则。缺省为 true; +* `--ipv6=true|false`:是否启用 IPv6 支持,默认关闭; +* `-l, --log-level="debug|info|warn|error|fatal"`:指定日志输出级别; +* `--label="[]"`:添加指定的键值对标注; +* `--log-driver="json-file|syslog|journald|gelf|fluentd|awslogs|splunk|etwlogs|gcplogs|none"`:指定日志后端驱动,默认为 `json-file`; +* `--log-opt=[]`:日志后端的选项; +* `--mtu=VALUE`:指定容器网络的 `mtu`; +* `-p=""`:指定 daemon 的 PID 文件路径。缺省为 `/var/run/docker.pid`; +* `--raw-logs`:输出原始,未加色彩的日志信息; +* `--registry-mirror=://`:指定 `docker pull` 时使用的注册服务器镜像地址; +* `-s, --storage-driver=""`:指定使用给定的存储后端; +* `--selinux-enabled=true|false`:是否启用 SELinux 支持。缺省值为 false。SELinux 目前尚不支持 overlay 存储驱动; +* `--storage-opt=[]`:驱动后端选项; +* `--tls=true|false`:是否对 Docker daemon 启用 TLS 安全机制,默认为否; +* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径; +* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径; +* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径; +* `--tlsverify=true|false`:启用 TLS 校验,默认为否; +* `--userland-proxy=true|false`:是否使用用户态代理来实现容器间和出容器的回环通信,默认为 true; +* `--userns-remap=default|uid:gid|user:group|user|uid`:指定容器的用户命名空间,默认是创建新的 UID 和 GID 映射到容器内进程。 + +## 参考 + +* [官方文档](https://docs.docker.com/engine/reference/commandline/dockerd/) diff --git a/appendix/debug.md b/appendix/debug.md new file mode 100644 index 000000000..9fce8d7f3 --- /dev/null +++ b/appendix/debug.md @@ -0,0 +1,42 @@ +# 如何调试 Docker + +## 开启 Debug 模式 + +在 dockerd 配置文件 daemon.json(默认位于 /etc/docker/)中添加 + +```json +{ + "debug": true +} +``` + +重启守护进程。 + +```bash +$ sudo kill -SIGHUP $(pidof dockerd) +``` + +此时 dockerd 会在日志中输入更多信息供分析。 + +## 检查内核日志 + +```bash +$ sudo dmesag |grep dockerd +$ sudo dmesag |grep runc +``` + +## Docker 不响应时处理 + +可以杀死 dockerd 进程查看其堆栈调用情况。 + +```bash +$ sudo kill -SIGUSR1 $(pidof dockerd) +``` + +## 重置 Docker 本地数据 + +*注意,本操作会移除所有的 Docker 本地数据,包括镜像和容器等。* + +```bash +$ sudo rm -rf /var/lib/docker +``` diff --git a/appendix/faq/README.md b/appendix/faq/README.md index fefbe1acf..8b4a24814 100644 --- a/appendix/faq/README.md +++ b/appendix/faq/README.md @@ -1,99 +1,118 @@ # 常见问题总结 ## 镜像相关 -### 如何批量清理临时镜像文件 -答:可以使用 `docker rmi $(docker images -q -f dangling=true)` 命令。 + +### 如何批量清理临时镜像文件? + +答:可以使用 `docker image prune` 命令。 ### 如何查看镜像支持的环境变量? + 答:可以使用 `docker run IMAGE env` 命令。 ### 本地的镜像文件都存放在哪里? -答:与 Docker 相关的本地资源都存放在 `/var/lib/docker/` 目录下,以 aufs 文件系统为例,其中 container 目录存放容器信息,graph 目录存放镜像信息,aufs 目录下存放具体的镜像层文件。 + +答:与 Docker 相关的本地资源默认存放在 `/var/lib/docker/` 目录下,以 `overlay2` 文件系统为例,其中 `containers` 目录存放容器信息,`image` 目录存放镜像信息,`overlay2` 目录下存放具体的镜像层文件。 ### 构建 Docker 镜像应该遵循哪些原则? + 答:整体原则上,尽量保持镜像功能的明确和内容的精简,要点包括 -* 尽量选取满足需求但较小的基础系统镜像,例如大部分时候可以选择 debian:wheezy 或 debian:jessie 镜像,仅有不足百兆大小; +* 尽量选取满足需求但较小的基础系统镜像,例如大部分时候可以选择 `alpine` 镜像,仅有不足六兆大小; + * 清理编译生成文件、安装包的缓存等临时文件; + * 安装各个软件时候要指定准确的版本号,并避免引入不需要的依赖; + * 从安全角度考虑,应用要尽量使用系统的库和依赖; + * 如果安装应用时候需要配置一些特殊的环境变量,在安装后要还原不需要保持的变量值; + * 使用 Dockerfile 创建镜像时候要添加 .dockerignore 文件或使用干净的工作目录。 +更多内容请查看 [Dockerfile 最佳实践](../best_practices.md) + ### 碰到网络问题,无法 pull 镜像,命令行指定 http_proxy 无效? + 答:在 Docker 配置文件中添加 `export http_proxy="http://:"`,之后重启 Docker 服务即可。 ## 容器相关 -### 容器退出后,通过 docker ps 命令查看不到,数据会丢失么? -答:容器退出后会处于终止(exited)状态,此时可以通过 `docker ps -a` 查看。其中的数据也不会丢失,还可以通过 `docker start` 命令来启动它。只有删除掉容器才会清除所有数据。 -### 如何停止所有正在运行的容器 -答:可以使用 `docker kill $(docker ps -q)` 命令。 +### 容器退出后,通过 docker container ls 命令查看不到,数据会丢失么? + +答:容器退出后会处于终止(exited)状态,此时可以通过 `docker container ls -a` 查看。其中的数据也不会丢失,还可以通过 `docker start` 命令来启动它。只有删除掉容器才会清除所有数据。 + +### 如何停止所有正在运行的容器? + +答:可以使用 `docker stop $(docker container ls -q)` 命令。 -### 如何清理批量后台停止的容器? -答:可以使用 `docker rm -f $(docker ps -qa)` 命令。 +### 如何批量清理已经停止的容器? + +答:可以使用 `docker container prune` 命令。 ### 如何获取某个容器的 PID 信息? -答:可以使用 `docker inspect --format '{{ .State.Pid }}' ` 命令。 + +答:可以使用 + +```bash +docker inspect --format '{{ .State.Pid }}' +``` ### 如何获取某个容器的 IP 地址? -答:可以使用 `docker inspect --format '{{ .NetworkSettings.IPAddress }}' ` 命令 + +答:可以使用 +```bash +docker inspect --format '{{ .NetworkSettings.IPAddress }}' +``` ### 如何给容器指定一个固定 IP 地址,而不是每次重启容器 IP 地址都会变? -答:目前 Docker 并没有提供直接的对容器 IP 地址的管理支持,用户可以考虑参考第三部分中高级网络配置章节中介绍的创建点对点连接例子,来手动配置容器的静态 IP。或者在启动容器后,再手动进行修改(可参考其它类的问题 “*如何进入 Docker 容器的网络命名空间?*”)。 + +答:使用以下命令启动容器可以使容器 IP 固定不变 + +```bash +$ docker network create -d bridge --subnet 172.25.0.0/16 my-net + +$ docker run --network=my-net --ip=172.25.3.3 -itd --name=my-container busybox +``` ### 如何临时退出一个正在交互的容器的终端,而不终止它? + 答:按 `Ctrl-p Ctrl-q`。如果按 `Ctrl-c` 往往会让容器内应用进程终止,进而会终止容器。 ### 使用 `docker port` 命令映射容器的端口时,系统报错“Error: No public port '80' published for xxx”? + 答: -* 创建镜像时 Dockerfile 要通过 EXPOSE 指定正确的开放端口; +* 创建镜像时 `Dockerfile` 要通过 `EXPOSE` 指定正确的开放端口; + * 容器启动时指定 `PublishAllPort = true`。 ### 可以在一个容器中同时运行多个应用进程么? -答:一般并不推荐在同一个容器内运行多个应用进程。如果有类似需求,可以通过一些额外的进程管理机制,比如 supervisord 来管理所运行的进程。可以参考 https://docs.docker.com/articles/using_supervisord/。 + +答:一般并不推荐在同一个容器内运行多个应用进程。如果有类似需求,可以通过一些额外的进程管理机制,比如 `supervisord` 来管理所运行的进程。可以参考 https://docs.docker.com/config/containers/multi-service_container/ 。 ### 如何控制容器占用系统资源(CPU、内存)的份额? + 答:在使用 `docker create` 命令创建容器或使用 `docker run` 创建并启动容器的时候,可以使用 -c|--cpu-shares[=0] 参数来调整容器使用 CPU 的权重;使用 -m|--memory[=MEMORY] 参数来调整容器使用内存的大小。 ## 仓库相关 + ### 仓库(Repository)、注册服务器(Registry)、注册索引(Index) 有何关系? + 首先,仓库是存放一组关联镜像的集合,比如同一个应用的不同版本的镜像。 注册服务器是存放实际的镜像文件的地方。注册索引则负责维护用户的账号、权限、搜索、标签等的管理。因此,注册服务器利用注册索引来实现认证等管理。 -### 从非官方仓库(例如 non-official-repo.com)下载镜像时候,有时候会提示“Error: Invalid registry endpoint https://non-official-repo.com/v1/……”? -答:Docker 自 1.3.0 版本往后,加强了对镜像安全性的验证,需要添加私有仓库证书,或者手动添加对非官方仓库的信任。 -编辑 Docker 配置文件,在其中添加: - -```sh -DOCKER_OPTS="--insecure-registry non-official-repo" -``` -之后,重启 Docker 服务即可。 - ## 配置相关 -### Docker 的配置文件放在哪里,如何修改配置? -答:使用 upstart 的系统(如Ubuntu 14.04)的配置文件在 `/etc/default/docker`,使用systemd 的系统(如 Ubuntu 16.04、Centos 等)的配置文件在 `/etc/systemd/system/docker.service.d/docker.conf`。 - -Ubuntu 下面的配置文件内容如下,读者可以参考配。(如果出现该文件不存在的情况,重启或者自己新建一个文件都可以解决。) -```sh -# Customize location of Docker binary (especially for development testing). -#DOCKERD="/usr/local/bin/dockerd" - -# Use DOCKER_OPTS to modify the daemon startup options. -#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4" +### Docker 的配置文件放在哪里,如何修改配置? -# If you need Docker to use an HTTP proxy, it can also be specified here. -#export http_proxy="http://127.0.0.1:3128/" +答:使用 `systemd` 的系统(如 Ubuntu 16.04、Centos 等)的配置文件在 `/etc/docker/daemon.json`。 -# This is also a handy place to tweak where Docker's temporary files go. -#export TMPDIR="/mnt/bigdrive/docker-tmp" -``` ### 如何更改 Docker 的默认存储位置? -答:Docker 的默认存储位置是 `/var/lib/docker`,如果希望将 Docker 的本地文件存储到其他分区,可以使用 Linux 软连接的方式来完成,或者在启动 daemon 时通过 `-g` 参数指定。 + +答:Docker 的默认存储位置是 `/var/lib/docker`,如果希望将 Docker 的本地文件存储到其他分区,可以使用 Linux 软连接的方式来完成,或者在启动 daemon 时通过 `-g` 参数指定,或者修改配置文件 `/etc/docker/daemon.json` 的 "data-root" 项 。可以使用 `docker system info | grep "Root Dir"` 查看当前使用的存储位置。 例如,如下操作将默认存储位置迁移到 /storage/docker。 @@ -114,24 +133,29 @@ lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker [root@s26 lib]# service docker start ``` -### 使用内存和 swap 限制启动容器时候报警告:“WARNING: Your kernel does not support cgroup swap limit. WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.”? +### 使用内存和 swap 限制启动容器时候报警告:"WARNING: Your kernel does not support cgroup swap limit. WARNING: Your kernel does not support swap limit capabilities. Limitation discarded."? + 答:这是因为系统默认没有开启对内存和 swap 使用的统计功能,引入该功能会带来性能的下降。要开启该功能,可以采取如下操作: -* 编辑 `/etc/default/grub` 文件(Ubuntu 系统为例),配置 `GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"`; -* 更新 grub:`$ sudo update-grub`; +* 编辑 `/etc/default/grub` 文件(Ubuntu 系统为例),配置 `GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"` + +* 更新 grub:`$ sudo update-grub` + * 重启系统,即可。 ## Docker 与虚拟化 ### Docker 与 LXC(Linux Container)有何不同? + 答:LXC 利用 Linux 上相关技术实现了容器。Docker 则在如下的几个方面进行了改进: * 移植性:通过抽象容器配置,容器可以实现从一个平台移植到另一个平台; -* 镜像系统:基于 AUFS 的镜像系统为容器的分发带来了很多的便利,同时共同的镜像层只需要存储一份,实现高效率的存储; +* 镜像系统:基于 OverlayFS 的镜像系统为容器的分发带来了很多的便利,同时共同的镜像层只需要存储一份,实现高效率的存储; * 版本管理:类似于Git的版本管理理念,用户可以更方便的创建、管理镜像文件; * 仓库系统:仓库系统大大降低了镜像的分发和管理的成本; * 周边工具:各种现有工具(配置管理、云平台)对 Docker 的支持,以及基于 Docker的 PaaS、CI 等系统,让 Docker 的应用更加方便和多样化。 ### Docker 与 Vagrant 有何不同? + 答:两者的定位完全不同。 * Vagrant 类似 Boot2Docker(一款运行 Docker 的最小内核),是一套虚拟机的管理环境。Vagrant 可以在多种系统上和虚拟机软件中运行,可以在 Windows,Mac 等非 Linux 平台上为 Docker 提供支持,自身具有较好的包装性和移植性。 @@ -141,52 +165,57 @@ lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker 简单说:Vagrant 适合用来管理虚拟机,而 Docker 适合用来管理应用环境。 ### 开发环境中 Docker 和 Vagrant 该如何选择? -答: -Docker 不是虚拟机,而是进程隔离,对于资源的消耗很少,但是目前需要 Linux 环境支持。Vagrant 是虚拟机上做的封装,虚拟机本身会消耗资源。 + +答:Docker 不是虚拟机,而是进程隔离,对于资源的消耗很少,但是目前需要 Linux 环境支持。Vagrant 是虚拟机上做的封装,虚拟机本身会消耗资源。 如果本地使用的 Linux 环境,推荐都使用 Docker。 -如果本地使用的是 OSX 或者 Windows 环境,那就需要开虚拟机,单一开发环境下 Vagrant 更简单;多环境开发下推荐在 Vagrant 里面再使用 Docker 进行环境隔离。 +如果本地使用的是 macOS 或者 Windows 环境,那就需要开虚拟机,单一开发环境下 Vagrant 更简单;多环境开发下推荐在 Vagrant 里面再使用 Docker 进行环境隔离。 ## 其它 -### Docker 能在非 Linux 平台(比如 Windows 或 MacOS)上运行么? -答:可以。目前需要使用 docker for mac、boot2docker 等软件创建一个轻量级的 Linux 虚拟机层。 +### Docker 能在非 Linux 平台(比如 Windows 或 macOS )上运行么? + +答:完全可以。安装方法请查看 [安装 Docker](../../install/) 一节 + +### 如何将一台宿主主机的 Docker 环境迁移到另外一台宿主主机? -### 如何将一台宿主主机的 docker 环境迁移到另外一台宿主主机 答:停止 Docker 服务。将整个 Docker 存储文件夹复制到另外一台宿主主机,然后调整另外一台宿主主机的配置即可。 ### 如何进入 Docker 容器的网络命名空间? + 答:Docker 在创建容器后,删除了宿主主机上 `/var/run/netns` 目录中的相关的网络命名空间文件。因此,在宿主主机上是无法看到或访问容器的网络命名空间的。 用户可以通过如下方法来手动恢复它。 -首先,使用下面的命令查看容器进程信息,比如这里的1234。 +首先,使用下面的命令查看容器进程信息,比如这里的 1234。 -```sh +```bash $ docker inspect --format='{{. State.Pid}} ' $container_id 1234 ``` -接下来,在 /proc 目录下,把对应的网络命名空间文件链接到 /var/run/netns 目录。 -```sh +接下来,在 `/proc` 目录下,把对应的网络命名空间文件链接到 `/var/run/netns` 目录。 + +```bash $ sudo ln -s /proc/1234/ns/net /var/run/netns/ ``` 然后,在宿主主机上就可以看到容器的网络命名空间信息。例如 -```sh +```bash $ sudo ip netns show 1234 ``` 此时,用户可以通过正常的系统命令来查看或操作容器的命名空间了。例如修改容器的 IP 地址信息为 `172.17.0.100/16`。 -```sh +```bash $ sudo ip netns exec 1234 ifconfig eth0 172.17.0.100/16 ``` ### 如何获取容器绑定到本地那个 veth 接口上? + 答:Docker 容器启动后,会通过 veth 接口对连接到本地网桥,veth 接口命名跟容器命名毫无关系,十分难以找到对应关系。 最简单的一种方式是通过查看接口的索引号,在容器中执行 `ip a` 命令,查看到本地接口最前面的接口索引号,如 `205`,将此值加上 1,即 `206`,然后在本地主机执行 `ip a` 命令,查找接口索引号为 `206` 的接口,两者即为连接的 veth 接口对。 diff --git a/appendix/repo/README.md b/appendix/repo/README.md index 765be42fa..bc840d23a 100644 --- a/appendix/repo/README.md +++ b/appendix/repo/README.md @@ -1,2 +1,3 @@ # 热门镜像介绍 -本章将介绍一些热门镜像的功能,使用方法和生成它们的 Dockerfile 等。包括 Ubuntu、CentOS、MySQL、MongoDB、Redis、Nginx、Wordpress、Node.js 等。 + +本章将介绍一些热门镜像的功能,使用方法等。包括 Ubuntu、CentOS、MySQL、MongoDB、Redis、Nginx、Wordpress、Node.js 等。 diff --git a/appendix/repo/centos.md b/appendix/repo/centos.md index 44db1ab44..5ebaf20f6 100644 --- a/appendix/repo/centos.md +++ b/appendix/repo/centos.md @@ -1,58 +1,20 @@ -## [CentOS](https://hub.docker.com/_/centos/) +# [CentOS](https://hub.docker.com/_/centos) + +## 基本信息 -### 基本信息 [CentOS](https://en.wikipedia.org/wiki/CentOS) 是流行的 Linux 发行版,其软件包大多跟 RedHat 系列保持一致。 -该仓库位于 https://hub.docker.com/_/centos/,提供了 CentOS 从 5 ~ 7 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/centos` ,提供了 CentOS 从 5 ~ 8 各个版本的镜像。 + +## 使用方法 -### 使用方法 默认会启动一个最小化的 CentOS 环境。 -```sh -$ docker run --name some-centos -i -t centos bash +```bash +$ docker run --name centos -it centos bash bash-4.2# ``` -### Dockerfile - -#### CentOS 5 版本 -``` -FROM scratch -MAINTAINER The CentOS Project -ADD c5-docker.tar.xz / -LABEL name="CentOS Base Image" \ - vendor="CentOS" \ - license="GPLv2" \ - build-date="2016-03-31" - -# Default command -CMD ["/bin/bash"] -``` - -#### CentOS 6 版本 -``` -FROM scratch -MAINTAINER https://github.com/CentOS/sig-cloud-instance-images -ADD centos-6-docker.tar.xz / - -LABEL name="CentOS Base Image" \ - vendor="CentOS" \ - license="GPLv2" \ - build-date="20160729" - -CMD ["/bin/bash"] -``` +## Dockerfile -#### CentOS 7 版本 -``` -FROM scratch -MAINTAINER https://github.com/CentOS/sig-cloud-instance-images -ADD centos-7-docker.tar.xz / - -LABEL name="CentOS Base Image" \ - vendor="CentOS" \ - license="GPLv2" \ - build-date="20160729" - -CMD ["/bin/bash"] -``` +请到 https://github.com/docker-library/docs/tree/master/centos 查看。 diff --git a/appendix/repo/minio.md b/appendix/repo/minio.md new file mode 100644 index 000000000..c36d02d5d --- /dev/null +++ b/appendix/repo/minio.md @@ -0,0 +1,62 @@ +# minio +[TOC] +MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。 + +MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。 + +[官方文档](https://docs.min.io/) + +## 简单使用 + +测试、开发环境下不考虑数据存储的情况下可以使用下面的命令快速开启服务。 + +```bash +docker pull minio/minio +docker run -p 9000:9000 minio/minio server /data +``` + + + +## 离线部署 + +许多生产环境是一般是没有公网资源的,这就需要从有公网资源的服务器上把镜像导出,然后导入到需要运行镜像的内网服务器。 + +### 导出镜像 + +在有公网资源的服务器上下载好`minio/minio`镜像 + +```bash +docker save -o minio.tar minio/minio:latest +``` + + + +### 导入镜像 + +把压缩文件复制到内网服务器上,使用下面的命令导入镜像 + +```bash +docker load minio.tar +``` + +### 运行 minio + +- 把/mnt/data 改成要替换的数据目录 +- 替换 MINIO_ACCESS_KEY +- 替换 MINIO_SECRET_KEY +- 替换 name,minio1(可选) +- 如果9000端口冲突,替换端口前面的如:9009:9000 + +```bash +sudo docker run -d -p 9000:9000 --name minio1 \ + -e "MINIO_ACCESS_KEY=改成自己需要的" \ + -e "MINIO_SECRET_KEY=改成自己需要的" \ + -v /mnt/data:/data \ + --restart=always \ + minio/minio server /data +``` + +### 访问 web 管理页面 + +http://x.x.x.x:9000/minio/ + diff --git a/appendix/repo/mongodb.md b/appendix/repo/mongodb.md index 3ee445291..129e90869 100644 --- a/appendix/repo/mongodb.md +++ b/appendix/repo/mongodb.md @@ -1,263 +1,34 @@ -## [MongoDB](https://hub.docker.com/_/mongo/) +# [MongoDB](https://hub.docker.com/_/mongo/) + +## 基本信息 -### 基本信息 [MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是开源的 NoSQL 数据库实现。 -该仓库位于 https://hub.docker.com/_/mongo/,提供了 MongoDB 2.x ~ 3.x 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/mongo/` ,提供了 MongoDB 2.x ~ 4.x 各个版本的镜像。 + +## 使用方法 -### 使用方法 默认会在 `27017` 端口启动数据库。 -```sh -$ docker run --name some-mongo -d mongo +```bash +$ docker run --name mongo -d mongo ``` 使用其他应用连接到容器,可以用 -```sh +```bash $ docker run --name some-app --link some-mongo:mongo -d application-that-uses-mongo ``` 或者通过 `mongo` -```sh -$ docker run -it --link some-mongo:mongo --rm mongo sh -c 'exec mongo "$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/test"' -``` - -### Dockerfile - -#### 2.6 版本 -``` -FROM debian:wheezy - -# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added -RUN groupadd -r mongodb && useradd -r -g mongodb mongodb - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - ca-certificates wget \ - numactl \ - && rm -rf /var/lib/apt/lists/* - -# grab gosu for easy step-down from root -ENV GOSU_VERSION 1.7 -RUN set -x \ - && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \ - && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \ - && export GNUPGHOME="$(mktemp -d)" \ - && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ - && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ - && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ - && chmod +x /usr/local/bin/gosu \ - && gosu nobody true - -ENV MONGO_VERSION 2.6.12 - -RUN set -x \ - && wget -O mongo.tgz "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-$MONGO_VERSION.tgz" \ - && wget -O mongo.tgz.sig "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-$MONGO_VERSION.tgz.sig" \ - && export GNUPGHOME="$(mktemp -d)" \ - && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys DFFA3DCF326E302C4787673A01C4E7FAAAB2461C \ - && gpg --batch --verify mongo.tgz.sig mongo.tgz \ - && rm -r "$GNUPGHOME" mongo.tgz.sig \ - && tar -xvf mongo.tgz -C /usr/local --strip-components=1 \ - && rm mongo.tgz - -RUN mkdir -p /data/db /data/configdb \ - && chown -R mongodb:mongodb /data/db /data/configdb -VOLUME /data/db /data/configdb - -COPY docker-entrypoint.sh /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] - -EXPOSE 27017 -CMD ["mongod"] -``` - -#### 3.0 版本 -``` -FROM debian:wheezy - -# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added -RUN groupadd -r mongodb && useradd -r -g mongodb mongodb - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - numactl \ - && rm -rf /var/lib/apt/lists/* - -# grab gosu for easy step-down from root -ENV GOSU_VERSION 1.7 -RUN set -x \ - && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \ - && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \ - && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \ - && export GNUPGHOME="$(mktemp -d)" \ - && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ - && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ - && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ - && chmod +x /usr/local/bin/gosu \ - && gosu nobody true \ - && apt-get purge -y --auto-remove ca-certificates wget - -# gpg: key 7F0CEB10: public key "Richard Kreuter " imported -RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys 492EAFE8CD016A07919F1D2B9ECBEC467F0CEB10 - -ENV MONGO_MAJOR 3.0 -ENV MONGO_VERSION 3.0.12 - -RUN echo "deb http://repo.mongodb.org/apt/debian wheezy/mongodb-org/$MONGO_MAJOR main" > /etc/apt/sources.list.d/mongodb-org.list - -RUN set -x \ - && apt-get update \ - && apt-get install -y \ - mongodb-org=$MONGO_VERSION \ - mongodb-org-server=$MONGO_VERSION \ - mongodb-org-shell=$MONGO_VERSION \ - mongodb-org-mongos=$MONGO_VERSION \ - mongodb-org-tools=$MONGO_VERSION \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /var/lib/mongodb \ - && mv /etc/mongod.conf /etc/mongod.conf.orig - -RUN mkdir -p /data/db /data/configdb \ - && chown -R mongodb:mongodb /data/db /data/configdb -VOLUME /data/db /data/configdb - -COPY docker-entrypoint.sh /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] - -EXPOSE 27017 -CMD ["mongod"] -``` - -#### 3.2 版本 - -``` -FROM debian:wheezy - -# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added -RUN groupadd -r mongodb && useradd -r -g mongodb mongodb - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - numactl \ - && rm -rf /var/lib/apt/lists/* - -# grab gosu for easy step-down from root -ENV GOSU_VERSION 1.7 -RUN set -x \ - && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \ - && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \ - && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \ - && export GNUPGHOME="$(mktemp -d)" \ - && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ - && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ - && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ - && chmod +x /usr/local/bin/gosu \ - && gosu nobody true \ - && apt-get purge -y --auto-remove ca-certificates wget - -# pub 4096R/AAB2461C 2014-02-25 [expires: 2016-02-25] -# Key fingerprint = DFFA 3DCF 326E 302C 4787 673A 01C4 E7FA AAB2 461C -# uid MongoDB 2.6 Release Signing Key -# -# pub 4096R/EA312927 2015-10-09 [expires: 2017-10-08] -# Key fingerprint = 42F3 E95A 2C4F 0827 9C49 60AD D68F A50F EA31 2927 -# uid MongoDB 3.2 Release Signing Key -# -ENV GPG_KEYS \ - DFFA3DCF326E302C4787673A01C4E7FAAAB2461C \ - 42F3E95A2C4F08279C4960ADD68FA50FEA312927 -RUN set -ex \ - && for key in $GPG_KEYS; do \ - apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ - done - -ENV MONGO_MAJOR 3.2 -ENV MONGO_VERSION 3.2.8 - -RUN echo "deb http://repo.mongodb.org/apt/debian wheezy/mongodb-org/$MONGO_MAJOR main" > /etc/apt/sources.list.d/mongodb-org.list - -RUN set -x \ - && apt-get update \ - && apt-get install -y \ - mongodb-org=$MONGO_VERSION \ - mongodb-org-server=$MONGO_VERSION \ - mongodb-org-shell=$MONGO_VERSION \ - mongodb-org-mongos=$MONGO_VERSION \ - mongodb-org-tools=$MONGO_VERSION \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /var/lib/mongodb \ - && mv /etc/mongod.conf /etc/mongod.conf.orig - -RUN mkdir -p /data/db /data/configdb \ - && chown -R mongodb:mongodb /data/db /data/configdb -VOLUME /data/db /data/configdb - -COPY docker-entrypoint.sh /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] - -EXPOSE 27017 -CMD ["mongod"] +```bash +$ docker run -it --rm \ + --link some-mongo:mongo \ + mongo \ + sh -c 'exec mongo "$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/test"' ``` -#### 3.3 版本 - -``` -FROM debian:jessie - -# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added -RUN groupadd -r mongodb && useradd -r -g mongodb mongodb - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - numactl \ - && rm -rf /var/lib/apt/lists/* - -# grab gosu for easy step-down from root -ENV GOSU_VERSION 1.7 -RUN set -x \ - && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \ - && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \ - && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \ - && export GNUPGHOME="$(mktemp -d)" \ - && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ - && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ - && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ - && chmod +x /usr/local/bin/gosu \ - && gosu nobody true \ - && apt-get purge -y --auto-remove ca-certificates wget - -# pub 4096R/A15703C6 2016-01-11 [expires: 2018-01-10] -# Key fingerprint = 0C49 F373 0359 A145 1858 5931 BC71 1F9B A157 03C6 -# uid MongoDB 3.4 Release Signing Key -RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys 0C49F3730359A14518585931BC711F9BA15703C6 - -ENV MONGO_MAJOR 3.3 -ENV MONGO_VERSION 3.3.10 - -RUN echo "deb http://repo.mongodb.org/apt/debian jessie/mongodb-org/$MONGO_MAJOR main" > /etc/apt/sources.list.d/mongodb-org.list - -RUN set -x \ - && apt-get update \ - && apt-get install -y \ - mongodb-org-unstable=$MONGO_VERSION \ - mongodb-org-unstable-server=$MONGO_VERSION \ - mongodb-org-unstable-shell=$MONGO_VERSION \ - mongodb-org-unstable-mongos=$MONGO_VERSION \ - mongodb-org-unstable-tools=$MONGO_VERSION \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /var/lib/mongodb \ - && mv /etc/mongod.conf /etc/mongod.conf.orig - -RUN mkdir -p /data/db /data/configdb \ - && chown -R mongodb:mongodb /data/db /data/configdb -VOLUME /data/db /data/configdb - -COPY docker-entrypoint.sh /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] +## Dockerfile -EXPOSE 27017 -CMD ["mongod"] -``` \ No newline at end of file +请到 https://github.com/docker-library/docs/tree/master/mongo 查看。 diff --git a/appendix/repo/mysql.md b/appendix/repo/mysql.md index de5b6b4e0..1a38c9dfc 100644 --- a/appendix/repo/mysql.md +++ b/appendix/repo/mysql.md @@ -1,124 +1,34 @@ -## [MySQL](https://hub.docker.com/_/mysql/) +# [MySQL](https://hub.docker.com/_/mysql/) + +## 基本信息 -### 基本信息 [MySQL](https://en.wikipedia.org/wiki/MySQL) 是开源的关系数据库实现。 -该仓库位于 https://hub.docker.com/_/mysql/,提供了 MySQL 各个版本的镜像,包括 5.6 系列、5.7 系列等。 +该仓库位于 `https://hub.docker.com/_/mysql/` ,提供了 MySQL 5.5 ~ 8.x 各个版本的镜像。 + +## 使用方法 -### 使用方法 默认会在 `3306` 端口启动数据库。 -``` +```bash $ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=mysecretpassword -d mysql ``` + 之后就可以使用其它应用来连接到该容器。 -``` +```bash $ docker run --name some-app --link some-mysql:mysql -d application-that-uses-mysql ``` -或者通过 `mysql`。 -``` -$ docker run -it --link some-mysql:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"' -``` +或者通过 `mysql` 命令行连接。 -### Dockerfile -#### 5.6 版本 +```bash +$ docker run -it --rm \ + --link some-mysql:mysql \ + mysql \ + sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"' ``` -FROM debian:wheezy - -# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added -RUN groupadd -r mysql && useradd -r -g mysql mysql - -# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db: -# File::Basename -# File::Copy -# Sys::Hostname -# Data::Dumper -RUN apt-get update && apt-get install -y perl --no-install-recommends && rm -rf /var/lib/apt/lists/* - -# mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory -RUN apt-get update && apt-get install -y libaio1 && rm -rf /var/lib/apt/lists/* - -# gpg: key 5072E1F5: public key "MySQL Release Engineering " imported -RUN gpg --keyserver pgp.mit.edu --recv-keys A4A9406876FCBD3C456770C88C718D3B5072E1F5 - -ENV MYSQL_MAJOR 5.6 -ENV MYSQL_VERSION 5.6.20 - -# note: we're pulling the *.asc file from mysql.he.net instead of dev.mysql.com because the official mirror 404s that file for whatever reason - maybe it's at a different path? -RUN apt-get update && apt-get install -y curl --no-install-recommends && rm -rf /var/lib/apt/lists/* \ - && curl -SL "http://dev.mysql.com/get/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux-glibc2.5-x86_64.tar.gz" -o mysql.tar.gz \ - && curl -SL "http://mysql.he.net/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux-glibc2.5-x86_64.tar.gz.asc" -o mysql.tar.gz.asc \ - && apt-get purge -y --auto-remove curl \ - && gpg --verify mysql.tar.gz.asc \ - && mkdir /usr/local/mysql \ - && tar -xzf mysql.tar.gz -C /usr/local/mysql --strip-components=1 \ - && rm mysql.tar.gz* \ - && rm -rf /usr/local/mysql/mysql-test /usr/local/mysql/sql-bench \ - && rm -rf /usr/local/mysql/bin/*-debug /usr/local/mysql/bin/*_embedded \ - && find /usr/local/mysql -type f -name "*.a" -delete \ - && apt-get update && apt-get install -y binutils && rm -rf /var/lib/apt/lists/* \ - && { find /usr/local/mysql -type f -executable -exec strip --strip-all '{}' + || true; } \ - && apt-get purge -y --auto-remove binutils -ENV PATH $PATH:/usr/local/mysql/bin:/usr/local/mysql/scripts - -WORKDIR /usr/local/mysql -VOLUME /var/lib/mysql -COPY docker-entrypoint.sh /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] +## Dockerfile -EXPOSE 3306 -CMD ["mysqld", "--datadir=/var/lib/mysql", "--user=mysql"] -``` - -#### 5.7 版本 -``` -FROM debian:wheezy - -# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added -RUN groupadd -r mysql && useradd -r -g mysql mysql - -# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db: -# File::Basename -# File::Copy -# Sys::Hostname -# Data::Dumper -RUN apt-get update && apt-get install -y perl --no-install-recommends && rm -rf /var/lib/apt/lists/* - -# mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory -RUN apt-get update && apt-get install -y libaio1 && rm -rf /var/lib/apt/lists/* - -# gpg: key 5072E1F5: public key "MySQL Release Engineering " imported -RUN gpg --keyserver pgp.mit.edu --recv-keys A4A9406876FCBD3C456770C88C718D3B5072E1F5 - -ENV MYSQL_MAJOR 5.7 -ENV MYSQL_VERSION 5.7.4-m14 - -# note: we're pulling the *.asc file from mysql.he.net instead of dev.mysql.com because the official mirror 404s that file for whatever reason - maybe it's at a different path? -RUN apt-get update && apt-get install -y curl --no-install-recommends && rm -rf /var/lib/apt/lists/* \ - && curl -SL "http://dev.mysql.com/get/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux-glibc2.5-x86_64.tar.gz" -o mysql.tar.gz \ - && curl -SL "http://mysql.he.net/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux-glibc2.5-x86_64.tar.gz.asc" -o mysql.tar.gz.asc \ - && apt-get purge -y --auto-remove curl \ - && gpg --verify mysql.tar.gz.asc \ - && mkdir /usr/local/mysql \ - && tar -xzf mysql.tar.gz -C /usr/local/mysql --strip-components=1 \ - && rm mysql.tar.gz* \ - && rm -rf /usr/local/mysql/mysql-test /usr/local/mysql/sql-bench \ - && rm -rf /usr/local/mysql/bin/*-debug /usr/local/mysql/bin/*_embedded \ - && find /usr/local/mysql -type f -name "*.a" -delete \ - && apt-get update && apt-get install -y binutils && rm -rf /var/lib/apt/lists/* \ - && { find /usr/local/mysql -type f -executable -exec strip --strip-all '{}' + || true; } \ - && apt-get purge -y --auto-remove binutils -ENV PATH $PATH:/usr/local/mysql/bin:/usr/local/mysql/scripts - -WORKDIR /usr/local/mysql -VOLUME /var/lib/mysql - -COPY docker-entrypoint.sh /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] - -EXPOSE 3306 -CMD ["mysqld", "--datadir=/var/lib/mysql", "--user=mysql"] -``` +请到 https://github.com/docker-library/docs/tree/master/mysql 查看 diff --git a/appendix/repo/nginx.md b/appendix/repo/nginx.md index ff889225e..8abac44e7 100644 --- a/appendix/repo/nginx.md +++ b/appendix/repo/nginx.md @@ -1,101 +1,48 @@ -## [Nginx](https://hub.docker.com/_/nginx/) +# [Nginx](https://hub.docker.com/_/nginx/) + +## 基本信息 -### 基本信息 [Nginx](https://en.wikipedia.org/wiki/Nginx) 是开源的高效的 Web 服务器实现,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议。 -该仓库位于 https://hub.docker.com/_/nginx/,提供了 Nginx 1.0 ~ 1.11.x 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/nginx/` ,提供了 Nginx 1.0 ~ 1.19.x 各个版本的镜像。 + +## 使用方法 -### 使用方法 下面的命令将作为一个静态页面服务器启动。 -``` +```bash $ docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx ``` + 用户也可以不使用这种映射方式,通过利用 Dockerfile 来直接将静态页面内容放到镜像中,内容为 -``` +```bash FROM nginx COPY static-html-directory /usr/share/nginx/html ``` + 之后生成新的镜像,并启动一个容器。 -``` +```bash $ docker build -t some-content-nginx . $ docker run --name some-nginx -d some-content-nginx ``` + 开放端口,并映射到本地的 `8080` 端口。 -``` -docker run --name some-nginx -d -p 8080:80 some-content-nginx +```bash +$ docker run --name some-nginx -d -p 8080:80 some-content-nginx ``` Nginx的默认配置文件路径为 `/etc/nginx/nginx.conf`,可以通过映射它来使用本地的配置文件,例如 +```bash +$ docker run -d \ + --name some-nginx \ + -v /some/nginx.conf:/etc/nginx/nginx.conf:ro \ + nginx ``` -docker run --name some-nginx -v /some/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx -``` -使用配置文件时,为了在容器中正常运行,需要保持 `daemon off;`。 - -### Dockerfile -#### stable 版本 -``` -FROM debian:jessie - -MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com" - -ENV NGINX_VERSION 1.10.1-1~jessie -RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 \ - && echo "deb http://nginx.org/packages/debian/ jessie nginx" >> /etc/apt/sources.list \ - && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y \ - ca-certificates \ - nginx=${NGINX_VERSION} \ - nginx-module-xslt \ - nginx-module-geoip \ - nginx-module-image-filter \ - nginx-module-perl \ - nginx-module-njs \ - gettext-base \ - && rm -rf /var/lib/apt/lists/* +## Dockerfile -# forward request and error logs to docker log collector -RUN ln -sf /dev/stdout /var/log/nginx/access.log \ - && ln -sf /dev/stderr /var/log/nginx/error.log - -EXPOSE 80 443 - -CMD ["nginx", "-g", "daemon off;"] -``` - -#### 1.11.x 版本 - -``` -FROM debian:jessie - -MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com" - -ENV NGINX_VERSION 1.11.1-1~jessie - -RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 \ - && echo "deb http://nginx.org/packages/mainline/debian/ jessie nginx" >> /etc/apt/sources.list \ - && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y \ - ca-certificates \ - nginx=${NGINX_VERSION} \ - nginx-module-xslt \ - nginx-module-geoip \ - nginx-module-image-filter \ - nginx-module-perl \ - nginx-module-njs \ - gettext-base \ - && rm -rf /var/lib/apt/lists/* - -# forward request and error logs to docker log collector -RUN ln -sf /dev/stdout /var/log/nginx/access.log \ - && ln -sf /dev/stderr /var/log/nginx/error.log - -EXPOSE 80 443 - -CMD ["nginx", "-g", "daemon off;"] -``` +请到 https://github.com/docker-library/docs/tree/master/nginx 查看。 diff --git a/appendix/repo/nodejs.md b/appendix/repo/nodejs.md index 55295a658..d44563aa6 100644 --- a/appendix/repo/nodejs.md +++ b/appendix/repo/nodejs.md @@ -1,151 +1,40 @@ -## [Node.js](https://hub.docker.com/_/node/) +# [Node.js](https://hub.docker.com/_/node/) -### 基本信息 -[Node.js](https://en.wikipedia.org/wiki/Node.js)是基于 JavaScript 的可扩展服务端和网络软件开发平台。 +## 基本信息 -该仓库位于 https://hub.docker.com/_/node/,提供了 Node.js 0.10 ~ 6.3.x 各个版本的镜像。 +[Node.js](https://en.wikipedia.org/wiki/Node.js) 是基于 JavaScript 的可扩展服务端和网络软件开发平台。 + +该仓库位于 `https://hub.docker.com/_/node/` ,提供了 Node.js 0.10 ~ 14.x 各个版本的镜像。 + +## 使用方法 -### 使用方法 在项目中创建一个 Dockerfile。 -``` -FROM node:0.10-onbuild +```bash +FROM node:12 # replace this with your application's default port EXPOSE 8888 ``` + 然后创建镜像,并启动容器。 -``` +```bash $ docker build -t my-nodejs-app $ docker run -it --rm --name my-running-app my-nodejs-app ``` 也可以直接运行一个简单容器。 +```bash +$ docker run -it --rm \ + --name my-running-script \ + # -v "$(pwd)":/usr/src/myapp \ + --mount type=bind,src=`$(pwd)`,target=/usr/src/myapp \ + -w /usr/src/myapp \ + node:12-alpine \ + node your-daemon-or-script.js ``` -$ docker run -it --rm --name my-running-script -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp node:0.10 node your-daemon-or-script.js -``` - -### Dockerfile - -#### 0.10 版本 -``` -FROM buildpack-deps - -RUN apt-get update && apt-get install -y \ - ca-certificates \ - curl - -# verify gpg and sha256: http://nodejs.org/dist/v0.10.31/SHASUMS256.txt.asc -# gpg: aka "Timothy J Fontaine (Work) " -RUN gpg --keyserver pgp.mit.edu --recv-keys 7937DFD2AB06298B2293C3187D33FF9D0246406D - -ENV NODE_VERSION 0.10.32 - -RUN curl -SLO "http://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" \ - && curl -SLO "http://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ - && gpg --verify SHASUMS256.txt.asc \ - && grep " node-v$NODE_VERSION-linux-x64.tar.gz\$" SHASUMS256.txt.asc | sha256sum -c - \ - && tar -xzf "node-v$NODE_VERSION-linux-x64.tar.gz" -C /usr/local --strip-components=1 \ - && rm "node-v$NODE_VERSION-linux-x64.tar.gz" SHASUMS256.txt.asc - -CMD [ "node" ] -``` - -#### 4.x 版本 -``` -FROM buildpack-deps:jessie - -# gpg keys listed at https://github.com/nodejs/node -RUN set -ex \ - && for key in \ - 9554F04D7259F04124DE6B476D5A82AC7E37093B \ - 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \ - 0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93 \ - FD3A5288F042B6850C66B31F09FE44734EB7990E \ - 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \ - DD8F2338BAE7501E3DD5AC78C273792F7D83545D \ - B9AE9905FFD7803F25714661B63B535A4C206CA9 \ - C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ - ; do \ - gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ - done - -ENV NPM_CONFIG_LOGLEVEL info -ENV NODE_VERSION 4.4.7 - -RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ - && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ - && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ - && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \ - && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \ - && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt - -CMD [ "node" ] -``` - -#### 5.x 版本 - -``` -FROM buildpack-deps:jessie - -# gpg keys listed at https://github.com/nodejs/node -RUN set -ex \ - && for key in \ - 9554F04D7259F04124DE6B476D5A82AC7E37093B \ - 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \ - 0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93 \ - FD3A5288F042B6850C66B31F09FE44734EB7990E \ - 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \ - DD8F2338BAE7501E3DD5AC78C273792F7D83545D \ - B9AE9905FFD7803F25714661B63B535A4C206CA9 \ - C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ - ; do \ - gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ - done - -ENV NPM_CONFIG_LOGLEVEL info -ENV NODE_VERSION 5.12.0 - -RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ - && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ - && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ - && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \ - && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \ - && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt - -CMD [ "node" ] -``` - -#### 6.x 版本 -``` -FROM buildpack-deps:jessie -# gpg keys listed at https://github.com/nodejs/node -RUN set -ex \ - && for key in \ - 9554F04D7259F04124DE6B476D5A82AC7E37093B \ - 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \ - 0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93 \ - FD3A5288F042B6850C66B31F09FE44734EB7990E \ - 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \ - DD8F2338BAE7501E3DD5AC78C273792F7D83545D \ - B9AE9905FFD7803F25714661B63B535A4C206CA9 \ - C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ - ; do \ - gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ - done - -ENV NPM_CONFIG_LOGLEVEL info -ENV NODE_VERSION 6.3.1 - -RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ - && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ - && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ - && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \ - && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \ - && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt - -CMD [ "node" ] -``` +## Dockerfile +请到 https://github.com/docker-library/docs/tree/master/node 查看。 diff --git a/appendix/repo/php.md b/appendix/repo/php.md new file mode 100644 index 000000000..5ef53b845 --- /dev/null +++ b/appendix/repo/php.md @@ -0,0 +1,19 @@ +# [PHP](https://hub.docker.com/_/php/) + +## 基本信息 + +[PHP](https://en.wikipedia.org/wiki/Php)(Hypertext Preprocessor 超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML 中,尤其适合 web 开发。 + +该仓库位于 `https://hub.docker.com/_/php/` ,提供了 PHP 5.x ~ 8.x 各个版本的镜像。 + +## 使用方法 + +下面的命令将运行一个已有的 PHP 脚本。 + +```bash +$ docker run -it --rm -v "$PWD":/app -w /app php:alpine php your-script.php +``` + +## Dockerfile + +请到 https://github.com/docker-library/docs/tree/master/php 查看。 diff --git a/appendix/repo/redis.md b/appendix/repo/redis.md index cadeefc09..d14a73634 100644 --- a/appendix/repo/redis.md +++ b/appendix/repo/redis.md @@ -1,141 +1,42 @@ -## [Redis](https://hub.docker.com/_/redis/) +# [Redis](https://hub.docker.com/_/redis/) + +## 基本信息 -### 基本信息 [Redis](https://en.wikipedia.org/wiki/Redis) 是开源的内存 Key-Value 数据库实现。 -该仓库位于 https://hub.docker.com/_/redis/,提供了 Redis 3.x 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/redis/` ,提供了 Redis 3.x ~ 6.x 各个版本的镜像。 + +## 使用方法 -### 使用方法 默认会在 `6379` 端口启动数据库。 +```bash +$ docker run --name some-redis -d -p 6379:6379 redis ``` -$ docker run --name some-redis -d redis -``` -另外还可以启用 [持久存储](http://redis.io/topics/persistence)。 -``` -$ docker run --name some-redis -d redis redis-server --appendonly yes +另外还可以启用 [持久存储](https://redis.io/topics/persistence)。 + +```bash +$ docker run --name some-redis -d -p 6379:6379 redis redis-server --appendonly yes ``` 默认数据存储位置在 `VOLUME/data`。可以使用 `--volumes-from some-volume-container` 或 `-v /docker/host/dir:/data` 将数据存放到本地。 使用其他应用连接到容器,可以用 -``` +```bash $ docker run --name some-app --link some-redis:redis -d application-that-uses-redis ``` -或者通过 `redis-cli` - -``` -$ docker run -it --link some-redis:redis --rm redis sh -c 'exec redis-cli -h "$REDIS_PORT_6379_TCP_ADDR" -p "$REDIS_PORT_6379_TCP_PORT"' -``` - -### Dockerfile -#### 3.0 版本 -``` -FROM debian:jessie - -# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added -RUN groupadd -r redis && useradd -r -g redis redis - -RUN apt-get update && apt-get install -y --no-install-recommends \ - ca-certificates \ - wget \ - && rm -rf /var/lib/apt/lists/* -# grab gosu for easy step-down from root -ENV GOSU_VERSION 1.7 -RUN set -x \ - && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \ - && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \ - && export GNUPGHOME="$(mktemp -d)" \ - && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ - && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ - && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ - && chmod +x /usr/local/bin/gosu \ - && gosu nobody true - -ENV REDIS_VERSION 3.0.7 -ENV REDIS_DOWNLOAD_URL http://download.redis.io/releases/redis-3.0.7.tar.gz -ENV REDIS_DOWNLOAD_SHA1 e56b4b7e033ae8dbf311f9191cf6fdf3ae974d1c - -# for redis-sentinel see: http://redis.io/topics/sentinel -RUN buildDeps='gcc libc6-dev make' \ - && set -x \ - && apt-get update && apt-get install -y $buildDeps --no-install-recommends \ - && rm -rf /var/lib/apt/lists/* \ - && wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL" \ - && echo "$REDIS_DOWNLOAD_SHA1 *redis.tar.gz" | sha1sum -c - \ - && mkdir -p /usr/src/redis \ - && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \ - && rm redis.tar.gz \ - && make -C /usr/src/redis \ - && make -C /usr/src/redis install \ - && rm -r /usr/src/redis \ - && apt-get purge -y --auto-remove $buildDeps - -RUN mkdir /data && chown redis:redis /data -VOLUME /data -WORKDIR /data - -COPY docker-entrypoint.sh /usr/local/bin/ -RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat -ENTRYPOINT ["docker-entrypoint.sh"] - -EXPOSE 6379 -CMD [ "redis-server" ] -``` +或者通过 `redis-cli` -#### 3.2 版本 +```bash +$ docker run -it --rm \ + --link some-redis:redis \ + redis \ + sh -c 'exec redis-cli -h "$REDIS_PORT_6379_TCP_ADDR" -p "$REDIS_PORT_6379_TCP_PORT"' ``` -FROM debian:jessie -# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added -RUN groupadd -r redis && useradd -r -g redis redis +## Dockerfile -RUN apt-get update && apt-get install -y --no-install-recommends \ - ca-certificates \ - wget \ - && rm -rf /var/lib/apt/lists/* - -# grab gosu for easy step-down from root -ENV GOSU_VERSION 1.7 -RUN set -x \ - && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \ - && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \ - && export GNUPGHOME="$(mktemp -d)" \ - && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ - && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ - && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ - && chmod +x /usr/local/bin/gosu \ - && gosu nobody true - -ENV REDIS_VERSION 3.2.3 -ENV REDIS_DOWNLOAD_URL http://download.redis.io/releases/redis-3.2.3.tar.gz -ENV REDIS_DOWNLOAD_SHA1 92d6d93ef2efc91e595c8bf578bf72baff397507 - -# for redis-sentinel see: http://redis.io/topics/sentinel -RUN buildDeps='gcc libc6-dev make' \ - && set -x \ - && apt-get update && apt-get install -y $buildDeps --no-install-recommends \ - && rm -rf /var/lib/apt/lists/* \ - && wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL" \ - && echo "$REDIS_DOWNLOAD_SHA1 *redis.tar.gz" | sha1sum -c - \ - && mkdir -p /usr/src/redis \ - && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \ - && rm redis.tar.gz \ - && make -C /usr/src/redis \ - && make -C /usr/src/redis install \ - && rm -r /usr/src/redis \ - && apt-get purge -y --auto-remove $buildDeps - -RUN mkdir /data && chown redis:redis /data -VOLUME /data -WORKDIR /data - -COPY docker-entrypoint.sh /usr/local/bin/ -ENTRYPOINT ["docker-entrypoint.sh"] - -EXPOSE 6379 -CMD [ "redis-server" ] -``` +请到 https://github.com/docker-library/docs/tree/master/redis 查看。 diff --git a/appendix/repo/ubuntu.md b/appendix/repo/ubuntu.md index 2253678db..c2f534eef 100644 --- a/appendix/repo/ubuntu.md +++ b/appendix/repo/ubuntu.md @@ -1,142 +1,20 @@ -## [Ubuntu](https://hub.docker.com/_/ubuntu/) +# [Ubuntu](https://hub.docker.com/_/ubuntu/) + +## 基本信息 -### 基本信息 [Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 发行版,其自带软件版本往往较新一些。 -该仓库位于 https://hub.docker.com/_/ubuntu/,提供了 Ubuntu 从 12.04 ~ 16.10 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/ubuntu/` ,提供了 Ubuntu 从 12.04 ~ 20.04 各个版本的镜像。 + +## 使用方法 -### 使用方法 默认会启动一个最小化的 Ubuntu 环境。 -``` -$ docker run --name some-ubuntu -i -t ubuntu +```bash +$ docker run --name some-ubuntu -it ubuntu:20.04 root@523c70904d54:/# ``` -### Dockerfile - -#### 12.04 版本 -``` -FROM scratch -ADD precise-core-amd64.tar.gz / - -# a few minor docker-specific tweaks -# see https://github.com/dotcloud/docker/blob/master/contrib/mkimage/debootstrap -RUN echo '#!/bin/sh' > /usr/sbin/policy-rc.d \ - && echo 'exit 101' >> /usr/sbin/policy-rc.d \ - && chmod +x /usr/sbin/policy-rc.d \ - \ - && dpkg-divert --local --rename --add /sbin/initctl \ - && cp -a /usr/sbin/policy-rc.d /sbin/initctl \ - && sed -i 's/^exit.*/exit 0/' /sbin/initctl \ - \ - && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \ - \ - && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \ - && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \ - && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \ - \ - && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \ - \ - && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes - -# delete all the apt list files since they're big and get stale quickly -RUN rm -rf /var/lib/apt/lists/* -# this forces "apt-get update" in dependent images, which is also good - -# enable the universe -RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list - -# upgrade packages for now, since the tarballs aren't updated frequently enough -RUN apt-get update && apt-get dist-upgrade -y && rm -rf /var/lib/apt/lists/* - -# overwrite this with 'CMD []' in a dependent Dockerfile -CMD ["/bin/bash"] -``` - -#### 14.04 版本 -``` -FROM scratch -ADD trusty-core-amd64.tar.gz / - -# a few minor docker-specific tweaks -# see https://github.com/dotcloud/docker/blob/master/contrib/mkimage/debootstrap -RUN echo '#!/bin/sh' > /usr/sbin/policy-rc.d \ - && echo 'exit 101' >> /usr/sbin/policy-rc.d \ - && chmod +x /usr/sbin/policy-rc.d \ - \ - && dpkg-divert --local --rename --add /sbin/initctl \ - && cp -a /usr/sbin/policy-rc.d /sbin/initctl \ - && sed -i 's/^exit.*/exit 0/' /sbin/initctl \ - \ - && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \ - \ - && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \ - && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \ - && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \ - \ - && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \ - \ - && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes - -# delete all the apt list files since they're big and get stale quickly -RUN rm -rf /var/lib/apt/lists/* -# this forces "apt-get update" in dependent images, which is also good - -# enable the universe -RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list - -# upgrade packages for now, since the tarballs aren't updated frequently enough -RUN apt-get update && apt-get dist-upgrade -y && rm -rf /var/lib/apt/lists/* - -# overwrite this with 'CMD []' in a dependent Dockerfile -CMD ["/bin/bash"] -``` - -#### 16.04 版本 +## Dockerfile -``` -FROM scratch -ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz / - -# a few minor docker-specific tweaks -# see https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap -RUN set -xe \ - \ -# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L40-L48 - && echo '#!/bin/sh' > /usr/sbin/policy-rc.d \ - && echo 'exit 101' >> /usr/sbin/policy-rc.d \ - && chmod +x /usr/sbin/policy-rc.d \ - \ -# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L54-L56 - && dpkg-divert --local --rename --add /sbin/initctl \ - && cp -a /usr/sbin/policy-rc.d /sbin/initctl \ - && sed -i 's/^exit.*/exit 0/' /sbin/initctl \ - \ -# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L71-L78 - && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \ - \ -# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L85-L105 - && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \ - && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \ - && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \ - \ -# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L109-L115 - && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \ - \ -# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L118-L130 - && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \ - \ -# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L134-L151 - && echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests - -# delete all the apt list files since they're big and get stale quickly -RUN rm -rf /var/lib/apt/lists/* -# this forces "apt-get update" in dependent images, which is also good - -# enable the universe -RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list - -# overwrite this with 'CMD []' in a dependent Dockerfile -CMD ["/bin/bash"] -``` +请到 https://github.com/docker-library/docs/tree/master/ubuntu 查看。 diff --git a/appendix/repo/wordpress.md b/appendix/repo/wordpress.md index 1250db51e..2e571c491 100644 --- a/appendix/repo/wordpress.md +++ b/appendix/repo/wordpress.md @@ -1,117 +1,25 @@ -## [WordPress](https://hub.docker.com/_/wordpress/) +# [WordPress](https://hub.docker.com/_/wordpress/) -### 基本信息 -[WordPress](https://en.wikipedia.org/wiki/WordPress) 是开源的 Blog 和内容管理系统框架,它基于 PhP 和 MySQL。 +## 基本信息 -该仓库位于 https://hub.docker.com/_/wordpress/,提供了 WordPress 4.x 版本的镜像。 +[WordPress](https://en.wikipedia.org/wiki/WordPress) 是开源的 Blog 和内容管理系统框架,它基于 PHP 和 MySQL。 -### 使用方法 -启动容器需要 MySQL 的支持,默认端口为 `80`。 - -``` -$ docker run --name some-wordpress --link some-mysql:mysql -d wordpress -``` -启动 WordPress 容器时可以指定的一些环境参数包括: - -* `-e WORDPRESS_DB_USER=...` 缺省为 “root” -* `-e WORDPRESS_DB_PASSWORD=...` 缺省为连接 mysql 容器的环境变量 `MYSQL_ROOT_PASSWORD` 的值 -* `-e WORDPRESS_DB_NAME=...` 缺省为 “wordpress” -* `-e WORDPRESS_AUTH_KEY=...`, `-e WORDPRESS_SECURE_AUTH_KEY=...`, `-e WORDPRESS_LOGGED_IN_KEY=...`, `-e WORDPRESS_NONCE_KEY=...`, `-e WORDPRESS_AUTH_SALT=...`, `-e WORDPRESS_SECURE_AUTH_SALT=...`, `-e WORDPRESS_LOGGED_IN_SALT=...`, `-e WORDPRESS_NONCE_SALT=...` 缺省为随机 sha1 串 - -### Dockerfile -#### 4.0 版本 -``` -FROM debian:wheezy - -RUN apt-get update && apt-get install -y \ - apache2 \ - curl \ - libapache2-mod-php5 \ - php5-curl \ - php5-gd \ - php5-mysql \ - rsync \ - wget \ - && rm -rf /var/lib/apt/lists/* -RUN a2enmod rewrite - -# copy a few things from apache's init script that it requires to be setup -ENV APACHE_CONFDIR /etc/apache2 -ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars -# and then a few more from $APACHE_CONFDIR/envvars itself -ENV APACHE_RUN_USER www-data -ENV APACHE_RUN_GROUP www-data -ENV APACHE_RUN_DIR /var/run/apache2 -ENV APACHE_PID_FILE $APACHE_RUN_DIR/apache2.pid -ENV APACHE_LOCK_DIR /var/lock/apache2 -ENV APACHE_LOG_DIR /var/log/apache2 -ENV LANG C -RUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIR - -# make CustomLog (access log) go to stdout instead of files -# and ErrorLog to stderr -RUN find "$APACHE_CONFDIR" -type f -exec sed -ri ' \ - s!^(\s*CustomLog)\s+\S+!\1 /proc/self/fd/1!g; \ - s!^(\s*ErrorLog)\s+\S+!\1 /proc/self/fd/2!g; \ -' '{}' ';' +该仓库位于 `https://hub.docker.com/_/wordpress/` ,提供了 WordPress 4.x ~ 5.x 版本的镜像。 -RUN rm -rf /var/www/html && mkdir /var/www/html -VOLUME /var/www/html -WORKDIR /var/www/html +## 使用方法 -ENV WORDPRESS_VERSION 4.0.0 -ENV WORDPRESS_UPSTREAM_VERSION 4.0 - -# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress -RUN curl -SL http://wordpress.org/wordpress-${WORDPRESS_UPSTREAM_VERSION}.tar.gz | tar -xzC /usr/src/ - -COPY docker-apache.conf /etc/apache2/sites-available/wordpress -RUN a2dissite 000-default && a2ensite wordpress - -COPY docker-entrypoint.sh /entrypoint.sh - -ENTRYPOINT ["/entrypoint.sh"] -EXPOSE 80 -CMD ["apache2", "-DFOREGROUND"] -``` +启动容器需要 MySQL 的支持,默认端口为 `80`。 -#### 4.5 版本 +```bash +$ docker run --name some-wordpress --link some-mysql:mysql -d wordpress ``` -FROM php:5.6-apache - -RUN a2enmod rewrite expires - -# install the PHP extensions we need -RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* \ - && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ - && docker-php-ext-install gd mysqli opcache - -# set recommended PHP.ini settings -# see https://secure.php.net/manual/en/opcache.installation.php -RUN { \ - echo 'opcache.memory_consumption=128'; \ - echo 'opcache.interned_strings_buffer=8'; \ - echo 'opcache.max_accelerated_files=4000'; \ - echo 'opcache.revalidate_freq=60'; \ - echo 'opcache.fast_shutdown=1'; \ - echo 'opcache.enable_cli=1'; \ - } > /usr/local/etc/php/conf.d/opcache-recommended.ini - -VOLUME /var/www/html -ENV WORDPRESS_VERSION 4.5.3 -ENV WORDPRESS_SHA1 835b68748dae5a9d31c059313cd0150f03a49269 +启动 WordPress 容器时可以指定的一些环境变量包括: -# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress -RUN curl -o wordpress.tar.gz -SL https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz \ - && echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c - \ - && tar -xzf wordpress.tar.gz -C /usr/src/ \ - && rm wordpress.tar.gz \ - && chown -R www-data:www-data /usr/src/wordpress +* `WORDPRESS_DB_USER` 缺省为 `root` +* `WORDPRESS_DB_PASSWORD` 缺省为连接 mysql 容器的环境变量 `MYSQL_ROOT_PASSWORD` 的值 +* `WORDPRESS_DB_NAME` 缺省为 `wordpress` -COPY docker-entrypoint.sh /entrypoint.sh +## Dockerfile -# grr, ENTRYPOINT resets CMD now -ENTRYPOINT ["/entrypoint.sh"] -CMD ["apache2-foreground"] -``` \ No newline at end of file +请到 https://github.com/docker-library/docs/tree/master/wordpress 查看。 diff --git a/appendix/resources.md b/appendix/resources.md new file mode 100644 index 000000000..9694d0495 --- /dev/null +++ b/appendix/resources.md @@ -0,0 +1,28 @@ +# 资源链接 + +## 官方网站 + +* Docker 官方主页:https://www.docker.com +* Docker 官方博客:https://www.docker.com/blog/ +* Docker 官方文档:https://docs.docker.com/ +* Docker Hub:https://hub.docker.com +* Docker 的源代码仓库:https://github.com/moby/moby +* Docker 路线图 https://github.com/docker/roadmap/projects +* Docker 发布版本历史:https://docs.docker.com/release-notes/ +* Docker 常见问题:https://docs.docker.com/engine/faq/ +* Docker 远端应用 API:https://docs.docker.com/develop/sdk/ + +## 实践参考 + +* Dockerfile 参考:https://docs.docker.com/engine/reference/builder/ +* Dockerfile 最佳实践:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/ + +## 技术交流 + +* Docker 邮件列表: https://groups.google.com/forum/#!forum/docker-user +* Docker 的 IRC 频道:https://chat.freenode.net#docker +* Docker 的 Twitter 主页:https://twitter.com/docker + +## 其它 + +* Docker 的 StackOverflow 问答主页:https://stackoverflow.com/search?q=docker diff --git a/appendix/resources/README.md b/appendix/resources/README.md deleted file mode 100644 index 3a03d7490..000000000 --- a/appendix/resources/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# 资源链接 - -## 官方网站 -* Docker 官方主页: https://www.docker.com -* Docker 官方博客: https://blog.docker.com/ -* Docker 官方文档: https://docs.docker.com/ -* Docker Hub: https://hub.docker.com -* Docker 的源代码仓库: https://github.com/docker/docker -* Docker 发布版本历史:https://docs.docker.com/release-notes/ -* Docker 常见问题:https://docs.docker.com/engine/faq/ -* Docker 远端应用 API: https://docs.docker.com/reference/api/docker_remote_api/ - -## 实践参考 -* Dockerfile 参考:https://docs.docker.com/reference/builder/ -* Dockerfile 最佳实践:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/ - -## 技术交流 -* Docker 邮件列表: https://groups.google.com/forum/#!forum/docker-user -* Docker 的 IRC 频道: https://chat.freenode.net#docker -* Docker 的 Twitter 主页: https://twitter.com/docker - -## 其它 -* Docker 的 StackOverflow 问答主页: https://stackoverflow.com/search?q=docker \ No newline at end of file diff --git a/appendix_command/README.md b/appendix_command/README.md deleted file mode 100644 index 2e69ca1bd..000000000 --- a/appendix_command/README.md +++ /dev/null @@ -1,126 +0,0 @@ -# Docker命令查询 - -## 基本语法 -Docker 命令有两大类,客户端命令和服务端命令。前者是主要的操作接口,后者用来启动 Docker daemon。 - -* 客户端命令:基本命令格式为 `docker [OPTIONS] COMMAND [arg...]`; -* 服务端命令:基本命令格式为 `docker daemon [OPTIONS]`。 - -可以通过 `man docker` 或 `docker help` 来查看这些命令。 - -## 客户端命令选项 - -* --config="":指定客户端配置文件,默认为 `/.docker`; -* -D=true|false:是否使用 debug 模式。默认不开启; -* -H, --host=[]:指定命令对应 Docker daemon 的监听接口,可以为 unix 套接字(unix:///path/to/socket),文件句柄(fd://socketfd)或 tcp 套接字(tcp://[host[:port]]),默认为 unix:///var/run/docker.sock; -* -l, --log-level="debug|info|warn|error|fatal":指定日志输出级别; -* --tls=true|false:是否对 Docker daemon 启用 TLS 安全机制,默认为否; -* --tlscacert= /.docker/ca.pem:TLS CA 签名的可信证书文件路径; -* --tlscert= /.docker/cert.pem:TLS 可信证书文件路径; -* --tlscert= /.docker/key.pem:TLS 密钥文件路径; -* --tlsverify=true|false:启用 TLS 校验,默认为否。 - -## daemon 命令选项 -* --api-cors-header="":CORS 头部域,默认不允许 CORS,要允许任意的跨域访问,可以指定为 “*”; -* --authorization-plugin="":载入认证的插件; -* -b="":将容器挂载到一个已存在的网桥上。指定为 'none' 时则禁用容器的网络,与 --bip 选项互斥; -* --bip="":让动态创建的 docker0 网桥采用给定的 CIDR 地址; 与 -b 选项互斥; -* --cgroup-parent="":指定 cgroup 的父组,默认 fs cgroup 驱动为 `/docker`,systemd cgroup 驱动为 `system.slice`; -* --cluster-store="":构成集群(如 Swarm)时,集群键值数据库服务地址; -* --cluster-advertise="":构成集群时,自身的被访问地址,可以为 `host:port` 或 `interface:port`; -* --cluster-store-opt="":构成集群时,键值数据库的配置选项; -* --config-file="/etc/docker/daemon.json":daemon 配置文件路径; -* --containerd="":containerd 文件的路径; -* -D, --debug=true|false:是否使用 Debug 模式。缺省为 false; -* --default-gateway="":容器的 IPv4 网关地址,必须在网桥的子网段内; -* --default-gateway-v6="":容器的 IPv6 网关地址; -* --default-ulimit=[]:默认的 ulimit 值; -* --disable-legacy-registry=true|false:是否允许访问旧版本的镜像仓库服务器; -* --dns="":指定容器使用的 DNS 服务器地址; -* --dns-opt="":DNS 选项; -* --dns-search=[]:DNS 搜索域; -* --exec-opt=[]:运行时的执行选项; -* --exec-root="":容器执行状态文件的根路径,默认为 `/var/run/docker`; -* --fixed-cidr="":限定分配 IPv4 地址范围; -* --fixed-cidr-v6="":限定分配 IPv6 地址范围; -* -G, --group="":分配给 unix 套接字的组,默认为 `docker`; -* -g, --graph="":Docker 运行时的根路径,默认为 `/var/lib/docker`; -* -H, --host=[]:指定命令对应 Docker daemon 的监听接口,可以为 unix 套接字(unix:///path/to/socket),文件句柄(fd://socketfd)或 tcp 套接字(tcp://[host[:port]]),默认为 unix:///var/run/docker.sock; -* --icc=true|false:是否启用容器间以及跟 daemon 所在主机的通信。默认为 true。 -* --insecure-registry=[]:允许访问给定的非安全仓库服务; -* --ip="":绑定容器端口时候的默认 IP 地址。缺省为 0.0.0.0; -* --ip-forward=true|false:是否检查启动在 Docker 主机上的启用 IP 转发服务,默认开启。注意关闭该选项将不对系统转发能力进行任何检查修改; -* --ip-masq=true|false:是否进行地址伪装,用于容器访问外部网络,默认开启; -* --iptables=true|false:是否允许 Docker 添加 iptables 规则。缺省为 true; -* --ipv6=true|false:是否启用 IPv6 支持,默认关闭; -* -l, --log-level="debug|info|warn|error|fatal":指定日志输出级别; -* --label="[]":添加指定的键值对标注; -* --log-driver="json-file|syslog|journald|gelf|fluentd|awslogs|splunk|etwlogs|gcplogs|none":指定日志后端驱动,默认为 json-file; -* --log-opt=[]:日志后端的选项; -* --mtu=VALUE:指定容器网络的 mtu; -* -p="":指定 daemon 的 PID 文件路径。缺省为 `/var/run/docker.pid`; -* --raw-logs:输出原始,未加色彩的日志信息; -* --registry-mirror=://:指定 `docker pull` 时使用的注册服务器镜像地址; -* -s, --storage-driver="":指定使用给定的存储后端; -* --selinux-enabled=true|false:是否启用 SELinux 支持。缺省值为 false。SELinux 目前尚不支持 overlay 存储驱动; -* --storage-opt=[]:驱动后端选项; -* --tls=true|false:是否对 Docker daemon 启用 TLS 安全机制,默认为否; -* --tlscacert= /.docker/ca.pem:TLS CA 签名的可信证书文件路径; -* --tlscert= /.docker/cert.pem:TLS 可信证书文件路径; -* --tlscert= /.docker/key.pem:TLS 密钥文件路径; -* --tlsverify=true|false:启用 TLS 校验,默认为否; -* --userland-proxy=true|false:是否使用用户态代理来实现容器间和出容器的回环通信,默认为 true; -* --userns-remap=default|uid:gid|user:group|user|uid:指定容器的用户命名空间,默认是创建新的 UID 和 GID 映射到容器内进程。 - -## 子命令 - -可以通过 `man docker-COMMAND` 来查看这些命令的具体用法。 - -* attach:依附到一个正在运行的容器中; -* build:从一个 Dockerfile 创建一个镜像; -* commit:从一个容器的修改中创建一个新的镜像; -* cp:在容器和本地宿主系统之间复制文件中; -* create:创建一个新容器,但并不运行它; -* diff:检查一个容器文件系统的修改; -* events:从服务端获取实时的事件; -* exec:在运行的容器内执行命令; -* export:导出容器内容为一个 tar 包; -* history:显示一个镜像的历史信息; -* images:列出存在的镜像; -* import:导入一个文件(典型为 tar 包)路径或目录来创建一个本地镜像; -* info:显示一些相关的系统信息; -* inspect:显示一个容器的具体配置信息; -* kill:关闭一个运行中的容器 (包括进程和所有相关资源); -* load:从一个 tar 包中加载一个镜像; -* login:注册或登录到一个 Docker 的仓库服务器; -* logout:从 Docker 的仓库服务器登出; -* logs:获取容器的 log 信息; -* network:管理 Docker 的网络,包括查看、创建、删除、挂载、卸载等; -* node:管理 swarm 集群中的节点,包括查看、更新、删除、提升/取消管理节点等; -* pause:暂停一个容器中的所有进程; -* port:查找一个 nat 到一个私有网口的公共口; -* ps:列出主机上的容器; -* pull:从一个Docker的仓库服务器下拉一个镜像或仓库; -* push:将一个镜像或者仓库推送到一个 Docker 的注册服务器; -* rename:重命名一个容器; -* restart:重启一个运行中的容器; -* rm:删除给定的若干个容器; -* rmi:删除给定的若干个镜像; -* run:创建一个新容器,并在其中运行给定命令; -* save:保存一个镜像为 tar 包文件; -* search:在 Docker index 中搜索一个镜像; -* service:管理 Docker 所启动的应用服务,包括创建、更新、删除等; -* start:启动一个容器; -* stats:输出(一个或多个)容器的资源使用统计信息; -* stop:终止一个运行中的容器; -* swarm:管理 Docker swarm 集群,包括创建、加入、退出、更新等; -* tag:为一个镜像打标签; -* top:查看一个容器中的正在运行的进程信息; -* unpause:将一个容器内所有的进程从暂停状态中恢复; -* update:更新指定的若干容器的配置信息; -* version:输出 Docker 的版本信息; -* volume:管理 Docker volume,包括查看、创建、删除等; -* wait:阻塞直到一个容器终止,然后输出它的退出符。 - -## 一张图总结 Docker 的命令 -![命令周期](../_images/cmd_logic.png) diff --git a/archive/README.md b/archive/README.md new file mode 100644 index 000000000..5f748758a --- /dev/null +++ b/archive/README.md @@ -0,0 +1,7 @@ +# 归档项目 + +以下项目不被官方支持或内容陈旧,将在下一版本中删除。 + +* Docker Machine +* Mesos +* Docker Swarm diff --git a/basic_concept/README.md b/basic_concept/README.md index a79c6ec50..dec8e471b 100644 --- a/basic_concept/README.md +++ b/basic_concept/README.md @@ -1,8 +1,7 @@ # 基本概念 Docker 包括三个基本概念 -* 镜像(Image) -* 容器(Container) -* 仓库(Repository) +* 镜像(`Image`) +* 容器(`Container`) +* 仓库(`Repository`) 理解了这三个概念,就理解了 Docker 的整个生命周期。 - diff --git a/basic_concept/container.md b/basic_concept/container.md index 40661102f..cd1dd441b 100644 --- a/basic_concept/container.md +++ b/basic_concept/container.md @@ -1,13 +1,13 @@ -## Docker 容器 +# Docker 容器 -镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的`类`和`实例`一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。 +镜像(`Image`)和容器(`Container`)的关系,就像是面向对象程序设计中的 `类` 和 `实例` 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。 -容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 [命名空间](https://en.wikipedia.org/wiki/Linux_namespaces)。因此容器可以拥有自己的 `root` 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会把容器和虚拟机搞混。 +容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 [命名空间](https://en.wikipedia.org/wiki/Linux_namespaces)。因此容器可以拥有自己的 `root` 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。 -前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为**容器存储层**。 +前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为 **容器存储层**。 容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。 -按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 [数据卷(Volume)](https://docs.docker.com/engine/tutorials/dockervolumes/)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。 +按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 [数据卷(Volume)](../data_management/volume.md)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。 -数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器可以随意删除、重新 `run`,数据却不会丢失。 +数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。 diff --git a/basic_concept/image.md b/basic_concept/image.md index 9a1da204f..5718a1556 100644 --- a/basic_concept/image.md +++ b/basic_concept/image.md @@ -1,10 +1,10 @@ -## Docker 镜像 +# Docker 镜像 -我们都知道,操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 `root` 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 `root` 文件系统。比如官方镜像 `ubuntu:14.04` 就包含了完整的一套 Ubuntu 14.04 最小系统的 `root` 文件系统。 +我们都知道,操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 `root` 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 `root` 文件系统。比如官方镜像 `ubuntu:18.04` 就包含了完整的一套 Ubuntu 18.04 最小系统的 `root` 文件系统。 Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。 -### 分层存储 +## 分层存储 因为镜像包含操作系统完整的 `root` 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。 diff --git a/basic_concept/repository.md b/basic_concept/repository.md index cdfb602a9..c7c8d03c8 100644 --- a/basic_concept/repository.md +++ b/basic_concept/repository.md @@ -1,29 +1,29 @@ -## Docker Registry +# Docker Registry -镜像构建完成后,可以很容易的在当前宿主上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,[Docker Registry](https://docs.docker.com/registry/) 就是这样的服务。 +镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,[Docker Registry](../repository/registry.md) 就是这样的服务。 -一个 **Docker Registry** 中可以包含多个**仓库**(Repository);每个仓库可以包含多个**标签**(Tag);每个标签对应一个镜像。 +一个 **Docker Registry** 中可以包含多个 **仓库**(`Repository`);每个仓库可以包含多个 **标签**(`Tag`);每个标签对应一个镜像。 -一般而言,一个仓库包含的是同一个软件的不同版本的镜像,而标签则用于对应于软件的的不同版本。我们可以通过 `<仓库名>:<标签>` 的格式来指定具体是哪个版本的镜像。如果不给出标签,将以 `latest` 作为默认标签。 +通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 `<仓库名>:<标签>` 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 `latest` 作为默认标签。 -以 [Ubuntu 镜像](https://hub.docker.com/_/ubuntu/) 为例,`ubuntu` 是仓库的名字,其内包含有不同的版本标签,如,`14.04`, `16.04`。我们可以通过 `ubuntu:14.04`,或者 `ubuntu:16.04` 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 `ubuntu`,那将视为 `ubuntu:latest`。 +以 [Ubuntu 镜像](https://hub.docker.com/_/ubuntu) 为例,`ubuntu` 是仓库的名字,其内包含有不同的版本标签,如,`16.04`, `18.04`。我们可以通过 `ubuntu:16.04`,或者 `ubuntu:18.04` 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 `ubuntu`,那将视为 `ubuntu:latest`。 仓库名经常以 *两段式路径* 形式出现,比如 `jwilder/nginx-proxy`,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。 -### Docker Registry 公开服务 +## Docker Registry 公开服务 Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。 -最常使用的 Registry 公开服务是官方的 [Docker Hub](https://hub.docker.com/),这也是默认的 Registry,并拥有大量的高质量的官方镜像。除此以外,还有 [CoreOS](https://coreos.com/) 的 [Quay.io](https://quay.io/repository/),CoreOS 相关的镜像存储在这里;Google 的 [Google Container Registry](https://cloud.google.com/container-registry/),[Kubernetes](http://kubernetes.io/) 的镜像使用的就是这个服务。 +最常使用的 Registry 公开服务是官方的 [Docker Hub](https://hub.docker.com/),这也是默认的 Registry,并拥有大量的高质量的官方镜像。除此以外,还有 Red Hat 的 [Quay.io](https://quay.io/repository/);Google 的 [Google Container Registry](https://cloud.google.com/container-registry/),[Kubernetes](https://kubernetes.io/) 的镜像使用的就是这个服务。 -由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为**加速器**。常见的有 [阿里云加速器](https://cr.console.aliyun.com/#/accelerator)、[DaoCloud 加速器](https://www.daocloud.io/mirror#accelerator-doc)、[灵雀云加速器](http://docs.alauda.cn/feature/accelerator.html)等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从官方网站下载速度会提高很多。在后面的章节中会有进一步如何配置加速器的讲解。 +由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(`Registry Mirror`),这些镜像服务被称为 **加速器**。常见的有 [阿里云加速器](https://cr.console.aliyun.com/#/accelerator)、[DaoCloud 加速器](https://www.daocloud.io/mirror#accelerator-doc) 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。在 [安装 Docker](../install/mirror.md) 一节中有详细的配置方法。 -国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [时速云镜像仓库](https://hub.tenxcloud.com/)、[网易云镜像服务](https://c.163.com/hub#/m/library/)、[DaoCloud 镜像市场](https://hub.daocloud.io/)、[阿里云镜像库](https://cr.console.aliyun.com)等。 +国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [网易云镜像服务](https://c.163.com/hub#/m/library/)、[DaoCloud 镜像市场](https://hub.daocloud.io/)、[阿里云镜像库](https://cr.console.aliyun.com) 等。 -### 私有 Docker Registry +## 私有 Docker Registry -除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 [Docker Registry 镜像](https://hub.docker.com/_/registry/),可以直接使用做为私有 Registry 服务。在后续的相关章节中,会有进一步的搭建私有 Registry 服务的讲解。 +除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 [Docker Registry](https://hub.docker.com/_/registry/) 镜像,可以直接使用做为私有 Registry 服务。在 [私有仓库](../repository/registry.md) 一节中,会有进一步的搭建私有 Registry 服务的讲解。 开源的 Docker Registry 镜像只提供了 [Docker Registry API](https://docs.docker.com/registry/spec/api/) 的服务端实现,足以支持 `docker` 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。在官方的商业化版本 [Docker Trusted Registry](https://docs.docker.com/datacenter/dtr/2.0/) 中,提供了这些高级功能。 -除了官方的 Docker Registry 外,还有第三方软件实现了 Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,[VMWare Harbor](http://vmware.github.io/harbor/index_cn.html) 和 [Sonatype Nexus](https://www.sonatype.com/docker)。 +除了官方的 Docker Registry 外,还有第三方软件实现了 Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,[Harbor](https://github.com/goharbor/harbor) 和 [Sonatype Nexus](../repository/nexus3_registry.md)。 diff --git a/book.json b/book.json index a776c7b74..95d0b6758 100644 --- a/book.json +++ b/book.json @@ -1,9 +1,18 @@ { "title": "Docker -- 从入门到实践", "author": "yeasy", + "language": "zh-hans", + "links": { + "sidebar": { + "GitHub": "https://github.com/yeasy/docker_practice" + } + }, "plugins": [ + "-livereload", "image-captions", - "github-buttons" + "github", + "page-treeview@2.9.8", + "editlink" ], "pluginsConfig": { "image-captions": { @@ -12,13 +21,17 @@ }, "caption": "图 _PAGE_LEVEL_._PAGE_IMAGE_NUMBER_ - _CAPTION_" }, - "github-buttons": { - "repo": "yeasy/docker_practice", - "types": [ - "star", - "watch" - ], - "size": "small" + "github": { + "url": "https://github.com/yeasy/docker_practice" + }, + "editlink": { + "base": "https://github.com/yeasy/docker_practice/blob/master/", + "label": "编辑本页" + }, + "page-treeview": { + "copyright": "Copyright © yeasy", + "minHeaderCount": "2", + "minHeaderDeep": "2" } } } diff --git a/buildx/README.md b/buildx/README.md new file mode 100644 index 000000000..1408b3bc8 --- /dev/null +++ b/buildx/README.md @@ -0,0 +1,5 @@ +# Docker Buildx + +Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 [Moby BuildKit](buildkit.md) 提供的功能。提供了与 docker build 相同的用户体验,并增加了许多新功能。 + +> 该功能仅适用于 Docker v19.03+ 版本 diff --git a/buildx/buildkit.md b/buildx/buildkit.md new file mode 100644 index 000000000..235e1e60c --- /dev/null +++ b/buildx/buildkit.md @@ -0,0 +1,152 @@ +# 使用 `BuildKit` 构建镜像 + +**BuildKit** 是下一代的镜像构建组件,在 https://github.com/moby/buildkit 开源。 + +**注意:如果您的镜像构建使用的是云服务商提供的镜像构建服务(腾讯云容器服务、阿里云容器服务等),由于上述服务提供商的 Docker 版本低于 18.09,BuildKit 无法使用,将造成镜像构建失败。建议使用 BuildKit 构建镜像时使用一个新的 Dockerfile 文件(例如 Dockerfile.buildkit)** + +**注意:docker-compose build 命令暂时不支持 BuildKit** + +目前,Docker Hub 自动构建已经支持 buildkit,具体请参考 https://github.com/docker-practice/docker-hub-buildx + +## `Dockerfile` 新增指令详解 + +启用 `BuildKit` 之后,我们可以使用下面几个新的 `Dockerfile` 指令来加快镜像构建。 + +### `RUN --mount=type=cache` + +目前,几乎所有的程序都会使用依赖管理工具,例如 `Go` 中的 `go mod`、`Node.js` 中的 `npm` 等等,当我们构建一个镜像时,往往会重复的从互联网中获取依赖包,难以缓存,大大降低了镜像的构建效率。 + +例如一个前端工程需要用到 `npm`: + +```docker +FROM node:alpine as builder + +WORKDIR /app + +COPY package.json /app/ + +RUN npm i --registry=https://registry.npm.taobao.org \ + && rm -rf ~/.npm + +COPY src /app/src + +RUN npm run build + +FROM nginx:alpine + +COPY --from=builder /app/dist /app/dist +``` + +使用多阶段构建,构建的镜像中只包含了目标文件夹 `dist`,但仍然存在一些问题,当 `package.json` 文件变动时,`RUN npm i && rm -rf ~/.npm` 这一层会重新执行,变更多次后,生成了大量的中间层镜像。 + +为解决这个问题,进一步的我们可以设想一个类似 **数据卷** 的功能,在镜像构建时把 `node_modules` 文件夹挂载上去,在构建完成后,这个 `node_modules` 文件夹会自动卸载,实际的镜像中并不包含 `node_modules` 这个文件夹,这样我们就省去了每次获取依赖的时间,大大增加了镜像构建效率,同时也避免了生成了大量的中间层镜像。 + +`BuildKit` 提供了 `RUN --mount=type=cache` 指令,可以实现上边的设想。 + +```docker +# syntax = docker/dockerfile:experimental +FROM node:alpine as builder + +WORKDIR /app + +COPY package.json /app/ + +RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \ + --mount=type=cache,target=/root/.npm,id=npm_cache \ + npm i --registry=https://registry.npm.taobao.org + +COPY src /app/src + +RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \ +# --mount=type=cache,target=/app/dist,id=my_app_dist,sharing=locked \ + npm run build + +FROM nginx:alpine + +# COPY --from=builder /app/dist /app/dist + +# 为了更直观的说明 from 和 source 指令,这里使用 RUN 指令 +RUN --mount=type=cache,target=/tmp/dist,from=builder,source=/app/dist \ + # --mount=type=cache,target/tmp/dist,from=my_app_dist,sharing=locked \ + mkdir -p /app/dist && cp -r /tmp/dist/* /app/dist +``` + +**由于 `BuildKit` 为实验特性,每个 `Dockerfile` 文件开头都必须加上如下指令** + +```docker +# syntax = docker/dockerfile:experimental +``` + +第一个 `RUN` 指令执行后,`id` 为 `my_app_npm_module` 的缓存文件夹挂载到了 `/app/node_modules` 文件夹中。多次执行也不会产生多个中间层镜像。 + +第二个 `RUN` 指令执行时需要用到 `node_modules` 文件夹,`node_modules` 已经挂载,命令也可以正确执行。 + +第三个 `RUN` 指令将上一阶段产生的文件复制到指定位置,`from` 指明缓存的来源,这里 `builder` 表示缓存来源于构建的第一阶段,`source` 指明缓存来源的文件夹。 + +上面的 `Dockerfile` 中 `--mount=type=cache,...` 中指令作用如下: + +|Option |Description| +|---------------------|-----------| +|`id` | `id` 设置一个标志,以便区分缓存。| +|`target` (必填项) | 缓存的挂载目标文件夹。| +|`ro`,`readonly` | 只读,缓存文件夹不能被写入。 | +|`sharing` | 有 `shared` `private` `locked` 值可供选择。`sharing` 设置当一个缓存被多次使用时的表现,由于 `BuildKit` 支持并行构建,当多个步骤使用同一缓存时(同一 `id`)会发生冲突。`shared` 表示多个步骤可以同时读写,`private` 表示当多个步骤使用同一缓存时,每个步骤使用不同的缓存,`locked` 表示当一个步骤完成释放缓存后,后一个步骤才能继续使用该缓存。| +|`from` | 缓存来源(构建阶段),不填写时为空文件夹。| +|`source` | 来源的文件夹路径。| + +### `RUN --mount=type=bind` + +该指令可以将一个镜像(或上一构建阶段)的文件挂载到指定位置。 + +```docker +# syntax = docker/dockerfile:experimental +RUN --mount=type=bind,from=php:alpine,source=/usr/local/bin/docker-php-entrypoint,target=/docker-php-entrypoint \ + cat /docker-php-entrypoint +``` + +### `RUN --mount=type=tmpfs` + +该指令可以将一个 `tmpfs` 文件系统挂载到指定位置。 + +```docker +# syntax = docker/dockerfile:experimental +RUN --mount=type=tmpfs,target=/temp \ + mount | grep /temp +``` + +### `RUN --mount=type=secret` + +该指令可以将一个文件(例如密钥)挂载到指定位置。 + +```docker +# syntax = docker/dockerfile:experimental +RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \ + cat /root/.aws/credentials +``` + +```bash +$ docker build -t test --secret id=aws,src=$HOME/.aws/credentials . +``` + +### `RUN --mount=type=ssh` + +该指令可以挂载 `ssh` 密钥。 + +```docker +# syntax = docker/dockerfile:experimental +FROM alpine +RUN apk add --no-cache openssh-client +RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts +RUN --mount=type=ssh ssh git@gitlab.com | tee /hello +``` + +```bash +$ eval $(ssh-agent) +$ ssh-add ~/.ssh/id_rsa +(Input your passphrase here) +$ docker build -t test --ssh default=$SSH_AUTH_SOCK . +``` + +## 官方文档 + +* https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md diff --git a/buildx/buildx.md b/buildx/buildx.md new file mode 100644 index 000000000..ee7ec45c8 --- /dev/null +++ b/buildx/buildx.md @@ -0,0 +1,21 @@ +# 使用 Buildx 构建镜像 + +## 启用 Buildx + +`buildx` 命令属于实验特性,请参考 [开启实验特性](../install/experimental.md) 一节开启 Docker CLI 实验特性。 + +## 使用 + +你可以直接使用 `docker buildx build` 命令构建镜像。 + +```bash +$ docker buildx build . +[+] Building 8.4s (23/32) + => ... +``` + +Buildx 使用 [BuildKit 引擎](buildkit.md) 进行构建,支持许多新的功能,具体参考 [Buildkit](buildkit.md) 一节。 + +## 官方文档 + +* https://docs.docker.com/engine/reference/commandline/buildx/ diff --git a/buildx/multi-arch-images.md b/buildx/multi-arch-images.md new file mode 100644 index 000000000..79b66aef2 --- /dev/null +++ b/buildx/multi-arch-images.md @@ -0,0 +1,68 @@ +# 使用 buildx 构建多种系统架构支持的 Docker 镜像 + +在之前的版本中构建多种系统架构支持的 Docker 镜像,要想使用统一的名字必须使用 [`$ docker manifest`](../image/manifest.md) 命令。 + +在 Docker 19.03+ 版本中可以使用 `$ docker buildx build` 命令使用 `BuildKit` 构建镜像。该命令支持 `--platform` 参数可以同时构建支持多种系统架构的 Docker 镜像,大大简化了构建步骤。 + +## 新建 `builder` 实例 + +Docker for Linux 不支持构建 `arm` 架构镜像,我们可以运行一个新的容器让其支持该特性,Docker 桌面版无需进行此项设置。 + +```bash +$ docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3 +``` + +由于 Docker 默认的 `builder` 实例不支持同时指定多个 `--platform`,我们必须首先创建一个新的 `builder` 实例。同时由于国内拉取镜像较缓慢,我们可以使用配置了 [镜像加速地址](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) 的 [`dockerpracticesig/buildkit:master`](https://github.com/docker-practice/buildx) 镜像替换官方镜像。 + +> 如果你有私有的镜像加速器,可以基于 https://github.com/docker-practice/buildx 构建自己的 buildkit 镜像并使用它。 + +```bash +# 适用于国内环境 +$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master + +# 适用于腾讯云环境(腾讯云主机、coding.net 持续集成) +$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master-tencent + +# $ docker buildx create --name mybuilder --driver docker-container + +$ docker buildx use mybuilder +``` + +## 构建镜像 + +新建 Dockerfile 文件。 + +```docker +FROM --platform=$TARGETPLATFORM alpine + +RUN uname -a > /os.txt + +CMD cat /os.txt +``` + +使用 `$ docker buildx build` 命令构建镜像,注意将 `myusername` 替换为自己的 Docker Hub 用户名。 + +`--push` 参数表示将构建好的镜像推送到 Docker 仓库。 + +```bash +$ docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t myusername/hello . --push + +# 查看镜像信息 +$ docker buildx imagetools inspect myusername/hello +``` + +在不同架构运行该镜像,可以得到该架构的信息。 + +```bash +# arm +$ docker run -it --rm myusername/hello +Linux buildkitsandbox 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 armv7l Linux + +# arm64 +$ docker run -it --rm myusername/hello +Linux buildkitsandbox 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 aarch64 Linux + +# amd64 +$ docker run -it --rm myusername/hello +Linux buildkitsandbox 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 Linux +``` diff --git a/cases/README.md b/cases/README.md deleted file mode 100644 index 4f03d4b6b..000000000 --- a/cases/README.md +++ /dev/null @@ -1,2 +0,0 @@ -#实战案例 -介绍一些典型的应用场景和案例。 diff --git a/cases/ci/README.md b/cases/ci/README.md new file mode 100644 index 000000000..e304f68ec --- /dev/null +++ b/cases/ci/README.md @@ -0,0 +1,7 @@ +# CI/CD + +**持续集成(Continuous integration)** 是一种软件开发实践,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。 + +**持续部署(continuous deployment)** 是通过自动化的构建、测试和部署循环来快速交付高质量的产品。 + +与 `Jenkins` 不同的是,基于 Docker 的 CI/CD 每一步都运行在 Docker 容器中,所以理论上支持所有的编程语言。 diff --git a/cases/ci/actions/README.md b/cases/ci/actions/README.md new file mode 100644 index 000000000..204865208 --- /dev/null +++ b/cases/ci/actions/README.md @@ -0,0 +1,28 @@ +# GitHub Actions + +GitHub [Actions](https://github.com/features/actions) 是 GitHub 推出的一款 CI/CD 工具。 + +我们可以在每个 `job` 的 `step` 中使用 Docker 执行构建步骤。 + +```yaml +on: push + +name: CI + +jobs: + my-job: + name: Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + with: + fetch-depth: 2 + - name: run docker container + uses: docker://golang:alpine + with: + args: go version +``` + +## 参考资料 + +* [Actions Docs](https://docs.github.com/en/actions) diff --git a/cases/ci/drone/.env.example b/cases/ci/drone/.env.example new file mode 100644 index 000000000..8a6f5dd37 --- /dev/null +++ b/cases/ci/drone/.env.example @@ -0,0 +1,6 @@ +DRONE_SERVER_HOST= +DRONE_SERVER_PROTO= +DRONE_RPC_SECRET= +HOSTNAME= +DRONE_GITHUB_CLIENT_ID= +DRONE_GITHUB_CLIENT_SECRET= diff --git a/cases/ci/drone/.gitignore b/cases/ci/drone/.gitignore new file mode 100644 index 000000000..e8244fed3 --- /dev/null +++ b/cases/ci/drone/.gitignore @@ -0,0 +1,2 @@ +.env +ssl/* diff --git a/cases/ci/drone/README.md b/cases/ci/drone/README.md new file mode 100644 index 000000000..69271c39a --- /dev/null +++ b/cases/ci/drone/README.md @@ -0,0 +1,99 @@ +# Drone + +基于 `Docker` 的 `CI/CD` 工具 `Drone` 所有编译、测试的流程都在 `Docker` 容器中进行。 + +开发者只需在项目中包含 `.drone.yml` 文件,将代码推送到 git 仓库,`Drone` 就能够自动化的进行编译、测试、发布。 + +本小节以 `GitHub` + `Drone` 来演示 `Drone` 的工作流程。当然在实际开发过程中,你的代码也许不在 GitHub 托管,那么你可以尝试使用 `Gogs` + `Drone` 来进行 `CI/CD`。 + +## Drone 关联项目 + +在 Github 新建一个名为 `drone-demo` 的仓库。 + +打开我们已经 [部署好的 Drone 网站](install.md) 或者 [Drone Cloud](https://cloud.drone.io),使用 GitHub 账号登录,在界面中关联刚刚新建的 `drone-demo` 仓库。 + +## 编写项目源代码 + +初始化一个 git 仓库 + +```bash +$ mkdir drone-demo + +$ cd drone-demo + +$ git init + +$ git remote add origin git@github.com:username/drone-demo.git +``` + +这里以一个简单的 `Go` 程序为例,该程序输出 `Hello World!` + +编写 `app.go` 文件 + +```go +package main + +import "fmt" + +func main(){ + fmt.Printf("Hello World!\n"); +} +``` + +编写 `.drone.yml` 文件 + +```yaml +kind: pipeline +type: docker +name: build +steps: +- name: build + image: golang:alpine + pull: if-not-exists # always never + environment: + KEY: VALUE + commands: + - echo $KEY + - pwd + - ls + - CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . + - ./app + +trigger: + branch: + - master +``` + +现在目录结构如下 + +```bash +. +├── .drone.yml +└── app.go +``` + +## 推送项目源代码到 GitHub + +```bash +$ git add . + +$ git commit -m "test drone ci" + +$ git push origin master +``` + +## 查看项目构建过程及结果 + +打开我们部署好的 `Drone` 网站或者 Drone Cloud,即可看到构建结果。 + +![](_images/drone-build.png) + +当然我们也可以把构建结果上传到 GitHub,Docker Registry,云服务商提供的对象存储,或者生产环境中。 + +本书 GitBook 也使用 Drone 进行 CI/CD,具体配置信息请查看本书根目录 [`.drone.yml`](https://github.com/yeasy/docker_practice/blob/master/.drone.yml) 文件。 + +## 参考链接 + +* [Drone Github](https://github.com/drone/drone) +* [Drone 文档](https://docs.drone.io/) +* [Drone 示例](https://github.com/docker-practice/drone-demo) diff --git a/cases/ci/drone/_images/drone-build.png b/cases/ci/drone/_images/drone-build.png new file mode 100644 index 000000000..0c6c00961 Binary files /dev/null and b/cases/ci/drone/_images/drone-build.png differ diff --git a/cases/ci/drone/demo/.drone.yml b/cases/ci/drone/demo/.drone.yml new file mode 100644 index 000000000..f6c15aaf5 --- /dev/null +++ b/cases/ci/drone/demo/.drone.yml @@ -0,0 +1,19 @@ +kind: pipeline +type: docker +name: build +steps: +- name: build + image: golang:alpine + pull: if-not-exists # always never + environment: + KEY: VALUE + commands: + - echo $KEY + - pwd + - ls + - CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . + - ./app + +trigger: + branch: + - master diff --git a/cases/ci/drone/demo/README.md b/cases/ci/drone/demo/README.md new file mode 100644 index 000000000..7ab981271 --- /dev/null +++ b/cases/ci/drone/demo/README.md @@ -0,0 +1 @@ +# Drone Demo diff --git a/cases/ci/drone/demo/app.go b/cases/ci/drone/demo/app.go new file mode 100644 index 000000000..18f67bdf7 --- /dev/null +++ b/cases/ci/drone/demo/app.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main(){ + fmt.Printf("Hello World!\n"); +} diff --git a/cases/ci/drone/docker-compose.yml b/cases/ci/drone/docker-compose.yml new file mode 100644 index 000000000..8ef416bad --- /dev/null +++ b/cases/ci/drone/docker-compose.yml @@ -0,0 +1,39 @@ +version: '3' + +services: + + drone-server: + image: drone/drone:1 + ports: + - 443:443 + - 80:80 + volumes: + - drone-data:/data:rw + - ./ssl:/etc/certs + restart: always + environment: + - DRONE_AGENTS_ENABLED=true + - DRONE_SERVER_HOST=${DRONE_SERVER_HOST:-drone.domain.com} + - DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO:-https} + - DRONE_RPC_SECRET=${DRONE_RPC_SECRET:-secret} + - DRONE_GITHUB_SERVER=https://github.com + - DRONE_GITHUB_CLIENT_ID=${DRONE_GITHUB_CLIENT_ID} + - DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET} + + drone-agent: + image: drone/drone-runner-docker:1 + restart: always + depends_on: + - drone-server + volumes: + - /var/run/docker.sock:/var/run/docker.sock:rw + environment: + - DRONE_RPC_PROTO=http + - DRONE_RPC_HOST=drone-server + - DRONE_RPC_SECRET=${DRONE_RPC_SECRET:-secret} + - DRONE_RUNNER_NAME=${HOSTNAME:-demo} + - DRONE_RUNNER_CAPACITY=2 + dns: 114.114.114.114 + +volumes: + drone-data: diff --git a/cases/ci/drone/install.md b/cases/ci/drone/install.md new file mode 100644 index 000000000..3d94ee5c1 --- /dev/null +++ b/cases/ci/drone/install.md @@ -0,0 +1,87 @@ +# 部署 Drone + +## 要求 + +* 拥有公网 IP、域名 (如果你不满足要求,可以尝试在本地使用 Gogs + Drone) + +* 域名 SSL 证书 (目前国内有很多云服务商提供免费证书) + +* 熟悉 `Docker` 以及 `Docker Compose` + +* 熟悉 `Git` 基本命令 + +* 对 `CI/CD` 有一定了解 + +## 新建 GitHub 应用 + +登录 GitHub,在 https://github.com/settings/applications/new 新建一个应用。 + +![](https://docs.drone.io/screenshots/github_application_create.png) + +接下来查看这个应用的详情,记录 `Client ID` 和 `Client Secret`,之后配置 Drone 会用到。 + +## 配置 Drone + +我们通过使用 `Docker Compose` 来启动 `Drone`,编写 `docker-compose.yml` 文件。 + +```yaml +version: '3' + +services: + + drone-server: + image: drone/drone:1 + ports: + - 443:443 + - 80:80 + volumes: + - drone-data:/data:rw + - ./ssl:/etc/certs + restart: always + environment: + - DRONE_AGENTS_ENABLED=true + - DRONE_SERVER_HOST=${DRONE_SERVER_HOST:-https://drone.yeasy.com} + - DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO:-https} + - DRONE_RPC_SECRET=${DRONE_RPC_SECRET:-secret} + - DRONE_GITHUB_SERVER=https://github.com + - DRONE_GITHUB_CLIENT_ID=${DRONE_GITHUB_CLIENT_ID} + - DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET} + + drone-agent: + image: drone/drone-runner-docker:1 + restart: always + depends_on: + - drone-server + volumes: + - /var/run/docker.sock:/var/run/docker.sock:rw + environment: + - DRONE_RPC_PROTO=http + - DRONE_RPC_HOST=drone-server + - DRONE_RPC_SECRET=${DRONE_RPC_SECRET:-secret} + - DRONE_RUNNER_NAME=${HOSTNAME:-demo} + - DRONE_RUNNER_CAPACITY=2 + dns: 114.114.114.114 + +volumes: + drone-data: +``` + +新建 `.env` 文件,输入变量及其值 + +```bash +# 必填 服务器地址,例如 drone.domain.com +DRONE_SERVER_HOST= +DRONE_SERVER_PROTO=https +DRONE_RPC_SECRET=secret +HOSTNAME=demo +# 必填 在 GitHub 应用页面查看 +DRONE_GITHUB_CLIENT_ID= +# 必填 在 GitHub 应用页面查看 +DRONE_GITHUB_CLIENT_SECRET= +``` + +### 启动 Drone + +```bash +$ docker-compose up -d +``` diff --git a/cases/ci/travis/README.md b/cases/ci/travis/README.md new file mode 100644 index 000000000..792a5cee1 --- /dev/null +++ b/cases/ci/travis/README.md @@ -0,0 +1,47 @@ +# 在 Travis CI 中使用 Docker + +当代码提交到 GitHub 时,[Travis CI](https://travis-ci.com/) 会根据项目根目录 `.travis.yml` 文件设置的指令,执行一系列操作。 + +本小节介绍如何在 Travis CI 中使用 Docker 进行持续集成/持续部署(CI/CD)。这里以当代码提交到 GitHub 时自动构建 Docker 镜像并推送到 Docker Hub 为例进行介绍。 + +## 准备 + +首先登录 https://travis-ci.com/account/repositories 选择 GitHub 仓库,按照指引安装 GitHub App 来启用 GitHub 仓库构建。 + +在项目根目录新建一个 `Dockerfile` 文件。 + +```docker +FROM alpine + +RUN echo "Hello World" +``` + +新建 Travis CI 配置文件 `.travis.yml` 文件。 + +```yml +language: bash + +dist: xenial + +services: + - docker + +before_script: + # 登录到 docker hub + - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + +script: + # 这里编写测试代码的命令 + - echo "test code" + +after_success: + # 当代码测试通过后执行的命令 + - docker build -t username/alpine . + - docker push username/alpine +``` + +> 请提前在 Travis CI 仓库设置页面配置 `DOCKER_PASSWORD` `DOCKER_USERNAME` 变量 + +## 查看结果 + +将项目推送到 GitHub,登录 [Travis CI](https://travis-ci.com/) 查看构建详情。 diff --git a/cases/ci/travis/demo/.travis.yml b/cases/ci/travis/demo/.travis.yml new file mode 100644 index 000000000..a17054737 --- /dev/null +++ b/cases/ci/travis/demo/.travis.yml @@ -0,0 +1,16 @@ +language: bash + +dist: xenial + +services: + - docker + +before_script: + - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + +script: + - echo "test code" + +after_success: + - docker build -t username/alpine . + - docker push username/alpine diff --git a/cases/ci/travis/demo/Dockerfile b/cases/ci/travis/demo/Dockerfile new file mode 100644 index 000000000..a58cc938c --- /dev/null +++ b/cases/ci/travis/demo/Dockerfile @@ -0,0 +1,3 @@ +FROM alpine + +RUN echo "Hello World" diff --git a/cases/container_connect.md b/cases/container_connect.md deleted file mode 100644 index fc72123bb..000000000 --- a/cases/container_connect.md +++ /dev/null @@ -1,78 +0,0 @@ -## 多台物理主机之间的容器互联(暴露容器到真实网络中) -Docker 默认的桥接网卡是 docker0。它只会在本机桥接所有的容器网卡,举例来说容器的虚拟网卡在主机上看一般叫做 veth*** 而 Docker 只是把所有这些网卡桥接在一起,如下: -``` -[root@opnvz ~]# brctl show -bridge name bridge id STP enabled interfaces -docker0 8000.56847afe9799 no veth0889 - veth3c7b - veth4061 -``` -在容器中看到的地址一般是像下面这样的地址: -``` -root@ac6474aeb31d:~# ip a -1: lo: mtu 1500 qdisc noqueue state UNKNOWN group default - link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 - inet 127.0.0.1/8 scope host lo - valid_lft forever preferred_lft forever - inet6 ::1/128 scope host - valid_lft forever preferred_lft forever -11: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 - link/ether 4a:7d:68:da:09:cf brd ff:ff:ff:ff:ff:ff - inet 172.17.0.3/16 scope global eth0 - valid_lft forever preferred_lft forever - inet6 fe80::487d:68ff:feda:9cf/64 scope link - valid_lft forever preferred_lft forever -``` -这样就可以把这个网络看成是一个私有的网络,通过 nat 连接外网,如果要让外网连接到容器中,就需要做端口映射,即 -p 参数。 - -如果在企业内部应用,或者做多个物理主机的集群,可能需要将多个物理主机的容器组到一个物理网络中来,那么就需要将这个网桥桥接到我们指定的网卡上。 - -### 拓扑图 -主机 A 和主机 B 的网卡一都连着物理交换机的同一个 vlan 101,这样网桥一和网桥三就相当于在同一个物理网络中了,而容器一、容器三、容器四也在同一物理网络中了,他们之间可以相互通信,而且可以跟同一 vlan 中的其他物理机器互联。 -![物理拓扑图](../_images/container_connect_topology.png) - -### ubuntu 示例 -下面以 ubuntu 为例创建多个主机的容器联网: -创建自己的网桥,编辑 /etc/network/interface 文件 -``` -auto br0 -iface br0 inet static -address 192.168.7.31 -netmask 255.255.240.0 -gateway 192.168.7.254 -bridge_ports em1 -bridge_stp off -dns-nameservers 8.8.8.8 192.168.6.1 -``` -将 Docker 的默认网桥绑定到这个新建的 br0 上面,这样就将这台机器上容器绑定到 em1 这个网卡所对应的物理网络上了。 - -ubuntu 修改 /etc/default/docker 文件,添加最后一行内容 - -``` -# Docker Upstart and SysVinit configuration file -# Customize location of Docker binary (especially for development testing). -#DOCKER="/usr/local/bin/docker" -# Use DOCKER_OPTS to modify the daemon startup options. -#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4" - -# If you need Docker to use an HTTP proxy, it can also be specified here. -#export http_proxy="http://127.0.0.1:3128/" - -# This is also a handy place to tweak where Docker's temporary files go. -#export TMPDIR="/mnt/bigdrive/docker-tmp" - -DOCKER_OPTS="-b=br0" -``` - -在启动 Docker 的时候 使用 -b 参数 将容器绑定到物理网络上。重启 Docker 服务后,再进入容器可以看到它已经绑定到你的物理网络上了。 - -``` -root@ubuntudocker:~# docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -58b043aa05eb desk_hz:v1 "/startup.sh" 5 days ago Up 2 seconds 5900/tcp, 6080/tcp, 22/tcp yanlx -root@ubuntudocker:~# brctl show -bridge name bridge id STP enabled interfaces -br0 8000.7e6e617c8d53 no em1 - vethe6e5 -``` -这样就直接把容器暴露到物理网络上了,多台物理主机的容器也可以相互联网了。需要注意的是,这样就需要自己来保证容器的网络安全了。 diff --git a/cases/environment.md b/cases/environment.md deleted file mode 100644 index 30d1ad9c6..000000000 --- a/cases/environment.md +++ /dev/null @@ -1,14 +0,0 @@ -## 标准化开发测试和生产环境 -对于大部分企业来说,搭建 PaaS 既没有那个精力,也没那个必要,用 Docker 做个人的 sandbox 用处又小了点。 - -可以用 Docker 来标准化开发、测试、生产环境。 - - -![企业应用结构](../_images/enterprise_usage.png) - - -Docker 占用资源小,在一台 E5 128 G 内存的服务器上部署 100 个容器都绰绰有余,可以单独抽一个容器或者直接在宿主物理主机上部署 samba,利用 samba 的 home 分享方案将每个用户的 home 目录映射到开发中心和测试部门的 Windows 机器上。 - -针对某个项目组,由架构师搭建好一个标准的容器环境供项目组和测试部门使用,每个开发工程师可以拥有自己单独的容器,通过 `docker run -v` 将用户的 home 目录映射到容器中。需要提交测试时,只需要将代码移交给测试部门,然后分配一个容器使用 `-v` 加载测试部门的 home 目录启动即可。这样,在公司内部的开发、测试基本就统一了,不会出现开发部门提交的代码,测试部门部署不了的问题。 - -测试部门发布测试通过的报告后,架构师再一次检测容器环境,就可以直接交由部署工程师将代码和容器分别部署到生产环境中了。这种方式的部署横向性能的扩展性也极好。 diff --git a/cases/os/README.md b/cases/os/README.md new file mode 100644 index 000000000..2c2d839b4 --- /dev/null +++ b/cases/os/README.md @@ -0,0 +1,9 @@ +# 操作系统 + +目前常用的 Linux 发行版主要包括 `Debian/Ubuntu` 系列和 `CentOS/Fedora` 系列。 + +前者以自带软件包版本较新而出名;后者则宣称运行更稳定一些。选择哪个操作系统取决于读者的具体需求。 + +使用 Docker,读者只需要一个命令就能快速获取一个 Linux 发行版镜像,这是以往包括各种虚拟化技术都难以实现的。这些镜像一般都很精简,但是可以支持完整 Linux 系统的大部分功能。 + +本章将介绍如何使用 Docker 安装和使用 `Busybox`、`Alphine`、`Debian/Ubuntu`、`CentOS/Fedora` 等操作系统。 diff --git a/cases/os/_images/alpinelinux-logo.png b/cases/os/_images/alpinelinux-logo.png new file mode 100644 index 000000000..acfe2b19a Binary files /dev/null and b/cases/os/_images/alpinelinux-logo.png differ diff --git a/cases/os/_images/busybox-logo.png b/cases/os/_images/busybox-logo.png new file mode 100644 index 000000000..4d3126a52 Binary files /dev/null and b/cases/os/_images/busybox-logo.png differ diff --git a/cases/os/_images/centos-logo.png b/cases/os/_images/centos-logo.png new file mode 100644 index 000000000..fec4449ae Binary files /dev/null and b/cases/os/_images/centos-logo.png differ diff --git a/cases/os/_images/coreos-login.png b/cases/os/_images/coreos-login.png new file mode 100644 index 000000000..02142e7fe Binary files /dev/null and b/cases/os/_images/coreos-login.png differ diff --git a/cases/os/_images/coreos-logo.jpg b/cases/os/_images/coreos-logo.jpg new file mode 100644 index 000000000..dee6e9e3e Binary files /dev/null and b/cases/os/_images/coreos-logo.jpg differ diff --git a/cases/os/_images/coreos_crt.png b/cases/os/_images/coreos_crt.png new file mode 100644 index 000000000..0260b26ce Binary files /dev/null and b/cases/os/_images/coreos_crt.png differ diff --git a/cases/os/_images/coreos_list.png b/cases/os/_images/coreos_list.png new file mode 100644 index 000000000..9896b0af6 Binary files /dev/null and b/cases/os/_images/coreos_list.png differ diff --git a/cases/os/_images/coreos_run_ip.png b/cases/os/_images/coreos_run_ip.png new file mode 100644 index 000000000..ab121f487 Binary files /dev/null and b/cases/os/_images/coreos_run_ip.png differ diff --git a/cases/os/_images/debian-logo.png b/cases/os/_images/debian-logo.png new file mode 100644 index 000000000..1cfcc6529 Binary files /dev/null and b/cases/os/_images/debian-logo.png differ diff --git a/cases/os/_images/docker_version.png b/cases/os/_images/docker_version.png new file mode 100644 index 000000000..479a9035f Binary files /dev/null and b/cases/os/_images/docker_version.png differ diff --git a/cases/os/_images/fedora-logo.png b/cases/os/_images/fedora-logo.png new file mode 100644 index 000000000..7dd1589cb Binary files /dev/null and b/cases/os/_images/fedora-logo.png differ diff --git a/cases/os/_images/php_pulling.png b/cases/os/_images/php_pulling.png new file mode 100644 index 000000000..189e0581d Binary files /dev/null and b/cases/os/_images/php_pulling.png differ diff --git a/cases/os/_images/ubuntu-logo.jpg b/cases/os/_images/ubuntu-logo.jpg new file mode 100644 index 000000000..4138fab12 Binary files /dev/null and b/cases/os/_images/ubuntu-logo.jpg differ diff --git a/cases/os/_images/vmware_coreos.png b/cases/os/_images/vmware_coreos.png new file mode 100644 index 000000000..1003e4c8f Binary files /dev/null and b/cases/os/_images/vmware_coreos.png differ diff --git a/cases/os/alpine.md b/cases/os/alpine.md new file mode 100644 index 000000000..0a36fc12e --- /dev/null +++ b/cases/os/alpine.md @@ -0,0 +1,69 @@ +# Alpine + +## 简介 + +![Alpine Linux 操作系统](_images/alpinelinux-logo.png) + +`Alpine` 操作系统是一个面向安全的轻型 `Linux` 发行版。它不同于通常 `Linux` 发行版,`Alpine` 采用了 `musl libc` 和 `busybox` 以减小系统的体积和运行时资源消耗,但功能上比 `busybox` 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,`Alpine` 还提供了自己的包管理工具 `apk`,可以通过 `https://pkgs.alpinelinux.org/packages` 网站上查询包信息,也可以直接通过 `apk` 命令直接查询和安装各种软件。 + +`Alpine` 由非商业组织维护的,支持广泛场景的 `Linux`发行版,它特别为资深/重度`Linux`用户而优化,关注安全,性能和资源效能。`Alpine` 镜像可以适用于更多常用场景,并且是一个优秀的可以适用于生产的基础系统/环境。 + +`Alpine` Docker 镜像也继承了 `Alpine Linux` 发行版的这些优势。相比于其他 `Docker` 镜像,它的容量非常小,仅仅只有 **5 MB** 左右(对比 `Ubuntu` 系列镜像接近 `200 MB`),且拥有非常友好的包管理机制。官方镜像来自 `docker-alpine` 项目。 + +目前 Docker 官方已开始推荐使用 `Alpine` 替代之前的 `Ubuntu` 做为基础镜像环境。这样会带来多个好处。包括镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等。 + +下表是官方镜像的大小比较: + +```bash +REPOSITORY TAG IMAGE ID VIRTUAL SIZE +alpine latest 4e38e38c8ce0 4.799 MB +debian latest 4d6ce913b130 84.98 MB +ubuntu latest b39b81afc8ca 188.3 MB +centos latest 8efe422e6104 210 MB +``` + +## 获取并使用官方镜像 + +由于镜像很小,下载时间往往很短,读者可以直接使用 `docker run` 指令直接运行一个 `Alpine` 容器,并指定运行的 Linux 指令,例如: + +```bash +$ docker run alpine echo '123' +123 +``` + +## 迁移至 `Alpine` 基础镜像 + +目前,大部分 Docker 官方镜像都已经支持 `Alpine` 作为基础镜像,可以很容易进行迁移。 + +例如: + +* `ubuntu/debian` -> `alpine` +* `python:3` -> `python:3-alpine` +* `ruby:2.6` -> `ruby:2.6-alpine` + +另外,如果使用 `Alpine` 镜像替换 `Ubuntu` 基础镜像,安装软件包时需要用 `apk` 包管理器替换 `apt` 工具,如 + +```bash +$ apk add --no-cache +``` + +`Alpine` 中软件安装包的名字可能会与其他发行版有所不同,可以在 `https://pkgs.alpinelinux.org/packages` 网站搜索并确定安装包名称。如果需要的安装包不在主索引内,但是在测试或社区索引中。那么可以按照以下方法使用这些安装包。 + +```bash +$ echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories +$ apk --update add --no-cache +``` + +由于在国内访问 `apk` 仓库较缓慢,建议在使用 `apk` 之前先替换仓库地址为国内镜像。 + +```docker +RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories \ + && apk add --no-cache +``` + +## 相关资源 + +* `Alpine` 官网:https://www.alpinelinux.org/ +* `Alpine` 官方仓库:https://github.com/alpinelinux +* `Alpine` 官方镜像:https://hub.docker.com/_/alpine/ +* `Alpine` 官方镜像仓库:https://github.com/gliderlabs/docker-alpine diff --git a/cases/os/busybox.md b/cases/os/busybox.md new file mode 100644 index 000000000..b3527728f --- /dev/null +++ b/cases/os/busybox.md @@ -0,0 +1,130 @@ +# Busybox + +## 简介 + +![Busybox - Linux 瑞士军刀](_images/busybox-logo.png) + +`BusyBox` 是一个集成了一百多个最常用 Linux 命令和工具(如 `cat`、`echo`、`grep`、`mount`、`telnet` 等)的精简工具箱,它只需要几 MB 的大小,很方便进行各种快速验证,被誉为“Linux 系统的瑞士军刀”。 + +`BusyBox` 可运行于多款 `POSIX` 环境的操作系统中,如 `Linux`(包括 `Android`)、`Hurd`、`FreeBSD` 等。 + +## 获取官方镜像 + +在 `Docker Hub` 中搜索 `busybox` 相关的镜像。 + +```bash +$ docker search busybox +NAME DESCRIPTION STARS OFFICIAL AUTOMATED +busybox Busybox base image. 755 [OK] +progrium/busybox 63 [OK] +radial/busyboxplus Full-chain, Internet enabled, busybox made... 11 [OK] +odise/busybox-python 3 [OK] +multiarch/busybox multiarch ports of ubuntu-debootstrap 2 [OK] +azukiapp/busybox This image is meant to be used as the base... 2 [OK] +... +``` + +读者可以看到最受欢迎的镜像同时带有 `OFFICIAL` 标记,说明它是官方镜像。用户使用 `docker pull` 指令下载 `busybox:latest` 镜像: + +```bash +$ docker pull busybox:latest +busybox:latest: The image you are pulling has been verified +e433a6c5b276: Pull complete +e72ac664f4f0: Pull complete +511136ea3c5a: Pull complete +df7546f9f060: Pull complete +Status: Downloaded newer image for busybox:latest +``` + +下载后,可以看到 `busybox` 镜像只有 **2.433 MB**: + +```bash +$ docker image ls +REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE +busybox latest e72ac664f4f0 6 weeks ago 2.433 MB +``` + +## 运行 busybox + +启动一个 `busybox` 容器,并在容器中执行 `grep` 命令。 + +```bash +$ docker run -it busybox +/ # grep +BusyBox v1.22.1 (2014-05-22 23:22:11 UTC) multi-call binary. + +Usage: grep [-HhnlLoqvsriwFE] [-m N] [-A/B/C N] PATTERN/-e PATTERN.../-f FILE [FILE]... + +Search for PATTERN in FILEs (or stdin) + + -H Add 'filename:' prefix + -h Do not add 'filename:' prefix + -n Add 'line_no:' prefix + -l Show only names of files that match + -L Show only names of files that don't match + -c Show only count of matching lines + -o Show only the matching part of line + -q Quiet. Return 0 if PATTERN is found, 1 otherwise + -v Select non-matching lines + -s Suppress open and read errors + -r Recurse + -i Ignore case + -w Match whole words only + -x Match whole lines only + -F PATTERN is a literal (not regexp) + -E PATTERN is an extended regexp + -m N Match up to N times per file + -A N Print N lines of trailing context + -B N Print N lines of leading context + -C N Same as '-A N -B N' + -e PTRN Pattern to match + -f FILE Read pattern from file +``` + +查看容器内的挂载信息。 + +```bash +/ # mount +overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/BOTCI5RF24AMC4A2UWF4N6ZWFP:/var/lib/docker/overlay2/l/TWVP5T5DMKJGXZOROR7CAPWGFP,upperdir=/var/lib/docker/overlay2/801ef0bf6cce35288dbb8fe00a4f9cc47760444693bfdf339ed0bdcf926e12a3/diff,workdir=/var/lib/docker/overlay2/801ef0bf6cce35288dbb8fe00a4f9cc47760444693bfdf339ed0bdcf926e12a3/work) +proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) +tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755) +devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666) +sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime) +tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,relatime,mode=755) +cgroup on /sys/fs/cgroup/systemd type cgroup (ro,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd) +cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (ro,nosuid,nodev,noexec,relatime,net_cls,net_prio) +cgroup on /sys/fs/cgroup/freezer type cgroup (ro,nosuid,nodev,noexec,relatime,freezer) +cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpu,cpuacct) +cgroup on /sys/fs/cgroup/cpuset type cgroup (ro,nosuid,nodev,noexec,relatime,cpuset) +cgroup on /sys/fs/cgroup/blkio type cgroup (ro,nosuid,nodev,noexec,relatime,blkio) +cgroup on /sys/fs/cgroup/perf_event type cgroup (ro,nosuid,nodev,noexec,relatime,perf_event) +cgroup on /sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory) +cgroup on /sys/fs/cgroup/devices type cgroup (ro,nosuid,nodev,noexec,relatime,devices) +cgroup on /sys/fs/cgroup/pids type cgroup (ro,nosuid,nodev,noexec,relatime,pids) +mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime) +shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k) +/dev/vda1 on /etc/resolv.conf type ext3 (rw,noatime,data=ordered) +/dev/vda1 on /etc/hostname type ext3 (rw,noatime,data=ordered) +/dev/vda1 on /etc/hosts type ext3 (rw,noatime,data=ordered) +devpts on /dev/console type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666) +proc on /proc/bus type proc (ro,relatime) +proc on /proc/fs type proc (ro,relatime) +proc on /proc/irq type proc (ro,relatime) +proc on /proc/sys type proc (ro,relatime) +proc on /proc/sysrq-trigger type proc (ro,relatime) +tmpfs on /proc/acpi type tmpfs (ro,relatime) +tmpfs on /proc/kcore type tmpfs (rw,nosuid,size=65536k,mode=755) +tmpfs on /proc/keys type tmpfs (rw,nosuid,size=65536k,mode=755) +tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755) +tmpfs on /proc/sched_debug type tmpfs (rw,nosuid,size=65536k,mode=755) +tmpfs on /sys/firmware type tmpfs (ro,relatime) +``` + +`busybox` 镜像虽然小巧,但包括了大量常见的 `Linux` 命令,读者可以用它快速熟悉 `Linux` 命令。 + +## 相关资源 + +* `Busybox` 官网:https://busybox.net/ +* `Busybox` 官方仓库:https://git.busybox.net/busybox/ +* `Busybox` 官方镜像:https://hub.docker.com/_/busybox/ +* `Busybox` 官方仓库:https://github.com/docker-library/busybox diff --git a/cases/os/centos.md b/cases/os/centos.md new file mode 100644 index 000000000..b331e0486 --- /dev/null +++ b/cases/os/centos.md @@ -0,0 +1,76 @@ +# CentOS/Fedora + +## CentOS 系统简介 + +`CentOS` 和 `Fedora` 都是基于 `Redhat` 的常见 Linux 分支。`CentOS` 是目前企业级服务器的常用操作系统;`Fedora` 则主要面向个人桌面用户。 + +![CentOS 操作系统](_images/centos-logo.png) + +CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统),它是基于 `Red Hat Enterprise Linux` 源代码编译而成。由于 `CentOS` 与 `Redhat Linux` 源于相同的代码基础,所以很多成本敏感且需要高稳定性的公司就使用 `CentOS` 来替代商业版 `Red Hat Enterprise Linux`。`CentOS` 自身不包含闭源软件。 + +### 使用 CentOS 官方镜像 + +首先使用 `docker search` 命令来搜索标星至少为 `25` 的 `CentOS` 相关镜像。 + +```bash +$ docker search -f stars=25 centos +NAME DESCRIPTION STARS OFFICIAL AUTOMATED +centos The official... 2543 [OK] +jdeathe/centos-ssh 27 [OK] +``` + +使用 `docker run` 直接运行最新的 `CentOS` 镜像,并登录 `bash`。 + +```bash +$ docker run -it centos bash +Unable to find image 'centos:latest' locally +latest: Pulling from library/centos +3d8673bd162a: Pull complete +Digest: sha256:a66ffcb73930584413de83311ca11a4cb4938c9b2521d331026dad970c19adf4 +Status: Downloaded newer image for centos:latest +[root@43eb3b194d48 /]# cat /etc/redhat-release +CentOS Linux release 7.2.1511 (Core) +``` + +## Fedora 系统简介 + +![Fedora 操作系统](_images/fedora-logo.png) + +`Fedora` 由 `Fedora Project` 社区开发,红帽公司赞助的 `Linux` 发行版。它的目标是创建一套新颖、多功能并且自由和开源的操作系统。`Fedora` 的功能对于用户而言,它是一套功能完备的,可以更新的免费操作系统,而对赞助商 `Red Hat` 而言,它是许多新技术的测试平台。被认为可用的技术最终会加入到 `Red Hat Enterprise Linux` 中。 + +### 使用 Fedora 官方镜像 + +首先使用 `docker search` 命令来搜索标星至少为 `2` 的 `Fedora` 相关镜像,结果如下。 + +```bash +$ docker search -f stars=2 fedora +NAME DESCRIPTION STARS OFFICIAL AUTOMATED +fedora Official Docker builds of Fedora 433 [OK] +dockingbay/fedora-rust Trusted build of Rust programming language... 3 [OK] +gluster/gluster-fedora Official GlusterFS image [ Fedora 21 + Glu... 3 [OK] +startx/fedora Simple container used for all startx based... 2 [OK] +``` + +使用 `docker run` 命令直接运行 `Fedora` 官方镜像,并登录 `bash`。 + +```bash +$ docker run -it fedora bash +Unable to find image 'fedora:latest' locally +latest: Pulling from library/fedora +2bf01635e2a0: Pull complete +Digest: sha256:64a02df6aac27d1200c2572fe4b9949f1970d05f74d367ce4af994ba5dc3669e +Status: Downloaded newer image for fedora:latest +[root@196ca341419b /]# cat /etc/redhat-release +Fedora release 24 (Twenty Four) +``` + +## 相关资源 + +* `Fedora` 官网:https://getfedora.org/ +* `Fedora` 官方仓库:https://github.com/fedora-infra +* `Fedora` 官方镜像:https://hub.docker.com/_/fedora/ +* `Fedora` 官方镜像仓库:https://github.com/fedora-cloud/docker-brew-fedora +* `CentOS` 官网:https://www.centos.org +* `CentOS` 官方仓库:https://github.com/CentOS +* `CentOS` 官方镜像:https://hub.docker.com/_/centos/ +* `CentOS` 官方镜像仓库:https://github.com/CentOS/CentOS-Dockerfiles diff --git a/cases/os/debian.md b/cases/os/debian.md new file mode 100644 index 000000000..b19c6d6e7 --- /dev/null +++ b/cases/os/debian.md @@ -0,0 +1,190 @@ +# Debian/Ubuntu +`Debian` 和 `Ubuntu` 都是目前较为流行的 **Debian 系** 的服务器操作系统,十分适合研发场景。`Docker Hub` 上提供了官方镜像,国内各大容器云服务也基本都提供了相应的支持。 + +## Debian 系统简介 + +![Debian 操作系统](_images/debian-logo.png) + +`Debian` 是由 `GPL` 和其他自由软件许可协议授权的自由软件组成的操作系统,由 **Debian 计划(Debian Project)** 组织维护。**Debian 计划** 是一个独立的、分散的组织,由 `3000` 人志愿者组成,接受世界多个非盈利组织的资金支持,`Software in the Public Interest` 提供支持并持有商标作为保护机构。`Debian` 以其坚守 `Unix` 和自由软件的精神,以及其给予用户的众多选择而闻名。现时 `Debian` 包括了超过 `25,000` 个软件包并支持 `12` 个计算机系统结构。 + +`Debian` 作为一个大的系统组织框架,其下有多种不同操作系统核心的分支计划,主要为采用 `Linux` 核心的 `Debian GNU/Linux` 系统,其他还有采用 `GNU Hurd` 核心的 `Debian GNU/Hurd` 系统、采用 `FreeBSD` 核心的 `Debian GNU/kFreeBSD` 系统,以及采用 `NetBSD` 核心的 `Debian GNU/NetBSD` 系统。甚至还有利用 `Debian` 的系统架构和工具,采用 `OpenSolaris` 核心构建而成的 `Nexenta OS` 系统。在这些 `Debian` 系统中,以采用 `Linux` 核心的 `Debian GNU/Linux` 最为著名。 + +众多的 `Linux` 发行版,例如 `Ubuntu`、`Knoppix` 和 `Linspire` 及 `Xandros` 等,都基于 `Debian GNU/Linux`。 + +### 使用 Debian 官方镜像 + +读者可以使用 `docker search` 查找 `Debian` 镜像: + +```bash +$ docker search debian +NAME DESCRIPTION STARS OFFICIAL AUTOMATED +debian Debian is... 1565 [OK] +neurodebian NeuroDebian... 26 [OK] +armbuild/debian port of debian 8 [OK] +... +``` + +官方提供了大家熟知的 `debian` 镜像以及面向科研领域的 `neurodebian` 镜像。 + +可以使用 `docker run` 直接运行 `Debian` 镜像。 + +```bash +$ docker run -it debian bash +root@668e178d8d69:/# cat /etc/issue +Debian GNU/Linux 8 +``` + +`Debian` 镜像很适合作为基础镜像,构建自定义镜像。 + +## Ubuntu 系统简介 + +![Ubuntu 操作系统](_images/ubuntu-logo.jpg) + +`Ubuntu` 是一个以桌面应用为主的 `GNU/Linux` 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词(官方译名“友帮拓”,另有“吾帮托”、“乌班图”、“有奔头”或“乌斑兔”等译名)。`Ubuntu` 意思是“人性”以及“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。 `Ubuntu` 基于 `Debian` 发行版和 `GNOME/Unity` 桌面环境,与 `Debian` 的不同在于它每 6 个月会发布一个新版本,每 2 年推出一个长期支持 **(Long Term Support,LTS)** 版本,一般支持 3 年时间。 + +### 使用 Ubuntu 官方镜像 + +`Ubuntu` 相关的镜像有很多,这里使用 `--filter=stars=10` 参数,只搜索那些被收藏 `10` 次以上的镜像。 + +```bash +$ docker search --filter=stars=10 ubuntu + +NAME DESCRIPTION STARS OFFICIAL AUTOMATED +ubuntu Ubuntu is a Debian-based Linux operating sys… 10539 [OK] +dorowu/ubuntu-desktop-lxde-vnc Docker image to provide HTML5 VNC interface … 395 [OK] +rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 243 [OK] +consol/ubuntu-xfce-vnc Ubuntu container with "headless" VNC session… 210 [OK] +ubuntu-upstart Upstart is an event-based replacement for th… 105 [OK] +ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ansible 98 [OK] +neurodebian NeuroDebian provides neuroscience research s… 64 [OK] +1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5 ubuntu-16-nginx-php-phpmyadmin-mysql-5 50 [OK] +ubuntu-debootstrap debootstrap --variant=minbase --components=m… 42 [OK] +nuagebec/ubuntu Simple always updated Ubuntu docker images w… 24 [OK] +i386/ubuntu Ubuntu is a Debian-based Linux operating sys… 19 +1and1internet/ubuntu-16-apache-php-5.6 ubuntu-16-apache-php-5.6 14 [OK] +1and1internet/ubuntu-16-apache-php-7.0 ubuntu-16-apache-php-7.0 13 [OK] +eclipse/ubuntu_jdk8 Ubuntu, JDK8, Maven 3, git, curl, nmap, mc, … 12 [OK] +1and1internet/ubuntu-16-nginx-php-phpmyadmin-mariadb-10 ubuntu-16-nginx-php-phpmyadmin-mariadb-10 11 [OK] +``` + +根据搜索出来的结果,读者可以自行选择下载镜像并使用。 + +下面以 `ubuntu:18.04` 为例,演示如何使用该镜像安装一些常用软件。 + +首先使用 `-ti` 参数启动容器,登录 `bash`,查看 `ubuntu` 的发行版本号。 + +```bash +$ docker run -ti ubuntu:18.04 /bin/bash +root@7d93de07bf76:/# cat /etc/os-release +NAME="Ubuntu" +VERSION="18.04.1 LTS (Bionic Beaver)" +ID=ubuntu +ID_LIKE=debian +PRETTY_NAME="Ubuntu 18.04.1 LTS" +VERSION_ID="18.04" +HOME_URL="https://www.ubuntu.com/" +SUPPORT_URL="https://help.ubuntu.com/" +BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" +PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" +VERSION_CODENAME=bionic +UBUNTU_CODENAME=bionic +``` + +当试图直接使用 `apt-get` 安装一个软件的时候,会提示 `E: Unable to locate package`。 + +```bash +root@7d93de07bf76:/# apt-get install curl +Reading package lists... Done +Building dependency tree +Reading state information... Done +E: Unable to locate package curl +``` + +这并非系统不支持 `apt-get` 命令。Docker 镜像在制作时为了精简清除了 `apt` 仓库信息,因此需要先执行 `apt-get update` 命令来更新仓库信息。更新信息后即可成功通过 `apt-get` 命令来安装软件。 + +```bash +root@7d93de07bf76:/# apt-get update +Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB] +Get:2 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB] +Get:3 http://security.ubuntu.com/ubuntu bionic-security/multiverse amd64 Packages [7348 B] +Get:4 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [823 kB] +Get:5 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB] +Get:6 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB] +Get:7 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages [11.3 MB] +Get:8 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages [31.0 kB] +Get:9 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [835 kB] +Get:10 http://archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages [13.5 kB] +Get:11 http://archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1344 kB] +Get:12 http://archive.ubuntu.com/ubuntu bionic/multiverse amd64 Packages [186 kB] +Get:13 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [1127 kB] +Get:14 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [1350 kB] +Get:15 http://archive.ubuntu.com/ubuntu bionic-updates/multiverse amd64 Packages [11.4 kB] +Get:16 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [44.7 kB] +Get:17 http://archive.ubuntu.com/ubuntu bionic-backports/main amd64 Packages [2496 B] +Get:18 http://archive.ubuntu.com/ubuntu bionic-backports/universe amd64 Packages [4252 B] +Fetched 17.6 MB in 1min 25s (207 kB/s) +Reading package lists... Done +``` + +首先,安装 `curl` 工具。 + +```bash +root@7d93de07bf76:/# apt-get install curl +Reading package lists... Done +Building dependency tree +Reading state information... Done +The following additional packages will be installed: + ca-certificates krb5-locales libasn1-8-heimdal libcurl4 libgssapi-krb5-2 libgssapi3-heimdal libhcrypto4-heimdal libheimbase1-heimdal libheimntlm0-heimdal libhx509-5-heimdal + libk5crypto3 libkeyutils1 libkrb5-26-heimdal libkrb5-3 libkrb5support0 libldap-2.4-2 libldap-common libnghttp2-14 libpsl5 libroken18-heimdal librtmp1 libsasl2-2 libsasl2-modules libsasl2-modules-db libsqlite3-0 libssl1.1 libwind0-heimdal openssl publicsuffix +... +root@7d93de07bf76:/# curl +curl: try 'curl --help' or 'curl --manual' for more information +``` + +接下来,再安装 `apache` 服务。 + +```bash +root@7d93de07bf76:/# apt-get install -y apache2 +Reading package lists... Done +Building dependency tree +Reading state information... Done +The following additional packages will be installed: + apache2-bin apache2-data apache2-utils file libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libexpat1 libgdbm-compat4 libgdbm5 libicu60 liblua5.2-0 libmagic-mgc libmagic1 libperl5.26 libxml2 mime-support netbase perl perl-modules-5.26 ssl-cert xz-utils +... +``` + +启动这个 `apache` 服务,然后使用 `curl` 来测试本地访问。 + +```bash +root@7d93de07bf76:/# service apache2 start + * Starting web server apache2 AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message + * +root@7d93de07bf76:/# curl 127.0.0.1 + + + + + + + Apache2 Ubuntu Default Page: It works +