前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker入门:使用Dockerfile构建Docker镜像

Docker入门:使用Dockerfile构建Docker镜像

作者头像
KenTalk
发布2023-04-07 15:45:55
6.9K0
发布2023-04-07 15:45:55
举报
文章被收录于专栏:Ken的杂谈Ken的杂谈

一、前言

我们通过Docker build命令以及Dockerfile把我们的应用以及应用依赖的资源及环境打包成Docker镜像,帮助我们在各种我们需要的环境中部署应用,让我们不再担心环境差异带来的应用部署问题

1、本篇主要内容

  • Docker build命令介绍
  • Dockerfile文件及常用参数介绍
  • Docker build+Dockerfile制作Docker镜像
  • Docker镜像发布到公共仓库

2、环境信息

环境

说明

Docker

Docker CE 20.10.21

Docker Desktop

4.14

Docker Golang镜像

1.19.4

Golang

1.19.4

Windows

Windows 11

二、镜像制作

创建镜像制作根目录,例如:d:\docker\helloworld(Windows),~/docker/helloworld(macOS),后续所有文件都放在该目录中

1、准备应用代码

用golang写的一个简单http server,监听8000端口,默认输出helloworld,新建helloworld.go保存以下代码

代码语言:javascript
复制
package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    log.Println("received request from", r.RemoteAddr, r.URL.Path[1:])
    var welcome = r.URL.Path[1:]
    if len(welcome) == 0 {
        welcome = "World"
    }
    fmt.Fprintf(w, "Hello, %s!  ---ken.io", welcome)
}

func main() {
    http.HandleFunc("/", handler)
    log.Println("starting server on port 8000")
    log.Fatal(http.ListenAndServe(":8000", nil))
}

2、编写Dockerfile文件

Dockerfile 是用于Docker镜像的文本文件(无后缀名),包含所有我们需要用于创建Docker镜像的命令,例如:指定基础镜像、安装依赖的软件、配置环境变量、添加文件和目录、定义容器启动时运行的命令等

代码语言:javascript
复制
# 使用官方提供的 Go 镜像作为基础镜像
FROM golang:1.19.4

# 将工作目录设置为 /app
WORKDIR /app

# 将当前目录下的所有内容复制到 /app 下
COPY . /app

# 允许宿主机访问容器的 8000 端口
EXPOSE 8000

# 设置容器进程为:go run helloworld.go
CMD go run helloworld.go

3、编译镜像文件

代码语言:javascript
复制
#进入目录
d: && cd d:\docker\helloworld

#编译镜像(默认为latest)(注意结尾一定要加.)
docker build -t helloworld .

#编译指定版本镜像(注意结尾一定要加.)
docker build -t helloworld:1.0 .

#查看本地镜像
docker images

#镜像列表
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
helloworld   1.0       c56b0d613f1a   1 minutes ago    992MB
helloworld   latest    c56b0d613f1a   1 minutes ago    992MB

注意看这里的IMAGE ID是一样的,我们虽然执行了两次Docker build,但是Dockerfile并无变化,Docker很机智的把后创建的Repository Tag指向了同一个Source Image,不信你可以看一下两次docker build命令的输出结果,writing image的sha256值是一模一样的

4、创建并启动容器

代码语言:javascript
复制
#创建并启动容器(默认使用latest版本)
docker run -d --name myhello -p 8000:8000 helloworld 

#查看已启动的容器
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS         PORTS                    NAMES
1438022c3ae4   helloworld   "/bin/sh -c 'go run …"   6 seconds ago   Up 5 seconds   0.0.0.0:8000->8000/tcp   myhello

看到helloworld的容器且状态为UP,说明容器已正常启动,此时访问 http://localhost:8000/ 将会看到HelloWorld

也可以试试访问http://localhost:8000/ken,将会看到不一样的内容

三、推送镜像到官方仓库

1、注册Docker账号

访问 https://hub.docker.com/signup ,注册自己的Docker账号

截图中的邮箱仅为示例,实际并不存在

2、登录Docker账号

在Docker Client或者Docker Desktop中登录自己的账号,这里使用Docker Client做演示

代码语言:javascript
复制
#登录命令
docker login

#根据命令号交互输入注册时的账号密码即可成功登录
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: kentalk
Password:
Login Succeeded

Logging in with your password grants your terminal complete access to your account.
For better security, log in with a limited-privilege personal access token. Learn more at https://docs.docker.com/go/access-tokens/

3、推送镜像

基于已有本地Docker镜像创建符合Docker规范的Repository: {username}/{repository}

代码语言:javascript
复制
docker tag helloworld  kentalk/helloworld
docker tag helloworld:1.0  kentalk/helloworld:1.0

命令执行后再查看下本地镜像

代码语言:javascript
复制
#查看本地镜像
docker images

#镜像列表
REPOSITORY           TAG       IMAGE ID       CREATED             SIZE
kentalk/helloworld   1.0       c56b0d613f1a   About an hour ago   992MB
kentalk/helloworld   latest    c56b0d613f1a   About an hour ago   992MB
helloworld           1.0       c56b0d613f1a   About an hour ago   992MB
helloworld           latest    c56b0d613f1a   About an hour ago   992MB

