Go应用程序(在Docker容器中)在页面上没有反映出更改?

huangapple go评论135阅读模式
英文:

Go app (in docker container) not reflecting changes on page?

问题

我是你的中文翻译助手,以下是翻译好的内容:

我刚开始学习Go语言,但遇到一个烦人的问题,即在代码更改后,除非我在启动容器时再次执行--build命令,否则页面上不会反映出更改。这种情况正常吗?我正在运行Windows 10,Go 1.19,AMD,Docker Desktop/Compose。

如果我将"Hello, World!"更改为其他字符串,然后按下CTRL+C停止运行的应用程序,然后运行docker-compose up命令,页面上不会反映出更改,即使我清除了浏览器缓存并使用隐身窗口。然而,如果我运行docker-compose up --build命令,更改将会反映出来。

提醒一下,我刚开始学习Go语言,这种行为正常吗?我每次都需要在docker-compose中重新构建项目才能看到更改吗?或者你在我的代码中看到了什么不对劲的地方吗?我正在按照几年前的Udemy课程进行学习,所以每一步都需要解决一个新的问题,因为它的工作方式与示例不同。

他们建议使用Air进行热重载,但我也遇到了问题,它也无法正常工作,不过我已经在GitHub上提交了一个问题。

以下是各个文件的代码:

main.go

package main

import (
	"ambassador/src/database"

	"github.com/gofiber/fiber/v2"
)

func main() {

	// 连接数据库
	database.Connect()

	// 迁移数据库中的表
	database.AutoMigrate()

	// 创建一个基于Express.js的新的fiber应用
	app := fiber.New()

	app.Get("/", func(c *fiber.Ctx) error {
		return c.SendString("Hello, World!")
	})

	app.Listen(":3000")
}

Dockerfile

FROM golang:1.19

WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download

COPY . .

# 使用air进行实时的Go热重载
# 这个方法不起作用,使用go install代替
# RUN curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b $(go env GOPATH)/bin

# Air对我来说不起作用。已经在GitHub上提交了问题。暂时跳过
# RUN go install github.com/cosmtrek/air@latest
# CMD ["air"]

CMD ["go", "run", "main.go"]

docker-compose.yaml

version: '3.9'
services:
    backend:
        build: .
        ports:
            - 8000:3000
        # volumes:
        #   - .:/app
        depends_on:
            - db

    db:
        image: mysql:5.7.22
        restart: always
        environment:
            MYSQL_DATABASE: ambassador
            MYSQL_USER: root
            MYSQL_PASSWORD: root
            MYSQL_ROOT_PASSWORD: root
        volumes:
            - .dbdata:/var/lib/mysql
        ports:
            - 33066:3306

src > database > db.go

package database

