docker你需要知道的事,快速上手

333 阅读13分钟

dokcer环境


换源:

系统源
# 对于 CentOS 7
sudo sed -e 's|^mirrorlist=|#mirrorlist=|g' \
         -e 's|^#baseurl=http://mirror.centos.org|baseurl=https://mirrors.tuna.tsinghua.edu.cn|g' \
         -i.bak \
         /etc/yum.repos.d/CentOS-*.repo

# 对于 CentOS 8
sudo sed -e 's|^mirrorlist=|#mirrorlist=|g' \
         -e 's|^#baseurl=http://mirror.centos.org/$contentdir|baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos|g' \
         -i.bak \
         /etc/yum.repos.d/CentOS-*.repo

安装

docker安装

yum install docker -y
但是这种docker安装版本比较旧

yum install wget

centos7
wget -O /etc/yum.repos.d/docker-ce.repo https://repo.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo \
&& sudo sed -i 's+download.docker.com+repo.huaweicloud.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo \
&& yum makecache fast && yum install docker-ce -y

centos8

wget -O /etc/yum.repos.d/docker-ce.repo https://repo.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo \
&& sudo sed -i 's+download.docker.com+repo.huaweicloud.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo \
&& yum makecache  && yum install docker-ce -y

windows安装

下载desktop

Get Docker | Docker Docs

docker自启动

systemctl start docker
systemctl enable docker 

镜像加速

centos8(podman配置)

镜像加速配置文件

 vim /etc/containers/registries.conf
unqualified-search-registries = ["docker.io"]
[[registry]]
prefix = "docker.io"
location = "hub-mirror.c.163.com"

centos7(docker配置)

可选镜像源,任选其中一个

网易加速 7ms

https://hub-mirror.c.163.com

阿里加速 7ms,不过在centos8下做加速比较慢

这里直接在阿里搜索镜像加速就会出现你对应的一个加速地址。这里不做介绍

bhqsp9z7.mirror.aliyuncs.com这个是我自己阿里云的加速,每个阿里用户都有一个

镜像加速配置文件mirror.iscas.ac.cn这个镜像加速很快

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://docker.1panel.live"]
}
EOF
systemctl restart docker
docker info //查看有没有设置成功
time docker pull mysql 可以使用time命令来查看下载时间

docker启动

systemctl start docker
systemctl enable docker
docker -v

docker-compose安装通过源码

curl -L https://github.com/docker/compose/releases/download/2.2.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-co
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.2.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

1.29.1这个是版本,具体得看官方新版tag,对应的换。

github.com/docker/comp…

可执行权限

chmod +x /usr/local/bin/docker-compose

检测是否成功

docker-compose --version

docker-compose安装通过pip (推荐)

先安装pip

yum -y install python-pip
yum -y install python3-pip(centos8)
yum -y install epel-release // 如果你的源执行pip安装失败可用
pip3 install docker-compose

docker版本升级

移除旧版相关软件包,下载新版本,更新版本会有点慢。

第一种配置docker华为源

rpm -qa | grep docker | xargs yum remove -y;
wget -O /etc/yum.repos.d/docker-ce.repo https://repo.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo \
&& sudo sed -i 's+download.docker.com+repo.huaweicloud.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo \
&& yum makecache fast && yum install docker-ce -y

第二种。这是官网但是有时候不稳定
rpm -qa | grep docker | xargs yum remove -y;
curl -fsSL https://get.docker.com/ | sh


第三种
curl -fsSL https://www.larryane.xyz/docker-config.sh | sh

podman命令改docker 如果不习惯 (可选)

echo "alias docker=podman" >> .bashrc 
source .bashrc

docker命令

基本

启动docker进程
systemctl start docker

docker ps 运行容器
docker images 所有镜像
docker rm/rmi  容器/镜像移除
docker start/restart/stop 容器名字/容器id

