使用Docker镜像构建Go应用是目前比较流行的一种构建和部署应用的方式。下面,我将详细讲解如何使用Docker镜像构建Go应用的实现方法,包括两条示例说明。
1. 环境准备
在进行Docker镜像构建之前,需要进行以下环境准备:
- 安装Docker:Docker可以在官网上下载并安装(https://www.docker.com/get-started)。
- 安装Go:Go可以在官网上下载并安装(https://golang.org/dl/)。
2. 创建Go应用
首先,需要创建一个简单的Go应用,例如一个“Hello World”程序。在本例中,创建一个名为main.go
的文件,内容如下:
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}
3. 创建Dockerfile
接下来,需要创建一个Dockerfile文件,用于构建Docker镜像。在本例中,创建一个名为Dockerfile
的文件,内容如下:
# 使用官方的 Golang 镜像作为构建环境
FROM golang:alpine AS builder
# 设置工作目录
WORKDIR /app
# 将代码加入镜像中
COPY . .
# 构建二进制文件
RUN GOOS=linux GOARCH=amd64 go build -o main main.go
# 使用最小化的 alpine 镜像作为运行环境
FROM alpine:latest
# 设置工作目录
WORKDIR /app
# 从之前构建的镜像中将二进制文件复制到 alpine 镜像中
COPY --from=builder /app/main .
# 运行二进制文件
CMD ["./main"]
以上Dockerfile包含了两个部分。第一部分以golang:alpine镜像为基础创建一个builder,设置工作目录,将代码加入镜像中,然后构建二进制文件。第二部分以alpine:latest镜像为基础创建一个新的镜像,将之前构建的二进制文件从builder镜像中复制到新的镜像中,并设置工作目录和运行二进制文件。
4. 构建Docker镜像
在Dockerfile和Go程序创建完成后,进入Dockerfile所在目录,执行以下命令来构建Docker镜像:
docker build -t my-go-application .
其中,my-go-application
是镜像的名称,.
表示Dockerfile所在的当前目录。
5. 运行Docker镜像
构建Docker镜像完成后,可以使用以下命令来运行该镜像:
docker run -it --rm my-go-application
其中,-it
参数表示以交互模式和终端模式运行容器,--rm
参数表示容器停止后自动删除。
6. 示例1:使用Docker Compose构建多容器Go应用
在本示例中,将创建一个包含多个容器的Docker Compose项目,其中包括Go应用、MySQL数据库和phpMyAdmin数据库管理工具。
6.1 创建一个新的Go应用
首先,创建一个名为main.go
的文件,内容如下:
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
"os"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "root:password@tcp(db:3306)/testdb")
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
以上Go应用连接到一个名为testdb
的MySQL数据库,并在/
路径下返回Hello World!
字符串。
6.2 创建Docker Compose文件
接下来,创建一个名为docker-compose.yml
的文件,内容如下:
version: "3.9"
services:
app:
build: .
ports:
- "8080:8080"
depends_on:
- db
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: testdb
phpmyadmin:
image: phpmyadmin/phpmyadmin
depends_on:
- db
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: password
ports:
- "8081:80"
以上Docker Compose文件定义了三个服务:
app
服务:使用Dockerfile构建Go应用,并将容器内的8080端口映射到主机的8080端口。db
服务:使用MySQL官方镜像创建一个MySQL数据库容器,并设置数据库的root密码为password
,创建一个名为testdb
的数据库。phpmyadmin
服务:使用phpMyAdmin官方镜像创建一个PHPMyAdmin容器,连接到db
服务之上,并将容器内的80端口映射到主机的8081端口。
6.3 运行Docker Compose
在Docker Compose文件所在目录下,使用以下命令来启动所有的容器:
docker-compose up
运行完上述命令后,访问http://localhost:8080
和http://localhost:8081
可以分别查看Go应用和phpMyAdmin数据库管理工具。
6.4 停止Docker Compose
使用以下命令来停止Docker Compose:
docker-compose down
7. 示例2:使用Docker Swarm构建Go应用
在本示例中,将创建一个包含多个服务的Docker Swarm集群,其中包括Go应用和MongoDB数据库。
7.1 创建一个新的Go应用
首先,创建一个名为main.go
的文件,内容如下:
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://mongo:27017"))
if err != nil {
log.Fatal(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
collection := client.Database("testdb").Collection("test")
result, err := collection.InsertOne(context.Background(), map[string]string{"name": "John"})
if err != nil {
log.Fatal(err)
}
fmt.Fprintf(w, "Inserted document with ID %v\n", result.InsertedID)
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
以上Go应用连接到一个名为testdb
的MongoDB数据库,并在/
路径下向test
集合插入一个名为John
的文档。
7.2 创建Docker Compose文件
接下来,创建一个名为docker-compose.yml
的文件,内容如下:
version: "3.9"
services:
app:
image: go-app
deploy:
replicas: 4
ports:
- "8080:8080"
environment:
MONGODB_URI: mongodb://mongo:27017
networks:
- webnet
mongo:
image: mongo
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
networks:
- webnet
networks:
webnet:
以上Docker Compose文件定义了两个服务:
app
服务:使用Docker镜像构建Go应用,并在Docker Swarm集群中启动4个实例,将容器内的8080端口映射到主机的8080端口,并将MongoDB的URI设置为环境变量。mongo
服务:使用MongoDB官方镜像创建一个MongoDB数据库容器,并设置数据库的root用户名和密码。
7.3 创建Docker Swarm集群
在执行以下命令之前,需要确保已经初始化Docker Swarm集群:
docker swarm init
7.4 构建和发布Docker镜像
首先,使用以下命令将Go应用构建成Docker镜像,并将其上传至Docker Hub:
docker build -t my-go-app .
docker tag my-go-app:latest my-dockerhub-account/my-go-app:latest
docker push my-dockerhub-account/my-go-app:latest
其中,my-dockerhub-account
为Docker Hub账户名。
7.5 部署Docker服务
接着,使用以下命令创建一个名为webnet
的覆盖网络,并启动app
和mongo
服务:
docker network create --driver overlay webnet
docker stack deploy -c docker-compose.yml my-application
其中,my-application
为服务的名称。
7.6 检查服务状态
使用以下命令检查已经启动的服务状态:
docker stack ps my-application
如果一切正常,则应该可以看到在Docker Swarm集群中启动了4个Go服务实例。当访问http://localhost:8080
时,可以看到Go应用向MongoDB数据库中插入一个文档。
7.7 清除服务
使用以下命令清除所有服务:
docker stack rm my-application
docker network rm webnet
总结
本文分别介绍了使用Docker镜像构建Go应用的基本步骤、使用Docker Compose构建多容器Go应用的示例,以及使用Docker Swarm构建Go应用的示例。使用Docker镜像构建Go应用可以使得应用打包、部署和迁移更加方便、快速和高效。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用Docker镜像构建Go应用的实现方法 - Python技术站