Docker学习笔记

Docker基本操作

Docker环境配置
安装docker

参考https://www.jianshu.com/p/b7c9cfb06ea4

设置镜像源

/etc/docker/daemon.json

{
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}
启动docker
sudo systemctl start docker
设置开机自启
sudo systemctl enable docker
测试
docker run hello-world
Docker中央仓库
  1. Docker官方仓库,镜像最全,国内下载较慢

https://hub.docker.com/

  1. 国内镜像,如网易云、DaoCloud(推荐)

https://c.163yun.com/hub#/home

http://hub.daocloud.io/

  1. 在公司内部可以自行搭建中央仓库

自行搭建中央仓库方法

/etc/docker/daemon.json

{
  "registry-mirrors": ["https://registry.docker-cn.com"],
  "insecure-registries": ["ip:port"]
}

最后需要重新启动下服务

sudo systemctl daemon-reload
sudo systemctl restart docker
镜像操作
拉取镜像到本地
# 命令
docker pull 镜像名[:tag]

# 例如
docker pull daocloud.io/library/tomcat:8.5.15-jre8
查看全部本地镜像
docker images
删除本地镜像
docker rmi 镜像的标志
# 这里 b8 是镜像的 id 开头几个字母
docker rmi b8 
删除无用镜像
docker image prune

加上-a参数后,会删除所有没有被容器引用的镜像

镜像的导入导出
# 将本地的镜像导出
docker save -o 导出的路径 镜像id
# 例如
docker save -o ./tomcat.image b8

# 加载本地的镜像文件(名称和版本为none,可以用下面的命令更改名字)
docker load -i 镜像文件
# 例如
docker load -i ./tomcat.image

# 镜像重命名
docker tag 镜像id 新名字:版本
# 例如
docker tag b8 tomcat:8.5
容器的操作
运行容器
docker run 镜像id|镜像名称[:tag]
常用参数
docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像id|镜像名称[:tag]
# 例如
docker run -d -p 8081:8080 --name tomcat b8
  • -d 后台运行容器
  • -p 宿主机端口:容器端口 Linux端口和容器端口之间的映射
  • --name 容器名称 指定容器名称
查看运行中的容器
docker ps [-qa]
  • -a 查看所有容器,包括没有运行的容器

  • -q 只查看运行中容器的标志

  • -qa 查看所有容器的标志

  • 无参数 查看运行中的容器

查看日志
docker logs -f 容器id
  • -f 动态查看日志的最后几行
进入容器内部
docker exec -it 容器id bash
# 退出
exit
删除容器
# 停止指定容器
docker stop 容器id
# 停止所有容器
docker stop $(docker ps -qa)
# 删除指定容器
docker rm 容器id
# 删除全部容器
docker rm $(docker ps -qa)
启动容器
docker start 容器id

Docker应用

mysql
docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=my_secret daocloud.io/library/mysql:5.7.4
  • -e 指定 mysql 密码
tomcat
docker run -d -p 8080:8080 --name tomcat daocloud.io/library/tomcat:8.5.15-jre8
部署项目

以部署Jenkins为例,下载地址http://updates.jenkins-ci.org/download/war/2.263/jenkins.war

# 将宿主机内容复制到容器
docker cp 文件名 容器id:容器内部路径
# 例如
docker cp jenkins.war db4914a734a2:/usr/local/tomcat/webapps/ 

访问ip:8080/jenkins,可以看到jenkins已经安装好了,使用docker logs -f db4914a734a2 命令可以查看安装细节。

数据卷

将宿主机中的一个目录映射到容器的一个目录中,当宿主机目录发生变化时,容器中的目录也会跟着变化。数据卷实现了在容器外操作容器内的目录和文件

创建数据卷
# 创建数据卷
docker volume create 数据卷名称
# 默认数据卷位置是 /var/lib/docker/volumes/数据卷名称/_data
# 例如
docker volume create tomcat
查看数据卷详情
docker volume inspect 数据卷名称
# 例如
docker volume inspect tomcat
查看全部数据卷
docker volume ls
删除数据卷
docker volume rm 数据卷名称
# 例如
docker volume rm tomcat
删除无主数据卷
docker volume prune
应用数据卷