运行容器,后台运行docker镜像
docker run -d nginx
停止docker
docker stop 容器id
启动容器
docekr start 容器id

打开容器bash
docker exec -it 容器id sh
Ctrl+P+Q 退出

查看资源使用情况
docker stats --no-stream

提权root权限
docker --privileged=true   

自动删除    
docker --rm    
docker run  --name redis 
-v  /home/redis/data:/data 
-v /home/redis/conf/redis.conf:/usr/local/etc/redis/conf/redis.conf 
-d 
-p 6300:6379 redis redis.conf

--name给容器起别名
-v 映射卷
-d 后台运行
-p 端口映射

运行镜像

运行镜像一般是可以根据镜像id或镜像名加标签
docker run -p 3308:3306 --name mysql2 -e MYSQL_ROOT_PASSWORD=123456 -d 5c62e459e087

docker run -p 3307:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d larryane/mysql:1.0

更新启动参数

docker update --restart=always hertzbeat

自动启动容器

重启服务器时可以启动容器 --restart=always


docker run -d \
    -p 5000:5000 \
    -v /opt/data/registry:/var/lib/registry \
    --restart=always --name registry \
    registry
    
docker run --name nacos -e MODE=standalone -p 30099:8848 -d \
--restart=always \
nacos/nacos-server    

跟随主机端口


docker run --network host:host 
docker run --network=host

--network host: host 网络模式,所有容器端口都对应属主机端口,不存在映射关系。

备份docker中mysql数据库

docker exec CONTAINER /usr/bin/mysqldump -u username --password=xxx 数据库名字 > backup.sql

私有仓库

    
 标签   
 docker tag centos:7 127.0.0.1:5000/centos:7
 
 推送
 docker push 127.0.0.1:5000/centos:7

查看
curl 127.0.0.1:5000/v2/_catalog

其他机器拉取你的私有库
docker pull 1.116.187.129:5000/centos:7

官方推荐Secure Registry,即配置证书启动Registry
不然的话其他机器拉取,推送会导致客服端https请求失败

如果没证书需要在/etc/docker/daemon.json
{
  "registry-mirror": [
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ],
  "insecure-registries": [
    "192.168.199.100:5000"
  ]
}

docker镜像的保存和载入

比如这里,我们将java8的镜像保存为文件:

docker save -o redis.tar redis:5.0.2

# 导入之前导出的镜像
# 其中 -i 表示从文件输入。会成功导入镜像及相关元数据,包括tag信息
docker load -i xxx.tar
 
#推送远程仓库
docker login
docker tag [镜像id] [用户名]/[新镜像名称]:[新镜像标签]
docker tag c172e8504 larryane/gencode:2.0
docker push larryane/gencode:2.0
  

docker开发环境

启动
(-dit  这样就可以保持docker一直运行)

node

FROM centos:7
RUN yum -y install wget
RUN wget https://nodejs.org/dist/v16.18.1/node-v16.18.1-linux-x64.tar.xz

RUN tar xvf node-v16.18.1-linux-x64.tar.xz
RUN ln -s /node-v16.18.1-linux-x64/bin/node /usr/local/bin/node 

CMD ["echo","start over"]

构建
docker build -t env .

golang

docker run -dit --rm -v /D/goenv:/home golang bash
  
1.先在/D/goenv 存一个小项目
2.用vscode连接到远程的项目
3.在docker环境中在下载go插件
4.通过vscode命令行配置源
export GOPROXY=https://goproxy.cn,direct
5.工作区另存为桌面

java

docker run -dit --rm -v /D/javaenv:/home amazoncorretto bash
docker run -dit --rm -v /D/javaenv:/home amazoncorretto:17 bash

docker run -dit --rm -v /home/javaenv:/home amazoncorretto:17-alpine bash

go部署测试环境一,不推荐重启麻烦

