基于Docker-compose部署gin + mysql

文章目录

          • 目录结构
          • 操作命令
          • 遇到的问题
          • 代码
            • Dockerfile
            • docker-compose.yml
            • main.go
          • 运行效果

目录结构
ToDoList
├── api
│   └── api.go
├── config
│   ├── config.go
│   ├── config.json
│   └── my.cnf
├── database
│   └── mysql.go
├── docker-compose.yml
├── Dockerfile
├── go.mod
├── go.sum
├── html
│   └── index.html
├── main.go
├── model
│   └── item.go
├── practice
│   ├── HelloWorld.go
│   └── Practice.go
├── README.md
├── resource
│   ├── css
│   │   └── style.css
│   └── js
│       ├── app.js
│       └── jquery-3.6.0.min.js
├── router
│   └── router.go
├── sql
│   ├── 000001_init_create_item_table.down.sql
│   ├── 000001_init_create_item_table.up.sql
│   └── init
│       └── item.sql
└── wait-for-it.sh

操作命令
docker-compose up
遇到的问题
  • 每次运行项目时,需要执行两次docker-compose up,项目才能运行成功
    第一次执行docker-compose up时,会显示如下的错误dial tcp 172.23.0.02:3306: connect: connection refused,第二次启动时才会正常。原因是尽管在docker-compose.yml添加了depends_on字段,

    depends_on:
      - mysql
    

    但是depends_on字段仅能保证web服务启动时,mysql服务处于Running状态而不是Ready状态,因此需要添加一个脚本文件,检测mysql服务是否处于Ready状态。Docker官网给出的解决方案是在项目中添加一个wait-for-it.sh脚本文件。按照官网建议,添加wait-for-it.sh并修改docker-compose.yaml

    	command: ["./wait-for-it.sh", "mysql:3306", "--", "./main"]
    
  • standard_init_linux.go:219: exec user process caused: no such file or directory

    在执行docker-compose up命令时,会遇到standard_init_linux.go:219: exec user process caused: no such file or directory这个错误。
    在这里插入图片描述
    原因是Dockerfile的第二阶段(运行阶段)选择scratch作为起始镜像,scratch是一个空镜像,并没有/bin/bash命令,具体可参考Docker 底层镜像之选择困难症。
    解决办法是选择alpine作为起始镜像,并利用alpine中的包管理工具apk安装bash

    FROM alpine
    ....
    ....
    RUN apk update && apk add bash
    
  • 数据库初始化

    • 新建数据库
      docker-compose.yml中,使用MYSQL_DATABASE字段新建数据库
       mysql:
       image: mysql:5.7
       restart: always
       environment:
         MYSQL_DATABASE: "todolist"
      
    • 数据库配置
      使用挂载方式添加数据库配置
      volumes:
      - ./config/my.cnf:/etc/conf.d  # 数据库配置
      
    • 新建数据表
      使用挂载方式添加数据表初始化sql
      volumes:
      - ./sql/init:/docker-entrypoint-initdb.d/ # 数据库文件
      
代码
Dockerfile
FROM golang:1.16 as builder

MAINTAINER yanshan

ENV GO111MODULE=on \
    GOPROXY=https://goproxy.cn,direct

WORKDIR $GOPATH/src/ToDoList

COPY . .

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .

RUN mkdir dst
RUN cp main dst && cp wait-for-it.sh dst && cp -r html dst && cp -r resource dst && cp -r config dst

FROM alpine

MAINTAINER yanshan

ENV GIN_MOD=release

WORKDIR /DockerTest

RUN apk update && apk add bash

COPY --from=builder /go/src/ToDoList/dst .

EXPOSE 8080
docker-compose.yml
version: "3.3"
services:
  todolist:
    build: .
    image: todolist
    ports:
      - 8080:8080
    depends_on:
      - mysql
    command: ["./wait-for-it.sh", "mysql:3306", "--", "./main"]
  mysql:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: "todolist"
      MYSQL_ROOT_PASSWORD: "123456"
    ports:
      - 3306:3306
    volumes:
      - ./config/my.cnf:/etc/conf.d  # 数据库配置
      - ./sql/init:/docker-entrypoint-initdb.d/ # 数据库文件
main.go
package main

import (
	. "ToDoList/config"
	. "ToDoList/database"
	. "ToDoList/router"
	"net/http"
)

func main() {
	InitConfig("config/config.json")
	InitDatabase()
	defer SqlDB.Close()

	route := InitRouter()
	// 引入html资源
	route.LoadHTMLGlob("html/*")
	// 引入静态资源
	route.StaticFS("/resource", http.Dir("./resource"))

	route.Run()
}

运行效果

在这里插入图片描述
基于Docker-compose部署gin + mysql_第1张图片

你可能感兴趣的:(Docker,docker)