Reputation: 127
My dockerfile
FROM golang:1.18
WORKDIR /usr/src/app
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
RUN go build -o app
CMD ["./app"]
My docker-compose file
version: "3.7"
services:
api:
container_name: 'api'
build: './'
ports:
- '8080:8080'
volumes:
- './:/go/src/app'
depends_on:
- 'mongodb'
- 'redis'
networks:
- api-network
mongodb:
image: mongo:latest
ports:
- "27017:27017"
volumes:
- ./data/mongo:/data/db
networks:
- api-network
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
- ./data/redis:/data
networks:
- api-network
networks:
api-network:
My go code
package main
import (
"context"
"fmt"
"go-redis/handler"
"net/http"
"os"
"os/signal"
"strconv"
"time"
"github.com/go-redis/redis/v8"
"github.com/go-redis/redis_rate/v9"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/gommon/log"
"gopkg.in/mgo.v2"
)
var limiter *redis_rate.Limiter
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "redis:6379",
})
limiter = redis_rate.NewLimiter(rdb)
e := echo.New()
e.Logger.SetLevel(log.ERROR)
e.Use(middleware.Logger())
e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
Level: -1,
}))
e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
SigningKey: []byte(handler.JWT_KEY),
Skipper: func(c echo.Context) bool {
// Skip authentication for signup and login requests
if c.Path() == "/login" || c.Path() == "/signup" || c.Path() == "/all" || c.Path() == "" {
return true
}
return false
},
}))
e.Use(rateLimiting)
db, err := mgo.Dial("mongodb://mongodb:27017")
if err != nil {
e.Logger.Fatal(err)
}
// Create indices
if err = db.Copy().DB("twitter").C("users").EnsureIndex(mgo.Index{
Key: []string{"email"},
Unique: true,
}); err != nil {
log.Fatal(err)
}
// Initialize handler
h := &handler.Handler{DB: db, Rdb: rdb}
// Routes
e.POST("/signup", h.SignUp)
e.POST("/login", h.SignIn)
e.POST("/follow/:id", h.FollowUser)
e.POST("/posts", h.NewPost)
e.GET("/feed", h.FetchPosts)
e.GET("/users", h.GetUsers)
e.GET("/all", h.AllPosts)
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "hello world")
})
go func() {
// Start server
e.Logger.Fatal(e.Start(":1323"))
}()
closingChannel := make(chan os.Signal, 1)
signal.Notify(closingChannel, os.Interrupt)
<-closingChannel
fmt.Println("starting to shut down the server...")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := e.Shutdown(ctx); err != nil {
fmt.Println("couldnt shut down the server...")
}
}
func rateLimiting(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
res, err := limiter.Allow(c.Request().Context(), "project:123", redis_rate.PerMinute(10))
if err != nil {
return err
}
h := c.Response().Header()
h.Set("RateLimit-Remaining", strconv.Itoa(res.Remaining))
log.Printf("Remaining %d", res.Remaining)
if res.Allowed == 0 {
// We are rate limited.
seconds := int(res.RetryAfter / time.Second)
h.Set("RateLimit-RetryAfter", strconv.Itoa(seconds))
// Stop processing and return the error.
return c.JSON(http.StatusTooManyRequests, "Rate limit exceeded")
}
// Continue processing as normal.
return next(c)
}
}
I get no reacable servers error. When I change hostnames with localhost and run go run main.go
there are no errors but when I want to run go application in docker env and I can't connect to another container from go container.
I thought it was because mongodb is not running. But the go app depend on that so it should be running before go file got executed.
Can you help me with this problem?
Update:
I know it is not related but I changed ports in docker-compose with the same as application port which is 1323.
Still getting this error
{"time":"2022-06-08T09:19:29.1670281Z","level":"FATAL","prefix":"echo","file":"main.go","line":"47","message":"no reachable servers"}
On line 47. I am logging the error when connecting to mongodb.
Upvotes: 1
Views: 341
Reputation: 1412
What is the host OS ?
I've tested your code (commenting out what is related to go-redis/handler
) and it results that the first run is succesfull but the subsequent runs fail (though in this cases, the mongodb container fails to start) giving the exact same error message you get in the go app.
The fault happens when mongodb container is stopped and database get written to disk. If the mount for mongodb container is removed (i.e. use a docker volume) then subsequent runs are ok.
So may be the solution would be to use a docker volume in your docker compose setup.
EDIT: Unless the OP add more context, this seems as a duplicate of this and the answer is indeed related to the use of mounted volume for data persistence.
Upvotes: 1