方式一:映射前创建数据卷

docker run -v 数据卷名称:容器内部路径 镜像id

# 创建数据卷
docker volume create volume_tomcat
# 将数据卷映射到容器内部目录
docker run -d -p 8080:8080 --name tomcat -v volume_tomcat:/usr/local/tomcat/webapps/ daocloud.io/library/tomcat:8.5.15-jre8
# 将项目复制到数据卷中
sudo cp jenkins.war /var/lib/docker/volumes/volume_tomcat/_data

采用create方式创建的数据卷的挂载目录是/var/lib/docker/volumes/数据卷名称/_data。所以上面的-v volume_tomcat:/usr/local/tomcat/webapps/-v /var/lib/docker/volumes/volume_tomcat/_data:/usr/local/tomcat/webapps/是等价的。

方式二:指定数据卷目录(推荐)

docker run -v 路径:容器内部路径 镜像id

# 将指定目录数据卷映射到容器内部目录
docker run -d -p 8080:8080 --name tomcat -v /opt/volume_tomcat:/usr/local/tomcat/webapps/ daocloud.io/library/tomcat:8.5.15-jre8
# 将项目复制到数据卷中
sudo cp jenkins.war /opt/volume_tomcat

两种方式区别:第一种方式会在默认目录创建数据卷,而且容器中的内容也会拷贝到该目录中,第二种方式只在指定位置创建数据卷,但容器中内容不会自动拷贝进来

查看数据卷挂载位置
docker inspect 容器id | grep Mounts -A 20

Docker自定义镜像

创建Dockerfile
  • FROM 指定当前自定义镜像依赖的环境
  • COPY 将相对路径下的内容复制到自定义镜像中
  • WORKDIR 声明镜像的默认工作目录
  • ENV 配置环境变量
  • RUN 创建当前的 Docker 镜像,每次调用该指令的时候,Docker 都会创建新的镜像层。RUN 后面直接跟 shell 指令
  • CMD 需要执行的命令,在工作目录(workdir)下执行,可以写多个,只以最后一个为准
  • MAINTAINER 镜像维护者信息
  • EXPOSE 暴露端口

Dockerfile

FROM alpine:3.8

RUN apk add --no-cache \
    ca-certificates \
    git \
    gcc \
    musl-dev \
    openssl \
    go

ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
ENV APIPATH $GOPATH/src/api
RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" "$APIPATH" && chmod -R 777 "$GOPATH"

WORKDIR $APIPATH
COPY . .

RUN \
    go get -d -v \
    && go install -v \
    && go build

EXPOSE 3000
CMD ["./api"]
制作镜像
docker build -t 镜像名:[tag] 目录名
docker build -f Dockerfile -t 镜像名:[tag] 目录名
# 例如
docker build -t jenkins-tomcat:1.0.0 .
# 运行自定义镜像
docker run -d -p 8080:8080 --name jenkins-tomcat a75b8a0e7da6
dockerignore

在构建镜像过程中,为了提高构建性能,可以通过.dockerignore文件排除上下文目录下不需要的文件和目录

.dockerignore

.DS_Store
node_modules
/dist
dist

Dockerfile
.dockerignore

# git
.git
.gitignore

# local env files
.env.local
.env.*.local

.env.production
.env

server/public

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
发布镜像

构建镜像

docker build -t your_dockerhub_username/your_image_name .

构建完成后,可以使用docker images命令检查刚才构建的镜像

登录docker

docker login -u your_dockerhub_username 

命令执行会要求输入密码,登录成功后会在~/.docker/config.json存储用户登录信息

推送镜像

docker push your_dockerhub_username/your_image_name

取回镜像

docker pull your_dockerhub_username/your_image_name

Docker-Compose

之前运行一个容器,需要在命令行添加大量参数,这样不方便记忆和管理,Docker-Compose可以用文件方式编写这些参数,而且它还可以批量管理容器

安装Docker-Compose

参考 https://www.jianshu.com/p/b7c9cfb06ea4

docker-compose.yml

docker-compose.yml文件以key: value来指定配置信息,多个配置信息以换行+缩进方式区分。键和值之间有一个空格,缩进用两个空格,不能使用制表符。推荐用Docker插件进行格式化。

