Skip to content

Commit 51a36b7

Browse files
committed
feat: initial gitops sample app with metadata dashboard
0 parents  commit 51a36b7

14 files changed

Lines changed: 469 additions & 0 deletions

File tree

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.git
2+
.gitignore
3+
bin/
4+
*.md

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
PORT=8080
2+
APP_ENV=development

.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Binary
2+
bin/
3+
4+
# Environment
5+
.env
6+
*.exe
7+
8+
# IDE
9+
.idea/
10+
.vscode/
11+
*.swp
12+
*.swo
13+
*~
14+
15+
# OS
16+
.DS_Store
17+
Thumbs.db
18+
19+
# Go
20+
vendor/

Dockerfile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
FROM golang:1.25-alpine AS builder
2+
3+
ARG VERSION=dev
4+
ARG GIT_COMMIT=unknown
5+
ARG BUILD_TIME=unknown
6+
7+
WORKDIR /src
8+
9+
COPY go.mod go.sum ./
10+
RUN go mod download
11+
12+
COPY . .
13+
14+
RUN CGO_ENABLED=0 GOOS=linux go build \
15+
-ldflags="-s -w \
16+
-X github.com/moabdelazem/gitops-sample-app/pkg/version.Version=${VERSION} \
17+
-X github.com/moabdelazem/gitops-sample-app/pkg/version.GitCommit=${GIT_COMMIT} \
18+
-X github.com/moabdelazem/gitops-sample-app/pkg/version.BuildTime=${BUILD_TIME}" \
19+
-o /bin/gitops-app ./cmd/main.go
20+
21+
FROM alpine:3.21
22+
23+
RUN apk --no-cache add ca-certificates \
24+
&& addgroup -S appgroup \
25+
&& adduser -S appuser -G appgroup
26+
27+
WORKDIR /app
28+
29+
COPY --from=builder /bin/gitops-app .
30+
COPY --from=builder /src/web ./web
31+
32+
USER appuser
33+
34+
EXPOSE 8080
35+
36+
ENTRYPOINT ["./gitops-app"]

Makefile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
APP_NAME := gitops-app
2+
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
3+
GIT_COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
4+
BUILD_TIME ?= $(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
5+
LDFLAGS := -s -w \
6+
-X github.com/moabdelazem/gitops-sample-app/pkg/version.Version=$(VERSION) \
7+
-X github.com/moabdelazem/gitops-sample-app/pkg/version.GitCommit=$(GIT_COMMIT) \
8+
-X github.com/moabdelazem/gitops-sample-app/pkg/version.BuildTime=$(BUILD_TIME)
9+
10+
DOCKER_USERNAME := "moabdelazem"
11+
DOCKER_IMG := $(APP_NAME)
12+
DOCKER_TAG := $(VERSION)
13+
14+
.PHONY: build run clean docker-build docker-run help
15+
16+
build:
17+
@echo "Building $(APP_NAME) $(VERSION) ($(GIT_COMMIT))..."
18+
go build -ldflags="$(LDFLAGS)" -o bin/$(APP_NAME) ./cmd/main.go
19+
@echo "Binary: bin/$(APP_NAME)"
20+
21+
run: build
22+
@echo "Starting $(APP_NAME)..."
23+
./bin/$(APP_NAME)
24+
25+
clean:
26+
@rm -rf bin/
27+
@echo "Cleaned."
28+
29+
docker-build:
30+
@echo "Building Docker image $(DOCKER_IMG):$(DOCKER_TAG)..."
31+
docker build \
32+
--build-arg VERSION=$(VERSION) \
33+
--build-arg GIT_COMMIT=$(GIT_COMMIT) \
34+
--build-arg BUILD_TIME=$(BUILD_TIME) \
35+
-t $(DOCKER_USERNAME)/$(DOCKER_IMG):$(DOCKER_TAG) \
36+
-t $(DOCKER_USERNAME)/$(DOCKER_IMG):latest .
37+
38+
docker-run:
39+
@echo "Running $(DOCKER_IMG):$(DOCKER_TAG)..."
40+
docker run --rm -p 8080:8080 \
41+
-e APP_ENV=development \
42+
$(DOCKER_USERNAME)/$(DOCKER_IMG):$(DOCKER_TAG)

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# GitOps Sample App
2+
3+
This app is just for using it in ArgoCD.
4+
5+
Manifests repo: [gitops-sample-app-manifests](https://github.com/moabdelazem/gitops-sample-app-manifests)
6+
7+
## Endpoints
8+
9+
| Endpoint | Description |
10+
| --------------- | ------------------- |
11+
| `GET /` | HTML dashboard |
12+
| `GET /healthz` | Health check (JSON) |
13+
| `GET /api/info` | All metadata (JSON) |

cmd/main.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package main
2+
3+
import (
4+
"html/template"
5+
"log"
6+
"net/http"
7+
"path/filepath"
8+
"time"
9+
10+
"github.com/moabdelazem/gitops-sample-app/internal/config"
11+
"github.com/moabdelazem/gitops-sample-app/internal/handler"
12+
)
13+
14+
func main() {
15+
cfg := config.Load()
16+
17+
templatePath := filepath.Join("web", "templates", "index.html")
18+
tmpl, err := template.ParseFiles(templatePath)
19+
if err != nil {
20+
log.Fatalf("failed to parse template %s: %v", templatePath, err)
21+
}
22+
23+
h := handler.New(cfg, tmpl)
24+
mux := http.NewServeMux()
25+
h.Register(mux)
26+
27+
log.Printf("server starting on :%s [env=%s]", cfg.Port, cfg.Environment)
28+
29+
server := &http.Server{
30+
Addr: ":" + cfg.Port,
31+
Handler: mux,
32+
ReadTimeout: 5 * time.Second,
33+
WriteTimeout: 10 * time.Second,
34+
IdleTimeout: 30 * time.Second,
35+
}
36+
37+
if err := server.ListenAndServe(); err != nil {
38+
log.Fatalf("server failed: %v", err)
39+
}
40+
}

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/moabdelazem/gitops-sample-app
2+
3+
go 1.25.7
4+
5+
require github.com/joho/godotenv v1.5.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
2+
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=

internal/config/config.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package config
2+
3+
import (
4+
"log"
5+
"os"
6+
7+
"github.com/joho/godotenv"
8+
)
9+
10+
type Config struct {
11+
Port string
12+
Environment string
13+
PodName string
14+
NodeName string
15+
}
16+
17+
func Load() *Config {
18+
if err := godotenv.Load(); err != nil {
19+
log.Println("No .env file found, reading from environment")
20+
}
21+
22+
return &Config{
23+
Port: getEnv("PORT", "8080"),
24+
Environment: getEnv("APP_ENV", "development"),
25+
PodName: getEnv("POD_NAME", getHostname()),
26+
NodeName: getEnv("NODE_NAME", "unknown"),
27+
}
28+
}
29+
30+
func getEnv(key, fallback string) string {
31+
if val, ok := os.LookupEnv(key); ok && val != "" {
32+
return val
33+
}
34+
return fallback
35+
}
36+
37+
func getHostname() string {
38+
name, err := os.Hostname()
39+
if err != nil {
40+
return "unknown"
41+
}
42+
return name
43+
}

0 commit comments

Comments
 (0)