概念
应用场景:
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
作用:Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件
Docker 包括三个基本概念:
- 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
什么是 Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
Docker Compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
命令
docker容器
docker 查看docker客户端的所有命令选项
docker command --help 查看指定的docker命令使用方法
docker run 启动容器 -i 交互式操作 -t 终端 /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash 退出exit
-P :是容器内部端口随机映射到主机的端口。
-p : 是容器内部端口绑定到指定的主机端口。
--name 标识来命名容器
docker ps -a 查看所有的容器 -l 查看最后一次创建的容器
docker ps 查看正在运行的容器
docker start [ID或者名字]
docker stop [ID或者名字]
docker restart [ID或者名字]
docker exec -it [ID或者名字] /bin/bash
docker rm -f [ID或者名字]
docker logs [ID或者名字] 可以查看容器内部的标准输出
docker inspect [ID或者名字] 查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
docker top [ID或者名字] 来查看容器内部运行的进程
docker port 命令可以让我们快捷地查看端口的绑定情况
docker 镜像
docker images 列出本地主机上的镜像
docker pull 镜像名
docker search 镜像名
docker rmi [ID或者名字]
docker build -t :指定要创建的目标镜像名
. :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
docker tag 命令,为镜像添加一个新的标签。
场景
容器连接
新建网络
下面先创建一个新的 Docker 网络。
$ docker network create -d bridge test-net
运行一个容器并连接到新建的 test-net 网络:
$ docker run -itd --name test1 --network test-net ubuntu /bin/bash
打开新的终端,再运行一个容器并加入到 test-net 网络:
$ docker run -itd --name test2 --network test-net ubuntu /bin/bash
github
docker login
docker logout
docker tag centos_go:7.9.2009 dockerhubwtj/centos_go:7.9.2009
docker push dockerhubwtj/centos_go:7.9.2009
dockerfile
FROM 指定基础镜像,用于后续的指令构建。
//FROM centos:7.9.2009
MAINTAINER 指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令)
//MAINTAINER John Doe <johndoe@example.com>
LABEL 添加镜像的元数据,使用键值对的形式。
//LABEL version="1.0" description="My Docker Image"
RUN 在构建过程中在镜像中执行命令。
//RUN yum -y install curl
CMD 指定容器创建时的默认命令。(可以被覆盖)
//CMD ["npm", "start"]
ENTRYPOINT 设置容器创建时的主要命令。(不可被覆盖)
//ENTRYPOINT ["python", "app.py"]
EXPOSE 声明容器运行时监听的特定网络端口。
//EXPOSE 8080
ENV 在容器内部设置环境变量。
//ENV MY_VAR=myvalue
ADD 将文件、目录或远程URL复制到镜像中。
//ADD app.tar.gz /usr/src/app
COPY 将文件或目录复制到镜像中。
//COPY index.html /var/www/html
VOLUME 为容器创建挂载点或声明卷。
//VOLUME /data
WORKDIR 设置后续指令的工作目录。
//WORKDIR /app
USER 指定后续指令的用户上下文。
//USER appuser
ARG 定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。
//ARG ENVIRONMENT=production
ONBUILD 当该镜像被用作另一个构建过程的基础时,添加触发器。
//ONBUILD COPY . /app
STOPSIGNAL 设置发送给容器以退出的系统调用信号。
//STOPSIGNAL SIGINT
HEALTHCHECK 定义周期性检查容器健康状态的命令。
//HEALTHCHECK CMD curl -f http://localhost/ || exit 1
SHELL 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。
//SHELL ["/bin/bash", "-c"]
docker build -t [镜像名字] .
docker run -d -it --name [容器名字] -p 9999:9999 [镜像id或名字]
docker-compose
安装
手动安装
直接去github上找到稳定版本2.20.3
然后下载到服务器/usr/local/bin/路径下然后改名docker-compose之后
sudo chmod +x /usr/local/bin/docker-compose给权限
然后测试 docker-compose version
坑就是现在官网确实有v2版本但是我下载的不是然后命令不需要不加-的 还是加上-
命令
# 默认使用docker-compose.yml构建镜像
$ docker-compose build
$ docker-compose build --no-cache # 不带缓存的构建
# 指定不同yml文件模板用于构建镜像
$ docker-compose build -f docker-compose1.yml
# 列出Compose文件构建的镜像
$ docker-compose images
# 启动所有编排容器服务
$ docker-compose up -d
# 查看正在运行中的容器
$ docker-compose ps
# 查看所有编排容器,包括已停止的容器
$ docker-compose ps -a
# 进入指定容器执行命令
$ docker-compose exec nginx bash
$ docker-compose exec web python manage.py migrate --noinput
# 查看web容器的实时日志
$ docker-compose logs -f web
# 停止所有up命令启动的容器
$ docker-compose down
# 停止所有up命令启动的容器,并移除数据卷
$ docker-compose down -v
# 重新启动停止服务的容器
$ docker-compose restart web
# 暂停web容器
$ docker-compose pause web
# 恢复web容器
$ docker-compose unpause web
# 删除web容器,删除前必需停止stop web容器服务
$ docker-compose rm web
# 查看各个服务容器内运行的进程
$ docker-compose top
练习
1.写一个main的小案例
package main
import (
"context"
"encoding/json"
"flag"
"fmt"
"github.com/go-redis/redis/v8"
"io"
"log"
"net/http"
"os"
"time"
)
var (
redisClient *redis.Client
cfg Config
)
type Config struct {
RedisAddr string `json:"redisAddr"`
Password string `json:"Auth"`
}
func readCfg(cfgpath string) {
bytes, err := os.ReadFile(cfgpath)
if err != nil {
log.Fatal("Failed to read config file:", err)
}
c := Config{}
err = json.Unmarshal(bytes, &c)
if err != nil {
log.Fatal("Failed to parse config file:", err)
}
cfg = c
//fmt.Println(cfg)
}
func main() {
cfgpath := flag.String("cfg", "./config.json", "configuration file path")
flag.Parse()
readCfg(*cfgpath)
redisClient = redis.NewClient(&redis.Options{
Addr: cfg.RedisAddr,
Password: cfg.Password,
DB: 0,
})
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Second)
defer cancel()
num, err := redisClient.Incr(ctx, "num").Result()
if err != nil {
log.Println("Failed to increment value in Redis:", err)
http.Error(writer, "Internal Server Error", http.StatusInternalServerError)
return
}
io.WriteString(writer, fmt.Sprintf("Number of visits: %d", num))
})
err := http.ListenAndServe(":9999", nil)
if err != nil {
log.Fatal("HTTP server error:", err)
}
}
2.命令行读取配置文件,所以写一个配置文件
{
"redisAddr": "XXX:6379",
"Auth": "XXX"
}
3.上传到服务器编写docker-compose.yml文件
version: '1'
services:
redis:
image: "redis"
websvr:
# build: . #编译方式
image: "gowebservice" # 通过已经有的影像方式
volumes:
- .:/goDemo # 挂在目录
ports:
- "9999:9999"
command: -cfg ./test.json # 指定配置文件
depends_on:
- redis
两者的区别,就是image方式直接引用,build方式需要每次生成影像
如果是开发调试,可以采用build方式,如果是测试、演示,可以采用image方式