把本地的项目目录映射好然后启动
docker run -dit --rm -p 8083:8083 
-e mode=production -e dbUrl="root:root@tcp(r:3306)/study" 
-e GOPROXY=https://goproxy.cn,direct 
-v /D/Users/JNPF/Desktop/project/autopub-server:/app golang bash

安装air,启动

后续
git pull

导出环境变量
export dbUrl="root:root@tcp(192.168.20.143:3306)/study"

python

docker run -dit  \
--restart=always --name=pyenv \
-v /D/pyenv:/home python:3.10.9-slim

docker run -d  -p 8000:8000 \
--restart=always --name=codeapi \
-v /root/python/code-design:/app fast

可以临时调整参数

docker update --restart=always <CONTAINER ID>

其他配置

1.先在/D/pyenv 存一个小项目
2.用vscode连接到远程的项目
3.在docker环境中在下载python插件
4.通过vscode命令行配置源
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip install -r requirements.txt
5.工作区另存为桌面

下面是了解dockerfile编写,先从指令开始

Dockerfile 指令

FROM

指定基础镜像,必须,格式第一条指令,如构建很多镜像的ubuntu

FROM ubuntu

RUN

执行命令,通常执行命令行的命令,有两种格式写法

shell 格式:
RUN <命令>

exec 格式:可以理解成bahs脚本的执行参数,脚本里面会读取命令参数执行操作
RUN ["可执行文件", "参数1", "参数2"]

CMD

容器启动命令

shell 格式:CMD  <命令>

exec 格式:
CMD  ["可执行文件", "参数1", "参数2"]

copy

COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。

源路径就是指现在宿主机所在目录(是已经存在的), 目标路径是在docker容器内。准备复制过去的

COPY [--chown=<user>:<group>] <源路径>... <目标路径>

COPY package.json /usr/src/app/

需要注意的是copy 只能从dockerfile所在的目录开始,不能跳到dockerfile文件的上级

add

ADD 指令和 COPY 的格式和性质基本一致。在 COPY 基础上增加了一些功能。仅在需要自动解压缩的场合使用 ADD,其他情况有多余的层构建。一般复制文件使用copy

build

用于构建镜像

docker build [dockerfile文件上下文]
-t 指定生成镜像的名字
-f 指定对应的dockerfile名,注意默认docker读取名字是Dockerfile的文件,只有你名字是自定义时候需要

docker build -t java -f app .
点默认上下文是当前路径,上下文对于你文件中的add命令很关键,add文件就是要从上下文拿的

ENV

设置环境变量

换行及空格的处理

ENV VERSION=1.0 DEBUG=on \
    NAME="Happy Feet"

EXPOSE

声明暴露端口,没有实际映射端口的功能,是给运维看的优化提示,说明应用的默认启动端口

WORKDIR

指定工作目录,相当于cd命令,这时候 点就是指的是/java目录

WORKDIR /java
ADD demo*.jar /java/app.jar
等价于
WORKDIR /java
ADD demo*.jar ./app.jar

ENTRYPOINT

和CMD,很像,是入口点,更换cmd的命令入口,让在cmd命令的参数基于ENTRYPOINT 后面作为参数运行,所以可以让镜像变成命令一样使用,高级用法搭配脚本做cmd启动前的应用准备

VOLUME

主要有两种,一种是bind模式, 挂在主机上。这个时候要绝对路径。

数据卷:-v 主机绝对路径:docker容器内部路径

VOLUME /c/app /app

这种相当于是代码是主机的,做了个共享的感觉。docker容器是通过一个软链接去访问主机路径。这个时候如果在docker容器里面删除代码。主机的代码也会被删除。相反,如果主机上代码的

修改,也会直接体现在容器内部。但是这种挂载官方不推荐。

bind模式还有一个是bind到文件,-v /home/nginx.conf:/app/nginx.conf 这种在宿主机上面改还不能直接生效,原因是inode机制文件内容改变后,inode信息变了。容器需要重启加载这个新的inode.

而目录是因为不改目录名,里面的内容改了自然可以变。

