发布时间: 更新时间:

docker

安装docker

#更新apt包索引
 sudo apt-get update

#安装包以允许apt通过 HTTPS 使用存储库
 sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
    
#添加Docker官方的GPG密钥
 curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

#设置稳定存储库
 echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
#安装最新版本的Docker Engine和containerd
 sudo apt-get update
 sudo apt-get install docker-ce docker-ce-cli containerd.io
 
#hello-world 映像验证
 sudo docker run hello-world
# 使用脚本安装
 curl -fsSL https://get.docker.com -o get-docker.sh
 sudo sh get-docker.sh

Dockerfile

“点击展开go语言示例”

# 这个参考示例来自李文周大佬的bluebell项目

FROM golang:alpine AS builder

# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \
    CGO_ENABLED=0 \
    GOOS=linux \
    GOARCH=amd64

# 移动到工作目录:/build
WORKDIR /build

# 复制项目中的 go.mod 和 go.sum文件并下载依赖信息
COPY go.mod .
COPY go.sum .
RUN go mod download

# 将代码复制到容器中
COPY . .

# 将我们的代码编译成二进制可执行文件 bluebell_app
RUN go build -o bluebell_app .

###################
# 接下来创建一个小镜像
###################
FROM debian:stretch-slim

COPY ./wait-for.sh /
COPY ./templates /templates
COPY ./static /static
COPY ./conf /conf

# 从builder镜像中把/dist/app 拷贝到当前目录
COPY --from=builder /build/bluebell_app /

RUN set -eux; \
	apt-get update; \
	apt-get install -y \
		--no-install-recommends \
		netcat; \
        chmod 755 wait-for.sh

# 声明服务端口
EXPOSE 8084

# 需要运行的命令
#ENTRYPOINT ["/bluebell_app", "conf/config.yaml"]

基础知识参考

以下简介节选自docker文档

  1. **卷(volumes)**存储在由 Docker管理的主机文件系统(在 Linux 上的/var/lib/docker/volumes/ )。卷完全由 Docker 管理,非 Docker 进程不应修改文件系统的这一部分。卷是在 Docker 中持久化数据的最佳方式。
# 将当前目录的相对路径挂载到/app目录中
     volumes:
       - ./:/app

docker compose

安装docker compose

#单独下载和安装 Compose,不装Docker CLI
#下载 Docker Compose 的当前稳定版本
curl -SL https://github.com/docker/compose/releases/download/v2.7.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
 
#对二进制文件应用可执行权限
sudo chmod +x /usr/local/bin/docker-compose

#测试安装
docker compose version
# 脚本
curl -fsSL https://get.docker.com -o get-docker.sh && \
sudo sh get-docker.sh && \
docker -v && \
curl -SL https://github.com/docker/compose/releases/download/v2.7.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose  && \
docker compose version

docker-compose.yaml

“点击展开和折叠代码”

version: '3.7'
services:

  mysql5.7:
    # 镜像名
    image: 'mysql:5.7'
    # 容器名(以后的控制都通过这个)
    container_name: mysql5.7
    # 重启策略
    restart: always
    environment:
      # 时区上海
      TZ: Asia/Shanghai
      # root 密码
      MYSQL_ROOT_PASSWORD: root
      # 初始化数据库(后续的初始化sql会在这个库执行)
      MYSQL_DATABASE: nacos_config
      # 初始化用户(不能是root 会报错, 后续需要给新用户赋予权限)
      MYSQL_USER: nacos
      # 用户密码
      MYSQL_PASSWORD: nacos
      # 映射端口
    ports:
      - 3306:3306
    volumes:
      # 数据挂载
      #- /root/mysql/data/:/var/lib/mysql/
      # 配置挂载
      #- /root/mysql/conf/:/etc/mysql/conf.d/
      # 初始化目录挂载,注意此处我只跑了这个挂载,只是为了说明其他配置不应该数据初始化
      - /root/mysql/init/:/docker-entrypoint-initdb.d/
    command:
      # 将mysql8.0默认密码策略 修改为 原先 策略 (mysql8.0对其默认策略做了更改 会导致密码无法匹配)
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_general_ci
      --explicit_defaults_for_timestamp=true
      --lower_case_table_names=1
    networks:
      - proxy
      
  server:
    image: ghcr.io/USERNAME/server:master
    container_name: server
    ports:
      - 8082:8082
    expose:
      - "8082"
    depends_on:
      - mysql5.7
    restart: always
    volumes:
      - './data:/data/'
    networks:
      - proxy

  web:
    image: ghcr.io/USERNAME/web:master
    container_name: web
    depends_on:
      - server
    restart: always
    ports:
      - 3000:3000
    expose:
      - "3000"
    environment:
      - VIRTUAL_HOST=example.com
      - VIRTUAL_PORT=3000
      - LETSENCRYPT_HOST=example.com
      - [email protected]
    networks:
      - proxy