这里注意IMAGE ID并无变化,新的Repository只是基于本地镜像的引用

推送镜像到docker hub

代码语言:javascript
复制
#执行命令
docker push kentalk/helloworld

#输出示例
Using default tag: latest
The push refers to repository [docker.io/kentalk/helloworld]
c5aba32dc2d8: Pushed
7bc6949046cf: Pushed
3b5b867f93c1: Mounted from library/golang
caf157c05987: Mounted from library/golang
6424bc9210da: Mounted from library/golang
b77487480ddb: Mounted from library/golang
cd247c0fb37b: Mounted from library/golang
cfdd5c3bd77e: Mounted from library/golang
870a241bfebd: Mounted from library/golang
latest: digest: sha256:3fc3bd029a7dd0……caf7fe1601eb27424 size: 2209

虽然我们本地镜像有992MB,但是推送只消耗了2209字节,这是因为我们是基于官方镜像的加工,只需要把Dockerfile上传即可,并不需要把我们本地的镜像文件完整的上传

推送完成后,可以在跟人账号https://hub.docker.com/u/kentalk页看到推送的镜像

也可以直接访问 https://hub.docker.com/r/kentalk/helloworld/tags,查看Repository下的所有Tag

这里可以通过Manage Repository修改镜像介绍等,也可以在Overview查看镜像介绍等信息,这里就不再赘述

4、获取远端镜像

删除本地kentalk开头镜像

代码语言:javascript
复制
docker image rm kentalk/helloworld:latest
docker image rm kentalk/helloworld:1.0

停用并删除已有helloworld容器

代码语言:javascript
复制
docker stop myhello
docker rm myhello

从远端拉取镜像并启动kentalk/helloworld容器

代码语言:javascript
复制
#执行命令
docker run -d --name myhello -p 8000:8000 kentalk/helloworld 

#输出内容
Unable to find image 'kentalk/helloworld:latest' locally
latest: Pulling from kentalk/helloworld
Digest: sha256:3fc3bd029a7dd0011ff97c4e2c108296701342c0452886fcaf7fe1601eb27424
Status: Downloaded newer image for kentalk/helloworld:latest
8b7da7d0cc249d00b46739b83d597d27b9c665307a74e42fde8ac5fe67b7edf4

查看镜像运行情况

代码语言:javascript
复制
#查看所有容器
docker ps -a

#容器List
CONTAINER ID   IMAGE                COMMAND                  CREATED              STATUS              PORTS                    NAMES
8b7da7d0cc24   kentalk/helloworld   "/bin/sh -c 'go run …"   About a minute ago   Up About a minute   0.0.0.0:8000->8000/tcp   myhello

访问 http://localhost:8000/ken 将会看到:

四、备注

1、Docker build常用参数

参数

说明

-t

指定Repository以及Tag,例如helloworld:1.0

-f

指定Dockerfile路径,Dockerfile不在当前目录时使用

—no-cache

常见镜像的过程中不使用Build Cache构建镜像

—pull

构建镜像时总是拉取Base Image的最新版本

2、Dockerfile常用指令

指令

描述

FROM

指定基础镜像,可以指定多个,指定多个基础镜像时,编译时也会生成对应的多个镜像

MAINTAINER

指定镜像维护人信息,制作人根据自己情况指定

WORKDIR

设置工作目录,后续的RUN、COPY、CMD等命令都将在工作目录下运行

RUN

构建镜像时运行命令,可以用他安装软件等等

COPY

拷贝文件或目录到镜像中

ADD

拷贝文件或目录到镜像中,如果源文件是gizp等压缩文件,会被自动解压到目标目录

ENV

设置环境变量

USER

为RUN、CMD 和 ENTRYPOINT 执行命令指定运行用户

ARG

由外部启动时必须传入的参数,在容器启动时用–build-arg传递参数

EXPOSE

声明容器暴露给宿主机的端口,可以是一个或者多个以空格间隔

HEALTHCHECK

容器中服务健康检查

VOLUME

用于指定持久化目录

CMD

运行容器时执行,启动的进程会作为容器的主进程,如果有多个CMD指令,如果指定了多个,最后一个生效,这种机制保障了我们基于Base Image制作镜像时可以运行自己想要的程序作为容器主进程

ENTRYPOINT

运行容器时执行,如果有多个 ENTRYPOINT 命令,作用相当于CMD,可以执行比CMD更复杂的命令,如果指定了多个,只有最后一个生效

3、本文参考


本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-12-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
    • 1、本篇主要内容
      • 2、环境信息
      • 二、镜像制作
        • 1、准备应用代码
          • 2、编写Dockerfile文件
            • 3、编译镜像文件
              • 4、创建并启动容器
              • 三、推送镜像到官方仓库
                • 1、注册Docker账号
                  • 2、登录Docker账号
                    • 3、推送镜像
                      • 4、获取远端镜像
                      • 四、备注
                        • 1、Docker build常用参数
                          • 2、Dockerfile常用指令
                            • 3、本文参考
                            相关产品与服务
                            容器镜像服务
                            容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档