英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论