version: '3'
services:
  mysql: # 服务的名称
    restart: always # 只要 docker 启动,服务自动启动
    image: daocloud.io/library/mysql:8.0.19 # 镜像位置
    container_name: mysql # 容器的名称,通过 docker ps 查看
    command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    ports:
      - 3306:3306 # 指定端口映射,可以指定多对映射
    environment:  # 设置环境变量
      MYSQL_ROOT_PASSWORD: screct # 指定 MYSQL root 用户登录密码
      MYSQL_DATABASE: testdb # 初始化数据库
      TZ: Asia/Shanghai # 指定时区

    volumes:
      - ./init:/docker-entrypoint-initdb.d # 初始化数据,容器创建时自动导入 MYSQL_DATABASE 指定数据库,注意数据源必须在数据卷首次挂载前存在
      - /opt/docker_mysql/data:/var/lib/mysql # 映射数据卷
      - /opt/docker_mysql/config:/etc/mysql/conf.d' # mysql 配置文件目录

  mongo:
    container_name: mongo
    image: mongo:latest
    restart: always
    ports:
      - '27017:27017'
    volumes:
      - /opt/docker_mongo/data/db:/data/db

  redis:
    container_name: redis
    image: redis:alpine
    restart: always
    volumes:
      - redis_data:/data

  express-mongo-demo:
    restart: always
    build: # 构建自定义镜像
      context: ./ # 指定 dockerfile 所在路径,这里是当前目录
      dockerfile: Dockerfile # 指定 dockerfile 文件名
    image: express-mongo-demo:1.0.1 # 指定镜像名字
    container_name: express-mongo-demo # 指定容器名字
    ports:
      - 8080:8080     
    depends_on: # 镜像启动顺序
      - redis
      - mongo
volumes: # docker create volume 创建的容器需要在这里声明
    redis_data:
启动并运行容器

运行docker-compose命令后,默认在当前目录下找docker-compose.yml文件

docker-compose up -d

如果mysql启动失败,查看日志发现如下报错

mysqld: Can't create/write to file '/tmp/ibZhgm0t' (Errcode: 13 - Permission denied)

这是由于mysql没有/tmp目录写入权限导致的,运行sudo chmod 777 /tmp后重启服务

关闭并删除容器
docker-compose down
关闭容器同时删除数据卷
docker-compose down --volumes
docker-compose down -v

只会删除默认容器

开启|关闭|重启已存在容器

该容器必须是由docker-compose所管理的

docker-compose start|stop|restart
查看容器
docker-compose ps
查看日志
docker-compose logs -f
docker-compose管理自定义镜像
构建自定义镜像

Dockerfile

# 镜像依赖的环境
FROM node:10

# 容器中的工作目录
WORKDIR /usr/src/app

# 复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
COPY package*.json ./

# RUN 在 docker build 时运行
RUN npm install

COPY . .

# 声明端口,帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
EXPOSE 8080

# CMD 在 docker run 时运行,多个 CMD 仅最后一个有效。
CMD ["npm", "start"]

docker-compose.yml

version: '3'
services:
  mongo:
    container_name: mongo
    image: mongo:latest
    restart: always
    ports:
      - '27017:27017'
    volumes:
      - /opt/docker_mongo/data/db:/data/db

  redis:
    container_name: redis
    image: redis:alpine
    restart: always
    volumes:
      - /opt/docker_redis/data:/data

  express-mongo-demo:
    restart: always
    build: # 构建自定义镜像
      context: ./ # 指定 dockerfile 所在路径,这里是当前目录
      dockerfile: Dockerfile # 指定 dockerfile 文件名
    image: express-mongo-demo:1.0.1 # 指定镜像名字
    container_name: express-mongo-demo # 指定容器名字
    ports:
      - 8080:8080     
    depends_on:
      - redis
      - mongo
运行自定义镜像
docker-compose up -d

如果自定义镜像不存在,会自动构建自定义镜像,如果自定义镜像已经存在,会直接运行这个镜像

重新构建自定义镜像
docker-compose build
运行前重新构建镜像
docker-compose up -d --build
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342