Golang应用如何通过GitHub、Travis和Heroku部署MongoDB支持的服务
Golang应用如何通过GitHub、Travis和Heroku部署MongoDB支持的服务 我为我的日记应用程序编写了一个服务器,并希望将其部署在 Heroku 上,但前提是它需要通过 Travis CI 的单元测试。
关键在于,我的应用程序还依赖于一个正常运行的 MongoDB 版本。
有没有人之前做过这种 GitHub-Travis-Heroku 的配置?您有什么推荐的资源或项目可以供我学习吗?
2 回复
模拟 MongoDB。
更多关于Golang应用如何通过GitHub、Travis和Heroku部署MongoDB支持的服务的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
对于通过GitHub、Travis CI和Heroku部署MongoDB支持的Golang服务,以下是完整的配置方案:
1. 项目结构示例
my-diary-app/
├── main.go
├── go.mod
├── go.sum
├── .travis.yml
├── Procfile
├── mongodb_test.go
└── .env.example
2. main.go 示例(MongoDB集成)
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/bson"
)
var client *mongo.Client
type DiaryEntry struct {
ID string `bson:"_id,omitempty"`
Title string `bson:"title"`
Content string `bson:"content"`
CreatedAt time.Time `bson:"created_at"`
}
func initMongoDB() {
mongoURI := os.Getenv("MONGODB_URI")
if mongoURI == "" {
mongoURI = "mongodb://localhost:27017"
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var err error
client, err = mongo.Connect(ctx, options.Client().ApplyURI(mongoURI))
if err != nil {
log.Fatal(err)
}
err = client.Ping(ctx, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected to MongoDB!")
}
func diaryHandler(w http.ResponseWriter, r *http.Request) {
collection := client.Database("diary").Collection("entries")
switch r.Method {
case "GET":
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
cursor, err := collection.Find(ctx, bson.M{})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer cursor.Close(ctx)
var entries []DiaryEntry
if err = cursor.All(ctx, &entries); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "Found %d entries", len(entries))
case "POST":
// 处理日记创建逻辑
fmt.Fprint(w, "Entry created")
}
}
func main() {
initMongoDB()
http.HandleFunc("/diary", diaryHandler)
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Printf("Server starting on port %s", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}
3. .travis.yml 配置
language: go
go:
- "1.19"
- "1.20"
services:
- mongodb
env:
- MONGODB_URI=mongodb://localhost:27017
before_script:
- go mod download
script:
- go test -v ./...
- go build -v ./...
deploy:
provider: heroku
api_key:
secure: $HEROKU_API_KEY
app: your-heroku-app-name
on:
branch: main
run:
- "heroku config:set MONGODB_URI=$MONGODB_PROD_URI -a your-heroku-app-name"
4. 单元测试示例(mongodb_test.go)
package main
import (
"context"
"testing"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func TestMongoDBConnection(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
t.Fatalf("Failed to connect to MongoDB: %v", err)
}
defer client.Disconnect(ctx)
err = client.Ping(ctx, nil)
if err != nil {
t.Fatalf("Failed to ping MongoDB: %v", err)
}
}
func TestDiaryCRUD(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
t.Fatalf("Failed to connect: %v", err)
}
defer client.Disconnect(ctx)
collection := client.Database("test_diary").Collection("entries")
// 清理测试数据
collection.Drop(ctx)
// 测试插入
entry := DiaryEntry{
Title: "Test Entry",
Content: "Test Content",
CreatedAt: time.Now(),
}
result, err := collection.InsertOne(ctx, entry)
if err != nil {
t.Fatalf("Failed to insert: %v", err)
}
// 测试查询
var retrievedEntry DiaryEntry
err = collection.FindOne(ctx, bson.M{"_id": result.InsertedID}).Decode(&retrievedEntry)
if err != nil {
t.Fatalf("Failed to find entry: %v", err)
}
if retrievedEntry.Title != "Test Entry" {
t.Errorf("Expected title 'Test Entry', got '%s'", retrievedEntry.Title)
}
}
5. Procfile(Heroku部署)
web: ./my-diary-app
6. 环境变量配置
在Travis CI中设置以下环境变量:
HEROKU_API_KEY: Heroku API密钥MONGODB_PROD_URI: 生产环境MongoDB连接字符串(使用MongoDB Atlas或Heroku Add-on)
在Heroku中设置:
heroku config:set MONGODB_URI=your_mongodb_atlas_uri
7. go.mod 依赖
module my-diary-app
go 1.19
require (
go.mongodb.org/mongo-driver v1.11.0
)
这个配置实现了完整的CI/CD流程:代码推送到GitHub → Travis CI运行单元测试(包括MongoDB测试)→ 测试通过后自动部署到Heroku → Heroku使用配置的MongoDB URI启动应用。