networks:
  proxy:
    name: nginx-proxy
    external: true

“点击展开nginx-proxy代码”

version: '3'

services:

  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - dhparam:/etc/nginx/dhparam
      - certs:/etc/nginx/certs:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
    restart: always
    networks:
      - nginxproxy
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-proxy-le
    depends_on:
      - nginx-proxy
    volumes:
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - dhparam:/etc/nginx/dhparam:ro
      - certs:/etc/nginx/certs
      - acme:/etc/acme.sh
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ##################
    # 由于LETSENCRYPT证书速率限制,可使用ZeroSSL
    # 注释掉web服务environment中的:
      - LETSENCRYPT_HOST=example.com
      - [email protected]
    # 需添加如下environment
    environment:
      - ACME_CA_URI=https://acme.zerossl.com/v2/DV90
      - ZEROSSL_API_KEY=
    ##################
    restart: always
    networks:
      - nginxproxy
      
volumes:
  conf:
  vhost:
  html:
  dhparam:
  certs:
  acme:

networks:
  nginxproxy:
    name: nginx-proxy
    external: true

基础知识参考

以下简介节选自docker compose文档

  1. Compose 中的网络:

Compose默认为您的应用程序设置单个网络。服务中的每个容器都加入默认网络。例如,假设您的应用程序是在一个名为myapp的目录,运行docker-compose up时会创建一个名为myapp_default的网络,服务中使用web和db的配置创建的容器会以web和db的名字加入myapp_default。

但是,当你使用external(外部网络,例如你有2个或多个docker-compose.yml)时,Compose不会创建默认网络,你必须使用docker network create Your_Nerwork预先创建网络。

注意:文档中示例写法错误,会报错

networks:
  proxy:
    external:
      name: nginx-proxy

应写为:

networks:
  proxy:
    name: nginx-proxy
    external: true

常用命令

Docker命令

docker run [可选参数] imagename              #新建并启动容器    
  --name = "name" 容器取名
  -it 交互模式进入容器
  -d 后台启动容器 注意:一般后台启动要有前台的应用,否则很可能被守护程序杀掉
  -p ip:主机端口:容器端口 #指定端口映射
  -v或--volume /卷名称的路径:/容器中的挂载路径

查看:
docker search xxx                           #搜索dockerhub-镜像
docker images [-a][-q]                      #列出本地主机的-镜像
    -a 显示所有信息
    -q 显示所有id
docker ps [-a][-q]                          #显示当前正在运行的容器
  -a 显示当前运行的容器,并显示历史运行过的容器
  -q 只显示运行容器的编号
docker logs 容器id                          #日志     
docker top 容器id                           #查看容器中进程信息
docker inspect 容器id                       #查看容器的详细信息


操作:
docker build -t tag .                       #构建标签为tag的镜像
docker pull 镜像:版本号                    #拉取-镜像
docker start 容器id                         #启动容器
docker restart 容器id                       #重启容器
docker stop 容器id                          #停止容器
docker kill 容器id                          #强制停止容器
docker rm 容器id                            #删除停止状态的容器
docker rm -f 容器id                         #强制删除容器
docker rmi -f xxx                           #删除单个-镜像
docker rmi -f $(docker images -aq)          #删除所有-镜像
docker stop $(docker ps -a -q)              #停止所有容器运行
docker rm $(docker ps -a -q)                #删除所有容器
docker network rm $(docker network ls -q)   #删除所有network
docker system prune --all --force --volumes #删除一切
exit 容器停止并退出
ctrl+p+q 容器不停止退出
docker exec -it mysql /bin/bash             #进入正在执行的mysql容器
docker exec -it 容器名 /bin/sh              #进入容器
docker exec -it 容器名 -c "apt-get update && apt-get install -y vim"                                        #进入容器安装vim编辑器
docker exec -it 容器名 -c " apk add --update vim"   #进入alpine容器安装vim编辑器
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_name_or_id]             #查看容器ip

从容器拷贝内容到主机:
docker cp 容器id: 路径  主机目的路径 #此处不必进入容器,容器可以是关闭的。
Docker-compose命令

docker-compose up -d                        # 在后台启动服务
docker-compose pull                         # 拉取
    docker-compose -f docker-compose.yml up -d  # 指定docker-compose.yml
    docker-compose -f docker-compose.yml pull   # 指定docker-compose.yml,后同

查看:
docker-compose ps                           # 查看正在运行中的容器
docker-compose ps -a                        # 查看所有编排容器,包括已停止的容器
docker-compose images                       # 列出Compose文件构建的镜像
docker-compose logs                         # 查看日志
docker-compose logs [serviceName]           # 查看某服务的日志 
docker-compose logs -f [serviceName]        # 查看某服务的实时日志

