now up and running using docker
This commit is contained in:
@@ -1,32 +1,26 @@
|
||||
# Use official Golang image
|
||||
FROM golang:1.20-alpine as builder
|
||||
# Stage 1: Build the Go binary
|
||||
FROM golang:1.21-alpine AS builder
|
||||
|
||||
# Set the Current Working Directory inside the container
|
||||
WORKDIR /app
|
||||
|
||||
# Copy go mod and sum files
|
||||
# Copy go.mod and go.sum first
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
# Download all dependencies. Dependencies will be cached if the go.mod and go.sum are not changed
|
||||
RUN go mod download
|
||||
|
||||
# Copy the source code into the container
|
||||
COPY src src
|
||||
# Copy the rest of the code
|
||||
COPY . .
|
||||
|
||||
# Build the Go app
|
||||
RUN go build -o main src
|
||||
# Build the Go binary
|
||||
RUN go build -o wagfarm-api main.go
|
||||
|
||||
# Start a new stage from a smaller image
|
||||
FROM alpine:latest
|
||||
# Stage 2: Minimal runtime image
|
||||
FROM alpine:latest
|
||||
|
||||
# Install required libraries
|
||||
RUN apk --no-cache add ca-certificates
|
||||
WORKDIR /root/
|
||||
|
||||
# Copy the pre-built binary file from the builder stage
|
||||
COPY --from=builder /app/main .
|
||||
# Copy the binary from the builder
|
||||
COPY --from=builder /app/wagfarm-api .
|
||||
|
||||
# Expose the API port
|
||||
EXPOSE 8089
|
||||
|
||||
# Run the Go app
|
||||
CMD ["./main"]
|
||||
# Run the binary
|
||||
CMD ["./wagfarm-api"]
|
||||
#CMD ["tail", "-f", "/dev/null"]
|
||||
@@ -12,16 +12,13 @@ type Fertilizer struct {
|
||||
FertilizerTypeID uint `gorm:"not null"`
|
||||
FertilizerType fertilizertype.FertilizerType `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
// Association to the ingredients. This represents the composition.
|
||||
Ingredients []FertilizerIngredient `gorm:"not null; many2many:fertilizer_ingredient"`
|
||||
Ingredients []ingredient.Ingredient `gorm:"not null; many2many:fertilizer_ingredient"`
|
||||
}
|
||||
|
||||
type FertilizerIngredient struct {
|
||||
FertilizerAssetID uint `gorm:"primaryKey"` // foreign key to the fertilizer assets
|
||||
IngredientID uint `gorm:"primaryKey"` // foreign key to the ingredient
|
||||
Amount float64 `gorm:"not null"` // amount of the ingredient
|
||||
|
||||
// Preload the ingredient details if needed.
|
||||
Ingredient ingredient.Ingredient `gorm:"not null"`
|
||||
FertilizerID uint `gorm:"primaryKey"` // foreign key to the fertilizer assets
|
||||
IngredientID uint `gorm:"primaryKey"` // foreign key to the ingredient
|
||||
Amount float64 `gorm:"not null"` // amount of the ingredient
|
||||
}
|
||||
|
||||
func RegisterModels() {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
@@ -21,11 +21,11 @@ func Connect() error {
|
||||
dbName := os.Getenv("DB_NAME")
|
||||
|
||||
dsn := fmt.Sprintf(
|
||||
"%s:%s@tcp(%s:%s)/%s?parseTime=true",
|
||||
dbUser, dbPassword, dbHost, dbPort, dbName,
|
||||
"host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
|
||||
dbHost, dbPort, dbUser, dbPassword, dbName,
|
||||
)
|
||||
|
||||
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to database: %w", err)
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ go 1.20
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
gorm.io/driver/mysql v1.5.7
|
||||
gorm.io/gorm v1.25.12
|
||||
github.com/shopspring/decimal v1.4.0
|
||||
gorm.io/driver/postgres v1.5.11
|
||||
gorm.io/gorm v1.25.12
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -21,6 +21,10 @@ require (
|
||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.5.5 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -35,6 +39,7 @@ require (
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
|
||||
@@ -25,6 +25,14 @@ github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
@@ -71,6 +79,8 @@ golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
@@ -86,6 +96,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.5.0/go.mod h1:FFla/fJuCvyTi7rJQd27qlNX2v3L6deTR1GgTjSOLPo=
|
||||
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
|
||||
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
|
||||
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||
gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A=
|
||||
|
||||
@@ -11,15 +11,15 @@ import (
|
||||
)
|
||||
|
||||
type BaseLog struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
Name string `gorm:"not null"`
|
||||
Notes string `gorm:"not null"`
|
||||
LogType string `gorm:"not null"`
|
||||
Date time.Time `gorm:"not null"`
|
||||
Duration float64 `gorm:"not null"` // in hours
|
||||
VisibiltyID uint `gorm:"not null"`
|
||||
Visibility visibility.Visibility `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"`
|
||||
Cost decimal.Decimal `gorm:"not null;type:decimal(10,2);"` // in euro
|
||||
ID uint `gorm:"primaryKey"`
|
||||
Name string `gorm:"not null"`
|
||||
Notes string `gorm:"not null"`
|
||||
LogType string `gorm:"not null"`
|
||||
Date time.Time `gorm:"not null"`
|
||||
Duration float64 `gorm:"not null"` // in hours
|
||||
VisibilityID uint `gorm:"not null"`
|
||||
Visibility visibility.Visibility `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"`
|
||||
Cost decimal.Decimal `gorm:"not null;type:decimal(10,2);"` // in euro
|
||||
}
|
||||
|
||||
func (l BaseLog) GetID() uint { return l.ID }
|
||||
|
||||
@@ -11,23 +11,6 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func initLogging() {
|
||||
// Ensure the logs directory exists
|
||||
if err := os.MkdirAll("logs", 0755); err != nil {
|
||||
log.Fatalf("Failed to create log directory: %v", err)
|
||||
}
|
||||
|
||||
// Open the log file
|
||||
f, err := os.OpenFile("logs/api.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open log file: %v", err)
|
||||
}
|
||||
|
||||
// Set log output
|
||||
log.SetOutput(f)
|
||||
gin.DefaultWriter = f // capture Gin logs too
|
||||
}
|
||||
|
||||
func RegisterModels() {
|
||||
assets.RegisterModels()
|
||||
logs.RegisterModels()
|
||||
@@ -39,11 +22,14 @@ func RegisterRoutes(r *gin.Engine) {
|
||||
assets.RegisterRoutes(group)
|
||||
logs.RegisterRoutes(group)
|
||||
taxonomy.RegisterRoutes(group)
|
||||
|
||||
r.GET("/health", func(c *gin.Context) {
|
||||
c.Status(200)
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
initLogging()
|
||||
|
||||
log.SetOutput(os.Stdout)
|
||||
log.Println("Starting API server...")
|
||||
|
||||
// connect to database
|
||||
|
||||
Reference in New Issue
Block a user