另一种是volumn模式 , 左边的主机路径不是路径,而只是个标记(卷名),这个时候镜像会新生成卷(在主机上,确保数据不会丢失)。代码不会互相影响。因为这种模式是docker自己控制了,卷是docker自己在主机某个位置生成,这个路径一般不会自己去找。如果改代码,必须是改变在docker自己容器内部,然后重新restart容器才可以生效。不过有dockerdesktop则很方便的可以进行本地改代码,重新刷新。

以docker容器定义的目录为主,不存在软链接。数据直接存在某个目录。

如下VOLUME larry /app

FROM ubuntu

RUN apt-get update -y  && \
  apt-get install -y python3-pip


COPY ./requirements.txt /app/requirements.txt

RUN pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

RUN pip3 install -r /app/requirements.txt

COPY . /app

WORKDIR /app

CMD [ "uvicorn" ,"main:app","--host" ,"0.0.0.0","--reload"]
## 网络监听端口
EXPOSE 8000

数据卷运用:

这里就可以做些有意思的事情,代码热部署

只要服务器下载一个git工具。

然后本地开发后上传上去,服务器只要拉取就可以自动完成部署了。这种是使用bind挂载的方式实现。

如果是使用volumn卷的方式,由于是构建dockerfile镜像的方式。那么文件是在内部,卷又是被docker管理,不好直接得到。这时候要进到容器内部,在git拉取代码才可以。

但是上面方式都有个问题,镜像构建拓展不利。每次拓展一个的话,由于git安装没有写进dockerfile中。所以每启动一个新容器都是没有git等一些你在上一个容器中安装好的工具。

写好的些配置等。所以这个在多环境和多端口部署的情况下有些不可用。