import (
	"ambassador/src/models"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB

func Connect() {
	var err error
	DB, err = gorm.Open(mysql.Open("root:root@tcp(db:3306)/ambassador"), &gorm.Config{})

	if err != nil {
		panic("无法连接到数据库!")
	}
}

func AutoMigrate() {
	DB.AutoMigrate(models.User{})
}

src > models > user.go

package models

type User struct {
	Id           uint
	FirstName    string
	LastName     string
	Email        string
	Password     string
	IsAmbassador bool
}

go.mod

module ambassador

go 1.19

require github.com/gofiber/fiber/v2 v2.36.0

require (
	github.com/andybalholm/brotli v1.0.4 // indirect
	github.com/go-sql-driver/mysql v1.6.0 // indirect
	github.com/jinzhu/inflection v1.0.0 // indirect
	github.com/jinzhu/now v1.1.5 // indirect
	github.com/klauspost/compress v1.15.0 // indirect
	github.com/valyala/bytebufferpool v1.0.0 // indirect
	github.com/valyala/fasthttp v1.38.0 // indirect
	github.com/valyala/tcplisten v1.0.0 // indirect
	golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
	gorm.io/driver/mysql v1.3.5 // indirect
	gorm.io/gorm v1.23.8 // indirect
)

相同的代码也包含在我IDE的这个截图中。

英文:

I'm new to Go, but having an annoying issue where changes in the code are not reflected on the page, unless I do another --build when I bring up the container. Is this normal? I'm running`Windows 10, Go 1.19, AMD, Docker Desktop/Compose.

If I change "Hello, World!" to some other string, CTRL+C the running app, and then run docker-compose up, the changes are NOT reflected on the page, even after clearing browser cache and using an incognito window. HOWEVER, if I run docker-compose up --build, the changes WILL be reflected.

Reminder I'm new to Go, but is this normal behaviour? Do I have to re-build the project in docker-compose each time to see the changes? Or do you see anything "off" in my code? I'm following a few year old Udemy course, so of course every step there's a new "thing" to troubleshoot as it doesn't work as shown eye roll

They suggest using Air for hot-reloading, which I'm also having an issue with as IT'S not working either, however I've opened a GitHub issue for that.

Here is the code from the various files:

main.go

package main

import (
	"ambassador/src/database"

	"github.com/gofiber/fiber/v2"
)

func main() {

	// Connect to the database
	database.Connect()

	// Migrate tables in the database
	database.AutoMigrate()

	// Create a new fiber app, which is based on Express.js
	app := fiber.New()

	app.Get("/", func(c *fiber.Ctx) error {
		return c.SendString("Hello, World!")
	})

	app.Listen(":3000")
}

Dockerfile

FROM golang:1.19

WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download

COPY . .

# Use air for live go hot-reloading
# This one doesn't work, use go install instead
# RUN curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b $(go env GOPATH)/bin

# Air does not work for me. Opening github issue. Skip for now
# RUN go install github.com/cosmtrek/air@latest
# CMD ["air"]

CMD ["go", "run", "main.go"]

docker-compose.yaml

version: '3.9'
services:
    backend:
        build: .
        ports:
            - 8000:3000
        # volumes:
        #   - .:/app
        depends_on:
            - db

    db:
        image: mysql:5.7.22
        restart: always
        environment:
            MYSQL_DATABASE: ambassador
            MYSQL_USER: root
            MYSQL_PASSWORD: root
            MYSQL_ROOT_PASSWORD: root
        volumes:
            - .dbdata:/var/lib/mysql
        ports:
            - 33066:3306

src > database > db.go

package database

import (
	"ambassador/src/models"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB

func Connect() {
	var err error
	DB, err = gorm.Open(mysql.Open("root:root@tcp(db:3306)/ambassador"), &gorm.Config{})

	if err != nil {
		panic("Could not connect with the database!")
	}
}

func AutoMigrate() {
	DB.AutoMigrate(models.User{})
}

src > models > user.go

package models

type User struct {
	Id           uint
	FirstName    string
	LastName     string
	Email        string
	Password     string
	IsAmbassador bool
}

go.mod

module ambassador

go 1.19

require github.com/gofiber/fiber/v2 v2.36.0

require (
	github.com/andybalholm/brotli v1.0.4 // indirect
	github.com/go-sql-driver/mysql v1.6.0 // indirect
	github.com/jinzhu/inflection v1.0.0 // indirect
	github.com/jinzhu/now v1.1.5 // indirect
	github.com/klauspost/compress v1.15.0 // indirect
	github.com/valyala/bytebufferpool v1.0.0 // indirect
	github.com/valyala/fasthttp v1.38.0 // indirect
	github.com/valyala/tcplisten v1.0.0 // indirect
	golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
	gorm.io/driver/mysql v1.3.5 // indirect
	gorm.io/gorm v1.23.8 // indirect
)

The same code is included in this screenshot of my IDE.

答案1

得分: 3

Go不是一种脚本语言,需要重新构建和重启应用程序才能应用更改。

您可以使用Golang fresh来重新构建和重启您的应用程序。

https://github.com/gravityblast/fresh

将以下内容添加到您的Dockerfile中:

RUN go install github.com/pilu/fresh@latest
...
CMD ["fresh"]
英文:

Go isn’t a script language and needs in rebuild and restart application to apply changes

You can use Golang fresh for rebuild and restart your app

https://github.com/gravityblast/fresh

Add this to your Dockerfile

RUN go install github.com/pilu/fresh@latest
...
CMD [ "fresh" ]

答案2

得分: 1

你没有将任何文件挂载到容器中,只是在构建镜像时复制它们一次。这就是为什么除非你构建或将新文件复制到容器中,否则你看不到任何更改。

你已经在docker-compose.yaml中注释掉了一个卷,但如果你取消注释这些行,你应该会看到更改反映出来而无需重新构建。

英文:

You are not mounting any files into your container, only copying them once on image build. This is why you are not seeing anychanges unless you build, or copy new files into the container.

You've already commented out a volume from your docker-compose.yaml, but if you uncomment those lines you should see that changes are reflected without rebuilding.

答案3

得分: 0

回答你的问题 - 不,当运行docker-compose文件时,你不需要添加--build标签。这与Go语言无关,只与docker容器的工作逻辑有关。

如果我们谈到实时重载的问题,那么问题出在docker在主机系统和容器之间进行文件共享的技术上。

当我尝试使用不是Docker Desktop而是像Rancher这样的替代品时,我也遇到了同样的问题,Rancher甚至通过moby使用docker CLI。当我切换回使用gRPC FUSE、osxfs和VirtioFS的原始Docker Desktop时,所有这些问题都得到了解决。

我不知道这个功能在Windows上是如何实现的,但我相信你可以深入研究这个方向。

英文:

To answer your original question — NO, you DO NOT need to add the --build tag when running up your docker-compose file. It doesn't relate to Go, it relates only to docker containers working logic.

If we come to the live-reload problem then the problem is with the technology docker uses for file sharing between a host system and containers.

I have had the same issues on mac when tried to use not the Docker Desktop but an alternative like Rancher which even uses docker CLI via moby. When I switched back to the original Docker Desktop which uses gRPC FUSE, osxfs, and VirtioFS — with all of them worked like a charm.

I don't know how this feature is implemented on windows, but I'm sure you could dig into this direction.

huangapple
  • 本文由 发表于 2022年8月7日 15:17:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/73265597.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定