操作:
docker-compose stop                         # 停止服务
docker-compose start                        # 启动已经存在的服务
docker-compose pause [serviceName]          # 暂停服务
docker-compose unpause [serviceName]        # 恢复服务
docker-compose restart [serviceName]        # 重启服务
docker-compose rm                           # 删除所有(停止状态的)服务容器
docker-compose down                         # 删除所有容器
docker-compose down --remove-orphans        # 删除orphans容器


docker-compose config  -q       # 验证(docker-compose.yml)文件配置,当配置正确时,不输出任何内容
docker-compose exec --index=1 [serviceName] sh     # 进入某服务的第1个容器执行命令

docker-compose --help                       # 帮助

actions自动化部署前后端分离项目

参考文章

本文使用github actions + docker compose部署到github container registry(这适用于中小型项目) 附:容器注册平台对比

  1. 准备好你的dockerfile

  2. 使用github actions

    “点击展开示例actions”

    on:
      push:
        branches:
          - master
          
      workflow_dispatch:
    
    env:
      REGISTRY: ghcr.io
      IMAGE_NAME: ${{ github.repository }}
    
    jobs:
              
      build-and-push-image:
        runs-on: ubuntu-latest
        permissions:
          contents: read
          packages: write
        strategy:
          matrix:
            node: [ '14' ]    
    
        steps:
          - name: Checkout repository
            uses: actions/checkout@v2
    
          - name: Setup node
            uses: actions/setup-node@v2
            with:
              node-version: ${{ matrix.node }}
              
          - name: npm install
            run: |
              cd web                       #进入前端dockerfile目录
              npm install       
                  
          - name: Set up QEMU
            uses: docker/setup-qemu-action@v1
          
          - uses: docker/setup-buildx-action@v1
            id: builder1
          
          - uses: docker/setup-buildx-action@v1
            id: builder2
            
          - name: Log in to the Container registry
            uses: docker/login-action@v1
            with:
              registry: ${{ env.REGISTRY }}
              username: ${{ github.actor }}
              password: ${{ secrets.GITHUB_TOKEN }}
              
          # 用于消毒标签,tag是此动作的重要功能之一,本示例没使用,请见文档    
          - name: Extract metadata (tags, labels) for Docker
            id: meta1
            uses: docker/metadata-action@v3
            with:
              images: ghcr.io/username/server      # images地址
          - name: Extract metadata (tags, labels) for Docker
            id: meta2
            uses: docker/metadata-action@v3
            with:
              images: ghcr.io/username/web         # images地址
    
    
          - name: Build and push Docker image 1
            uses: docker/build-push-action@v2
            with:
              builder: ${{ steps.builder1.outputs.name }}        
              context: ./server                # 服务端dockerfile目录
              file: ./server/Dockerfile        # 服务端dockerfile
              push: true
              tags: ${{ steps.meta1.outputs.tags }}
              labels: ${{ steps.meta1.outputs.labels }}
              cache-from: type=gha
              cache-to: type=gha,mode=max
    
          - name: Build and push Docker image 2
            uses: docker/build-push-action@v2
            with:
              builder: ${{ steps.builder2.outputs.name }}        
              context: ./web                  # 前端dockerfile目录
              file: ./web/Dockerfile          # 前端dockerfile
              push: true
              tags: ${{ steps.meta2.outputs.tags }}
              labels: ${{ steps.meta2.outputs.labels }}
              cache-from: type=gha
              cache-to: type=gha,mode=max
      deploy:
        runs-on: ubuntu-latest
        needs: build-and-push-image
        steps:
                  
          - uses: appleboy/ssh-action@master
            with:
              host: ${{ secrets.host }}          #仓库设置中添加Secrets:HOST
              username: root
              password: ${{ secrets.PASSWORD }}  #仓库设置中添加Secrets:PASSWORD
              port: 22
              script: |         
                echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin     # 用户名
                docker-compose -f docker-compose-nginx.yaml -f docker-compose-app.yaml pull   # docker-compose名
                docker-compose -f docker-compose-nginx.yaml -f docker-compose-app.yaml up -d   # docker-compose名
    
    # 此actions许多参数由github自动提供,无需添加,需修改的均已注释
    

  3. 在服务器上完成向 Container registry 验证

具体操作:打开/etc/profile

export CR_PAT=YOUR_TOKEN
source /etc/profile
echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
  1. 新建docker-compose-app.yaml和代理容器docker-compose-nginx.yaml,示例文档。如有不懂,请多看几遍acme-companion和示例文档。最后,Issues中的实例可能会有帮助。
Licensed under CC BY-NC-SA 4.0
最后更新于 2022-07-25