注意:(

为了镜像的可移植性,VOLUME 指令不支持指定主机目录参数(像 docker run -v <主机目录>:<容器目录> 是可以指定主机目录的)

如果要指定,还是要通过 docker run -v 来指定主机目录,也就是说dockerfile里面写bind模式无效

ONBUILD 为他人作嫁衣裳

嫁衣镜像

一个基本的环境,假设叫nodebase

FROM node:16-alpine3.16
RUN mkdir /app
WORKDIR /app
ONBUILD COPY ./package.json /app
ONBUILD RUN [ "npm", "install" ]
ONBUILD COPY . /app/

使用嫁衣镜像

FROM nodebase
CMD [ "npm", "start" ]
EXPOSE 8080

相当于是这个效果,但是onbuild只有在子镜像构建时候才镜像执行的操作

FROM node:16-alpine3.16
RUN mkdir /app
WORKDIR /app
COPY ./package.json /app
RUN [ "npm", "install" ]
COPY . /app/
CMD [ "npm", "run","serve" ]
EXPOSE 8080

知识点:

ENTRYPOINT ,HEALTHCHECK 最好不要都写。

多阶段构建

FROM alpine:latest AS builder
RUN apk --no-cache add build-base

FROM builder AS build1
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp

FROM builder AS build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp

可以使用多个from来执行多构建,同时as来重命名构建的名称。从上一个构建过程的基础上继续构建。

可以指定构建过程

 docker build --target builder -t alexellis2/href-counter:latest .

基于最小镜像

FROM scratch
COPY hello /
CMD ["/hello"]
1.先下载项目后导入到数据库
2.
docker run -p 8080:8080 --rm -v /d/xxl/logs:/data/applogs -d -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.3.16:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai --spring.datasource.username=root --spring.datasource.password=root" --name xxl-job-admin xuxueli/xxl-job-admin:2.4.0

docker-compose

1.示例

新建文件docker-compose.yml

nginx

version: "3"
services:
  nginx:
    image: nginx:latest
    container_name: nginx_lar
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /etc/nginx/conf.d/:/etc/nginx/conf.d/
      - /etc/nginx/cert/:/etc/nginx/cert/ 
      - /home/vite/dist/:/home/vite/dist/ 

mysql

version: "3"
services:
  mysql:
    image: mysql:8.0
    container_name: mysql_lar
    environment:
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3307:3306"
    volumes:
      - /var/mysql:/var/mysql

docker-compose通常是需要多个协同的时候用到

在你的docker-compose编排的服务有需要构建镜像时候。需要先编写dockerfile,否则不需要。

这里取代原来的ubuntu,换成docker官方推荐的alpine镜像

FROM python:alpine3.16

COPY ./requirements.txt /app/requirements.txt

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

RUN apk add --no-cache --virtual build-dependencies \
  python3-dev \
  libffi-dev \
  openssl-dev \
  gcc \
  libc-dev \
  linux-headers \
  freetds-dev \
  make

RUN pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

RUN pip3 install -r /app/requirements.txt

RUN apk del build-dependencies

COPY . /app

WORKDIR /app

CMD [ "uvicorn" ,"main:app","--host" ,"0.0.0.0","--reload"]

## 网络监听端口
EXPOSE 8000

或基于官方的基础包,只保证python可以运行,更精简。 (推荐,编译环境不用自己处理)

slim一般是环境的最小情况,-buster是debain10的发行版

FROM python:slim-buster

COPY ./requirements.txt /app/requirements.txt

RUN pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

RUN pip3 install -r /app/requirements.txt

COPY . /app

WORKDIR /app

CMD [ "uvicorn" ,"main:app","--host" ,"0.0.0.0","--reload"]

## 网络监听端口
EXPOSE 8000

docker-compose编排

version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/app
    environment:
      ENV: development
  # redis:
  #   image: "redis:alpine"

在与docker-compose文件的目录执行命令启动

 docker-compose up -d

整合多个环境

version: "3.9"
services:
  node:
    image: node:16.18.1-slim
    volumes:
      - /D/Users/lg/Desktop/project/web:/root
    tty: true
  redis-alpine:
    container_name: redis
    image: "redis:alpine"
    restart: always
    ports:
      - "6379:6379" 
  mysql:
      # 容器名(以后的控制都通过这个)
    container_name: mysql
      # 重启策略
    restart: always
    image: mysql:5.7
    ports:
      - "3306:3306"
    volumes:
      # 挂挂载配置文件
      - /D/Users/lg/Desktop/conf:/etc/mysql/conf.d
      # 挂载日志
      - /D/Users/lg/Desktop/logs:/logs
      # 挂载数据
      - /D/Users/lg/Desktop/data:/var/lib/mysql
    command: [
          'mysqld',
          '--innodb-buffer-pool-size=80M',
          '--character-set-server=utf8mb4',
          '--collation-server=utf8mb4_unicode_ci',
          '--default-time-zone=+8:00',
          '--lower-case-table-names=1'
        ]
    environment:
      # root 密码
      MYSQL_ROOT_PASSWORD: 123456       
  # java: 
  #   image: openjdk:8-slim
  #   volumes:
  #     - /D/Users/lg/Desktop/project/java:/root
  #   tty: true    
  
  # python:
  #   image: "python:3.9-slim-buster"
  #   volumes:
  #     - /D/Users/lg/Desktop/project/python:/root
  #   tty: true  
  # web:
  #   build: .
  #   ports:
  #     - "8000:8000"
  #   volumes:
  #     - .:/app
  #   environment:
  #     ENV: development
  #   depends_on:
  #     - redis-alpine
  fast:
    build: 
      context: ./web-server
    ports:
      - "8000:8000"
    volumes:
      - .:/app/server
    environment:
      ENV: development   
  web:
    build:
      context: ./web
    ports:
      - 3000:3000
      - 5173:5173
    volumes:
      - ./:/app/web
    command: npm run dev
  

问题

1.由于docker默认网络模式为Bridge模式,其通过localhost访问不到宿主机

参考

docs.docker.com/language/ja… 官方文档