Skip to content

Commit 916a393

Browse files
committed
hotfix: embed migration files
1 parent 4a50015 commit 916a393

File tree

12 files changed

+32
-39
lines changed

12 files changed

+32
-39
lines changed

cmd/mcpulse/main.go

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,20 @@ import (
88
"fmt"
99
"os"
1010
"os/signal"
11-
"path/filepath"
1211
"syscall"
1312
"time"
1413

1514
"github.com/golang-migrate/migrate/v4"
1615
githubPgx "github.com/golang-migrate/migrate/v4/database/pgx/v5"
1716
_ "github.com/golang-migrate/migrate/v4/source/file"
17+
"github.com/golang-migrate/migrate/v4/source/iofs"
1818
_ "github.com/jackc/pgx/v5/stdlib"
1919
"github.com/sirrobot01/mcpulse/internal/auth"
2020
"github.com/sirrobot01/mcpulse/internal/config"
2121
"github.com/sirrobot01/mcpulse/internal/database"
2222
"github.com/sirrobot01/mcpulse/internal/ingestion"
2323
"github.com/sirrobot01/mcpulse/internal/metrics"
24+
"github.com/sirrobot01/mcpulse/internal/migrations"
2425
"github.com/sirrobot01/mcpulse/internal/server"
2526
grpcserver "github.com/sirrobot01/mcpulse/internal/server/grpc"
2627
"go.uber.org/zap"
@@ -70,7 +71,7 @@ func main() {
7071
MaxLifetime: cfg.Database.MaxLifetime,
7172
}
7273

73-
if err := runMigrations(dbConfig, cfg.Database.MigrationsPath, logger); err != nil {
74+
if err := runMigrations(dbConfig, logger); err != nil {
7475
logger.Fatal("failed to run database migrations", zap.Error(err))
7576
}
7677

@@ -141,27 +142,7 @@ func main() {
141142
}
142143
}
143144

144-
func runMigrations(cfg database.Config, migrationsPath string, logger *zap.Logger) error {
145-
if migrationsPath == "" {
146-
migrationsPath = "migrations"
147-
}
148-
149-
absPath, err := filepath.Abs(migrationsPath)
150-
if err != nil {
151-
return fmt.Errorf("resolve migrations path: %w", err)
152-
}
153-
154-
if info, statErr := os.Stat(absPath); statErr != nil {
155-
if os.IsNotExist(statErr) {
156-
return fmt.Errorf("migrations path does not exist: %s", absPath)
157-
}
158-
return fmt.Errorf("stat migrations path: %w", statErr)
159-
} else if !info.IsDir() {
160-
return fmt.Errorf("migrations path is not a directory: %s", absPath)
161-
}
162-
163-
sourceURL := fmt.Sprintf("file://%s", absPath)
164-
145+
func runMigrations(cfg database.Config, logger *zap.Logger) error {
165146
db, err := sql.Open("pgx/v5", database.ConnectionString(cfg))
166147
if err != nil {
167148
return fmt.Errorf("open database for migrations: %w", err)
@@ -178,10 +159,18 @@ func runMigrations(cfg database.Config, migrationsPath string, logger *zap.Logge
178159
return fmt.Errorf("create migration driver: %w", err)
179160
}
180161

181-
m, err := migrate.NewWithDatabaseInstance(sourceURL, cfg.Database, driver)
182-
if err != nil {
183-
return fmt.Errorf("create migrator: %w", err)
162+
var m *migrate.Migrate
163+
var source string
164+
165+
// Try to use embedded migrations first
166+
d, iofsErr := iofs.New(migrations.FS, ".")
167+
if iofsErr == nil {
168+
m, err = migrate.NewWithInstance("iofs", d, cfg.Database, driver)
169+
if err == nil {
170+
source = "embedded"
171+
}
184172
}
173+
185174
defer func() {
186175
if sourceErr, dbErr := m.Close(); sourceErr != nil || dbErr != nil {
187176
logger.Warn("migration close error", zap.Error(errors.Join(sourceErr, dbErr)))
@@ -192,7 +181,7 @@ func runMigrations(cfg database.Config, migrationsPath string, logger *zap.Logge
192181
return fmt.Errorf("run migrations: %w", err)
193182
}
194183

195-
logger.Info("database migrations applied", zap.String("path", absPath))
184+
logger.Info("database migrations applied", zap.String("source", source))
196185
return nil
197186
}
198187

docker-compose.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ services:
3838
- "9090:9090" # gRPC API
3939
volumes:
4040
- ./config.yaml:/app/config.yaml:ro
41+
depends_on:
42+
timescale:
43+
condition: service_healthy
4144
healthcheck:
4245
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/health"]
4346
interval: 30s

docker/Dockerfile.goreleaser

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# Final stage only - GoReleaser provides the binary
22
FROM alpine:latest
33

4-
# Install ca-certificates for HTTPS requests
5-
RUN apk --no-cache add ca-certificates
4+
# Install ca-certificates for HTTPS requests and wget for healthcheck
5+
RUN apk --no-cache add ca-certificates wget
66

77
# Create non-root user
88
RUN addgroup -g 1000 mcpulse && \
99
adduser -D -s /bin/sh -u 1000 -G mcpulse mcpulse
1010

1111
# Set working directory
12-
WORKDIR /home/mcpulse
12+
WORKDIR /app
1313

1414
# Copy the binary (GoReleaser puts it in build context)
1515
COPY mcpulse .
@@ -21,8 +21,8 @@ RUN chmod +x mcpulse && \
2121
# Switch to non-root user
2222
USER mcpulse
2323

24-
# Expose port
25-
EXPOSE 8080
24+
# Expose ports
25+
EXPOSE 8080 9090
2626

2727
# Default command
28-
CMD ["./mcpulse", "--config", "/home/mcpulse/config.yaml"]
28+
CMD ["./mcpulse", "--config", "/app/config.yaml"]

internal/config/config.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ type DatabaseConfig struct {
4242
MaxConnections int `mapstructure:"max_connections"`
4343
MaxIdleConnections int `mapstructure:"max_idle_connections"`
4444
MaxLifetime time.Duration `mapstructure:"connection_max_lifetime"`
45-
MigrationsPath string `mapstructure:"migrations_path"`
4645
Retention RetentionConfig `mapstructure:"retention"`
4746
}
4847

@@ -246,10 +245,6 @@ func (c *Config) Validate() error {
246245
return fmt.Errorf("database username is required")
247246
}
248247

249-
if strings.TrimSpace(c.Database.MigrationsPath) == "" {
250-
return fmt.Errorf("database migrations path is required")
251-
}
252-
253248
if c.Ingestion.BufferSize < 1 {
254249
return fmt.Errorf("ingestion buffer size must be at least 1")
255250
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)