Skip to content

Commit 0776163

Browse files
Merge pull request #12 from CarterPerez-dev/go-backend-template
go backend to react-go stack
2 parents cb413c6 + bf95949 commit 0776163

39 files changed

+5819
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# AngelaMos | 2026
2+
# .air.toml - Hot reload configuration
3+
4+
root = "."
5+
tmp_dir = "tmp"
6+
7+
[build]
8+
cmd = "go build -o ./tmp/main ./cmd/api"
9+
bin = "tmp/main"
10+
full_bin = "./tmp/main"
11+
include_ext = ["go", "yaml", "yml"]
12+
exclude_dir = ["tmp", "vendor", "bin", "keys", "migrations"]
13+
exclude_regex = ["_test\\.go"]
14+
delay = 1000
15+
stop_on_error = true
16+
send_interrupt = true
17+
kill_delay = 500
18+
19+
[log]
20+
time = false
21+
22+
[color]
23+
main = "cyan"
24+
watcher = "magenta"
25+
build = "yellow"
26+
runner = "green"
27+
28+
[misc]
29+
clean_on_exit = true
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# AngelaMos | 2026
2+
# .env.example
3+
4+
# Environment: development, staging, production
5+
ENVIRONMENT=development
6+
7+
# Server
8+
HOST=0.0.0.0
9+
PORT=8080
10+
11+
# Database
12+
DATABASE_URL=postgres://postgres:postgres@localhost:5432/app?sslmode=disable
13+
14+
# Redis
15+
REDIS_URL=redis://localhost:6379/0
16+
17+
# JWT
18+
JWT_PRIVATE_KEY_PATH=keys/private.pem
19+
JWT_PUBLIC_KEY_PATH=keys/public.pem
20+
ACCESS_TOKEN_EXPIRE_MINUTES=15
21+
REFRESH_TOKEN_EXPIRE_DAYS=7
22+
23+
# Rate Limiting
24+
RATE_LIMIT_REQUESTS=100
25+
RATE_LIMIT_WINDOW=1m
26+
27+
# OpenTelemetry
28+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
29+
OTEL_SERVICE_NAME=go-backend
30+
31+
# Logging
32+
LOG_LEVEL=debug
33+
LOG_FORMAT=text
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# AngelaMos | 2026
2+
# .gitignore
3+
4+
# Binaries
5+
bin/
6+
*.exe
7+
*.exe~
8+
*.dll
9+
*.so
10+
*.dylib
11+
12+
# Test
13+
*.test
14+
coverage.out
15+
coverage.html
16+
17+
# Build
18+
tmp/
19+
20+
# IDE
21+
.idea/
22+
.vscode/
23+
*.swp
24+
*.swo
25+
*~
26+
27+
# OS
28+
.DS_Store
29+
Thumbs.db
30+
31+
# Environment
32+
.env
33+
.env.local
34+
.env.*.local
35+
36+
# Keys (sensitive)
37+
keys/*.pem
38+
keys/*.key
39+
40+
# Vendor (if using)
41+
vendor/
42+
43+
# Debug
44+
__debug_bin*
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# AngelaMos | 2026
2+
# .golangci.yml
3+
4+
version: "2"
5+
6+
linters:
7+
default: none
8+
enable:
9+
- errcheck
10+
- govet
11+
- gosec
12+
- bodyclose
13+
- nilerr
14+
- errorlint
15+
- exhaustive
16+
- gocritic
17+
- funlen
18+
- gocognit
19+
- dupl
20+
- goconst
21+
- ineffassign
22+
- unused
23+
- unconvert
24+
- unparam
25+
- testifylint
26+
- fatcontext
27+
28+
settings:
29+
errcheck:
30+
check-type-assertions: true
31+
check-blank: true
32+
33+
funlen:
34+
lines: 100
35+
statements: 50
36+
37+
gocognit:
38+
min-complexity: 20
39+
40+
govet:
41+
enable-all: true
42+
disable:
43+
- fieldalignment
44+
45+
revive:
46+
rules:
47+
- name: blank-imports
48+
- name: context-as-argument
49+
- name: context-keys-type
50+
- name: error-return
51+
- name: error-strings
52+
- name: error-naming
53+
- name: exported
54+
- name: increment-decrement
55+
- name: var-declaration
56+
- name: package-comments
57+
disabled: true
58+
- name: range
59+
- name: receiver-naming
60+
- name: time-naming
61+
- name: unexported-return
62+
- name: indent-error-flow
63+
- name: errorf
64+
- name: empty-block
65+
- name: superfluous-else
66+
- name: unreachable-code
67+
68+
staticcheck:
69+
checks:
70+
- all
71+
72+
gosec:
73+
excludes:
74+
- G104
75+
76+
sloglint:
77+
no-mixed-args: true
78+
kv-only: true
79+
context: all
80+
81+
issues:
82+
max-same-issues: 50
83+
exclude-dirs:
84+
- vendor
85+
- testdata
86+
exclude-rules:
87+
- path: _test\.go
88+
linters:
89+
- funlen
90+
- dupl
91+
- goconst
92+
93+
94+
formatters:
95+
enable:
96+
- gci # Groups imports
97+
- gofumpt # Whitespace
98+
- golines # Vertical wrap
99+
settings:
100+
golines:
101+
max-len: 80
102+
reformat-tags: true
103+
goimports:
104+
local-prefixes:
105+
- github.com/carterperez-dev/templates/go-backend
106+
gci:
107+
sections:
108+
- standard
109+
- default
110+
- prefix(github.com/carterperez-dev)
111+
custom-order: true
112+
gofumpt:
113+
extra-rules: true
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# AngelaMos | 2026
2+
# Dockerfile - Multi-stage distroless build
3+
4+
# Build stage
5+
FROM golang:1.25-bookworm AS builder
6+
7+
WORKDIR /build
8+
9+
# Copy dependency files first for layer caching
10+
COPY go.mod go.sum ./
11+
RUN go mod download
12+
13+
# Copy source code
14+
COPY . .
15+
16+
# Build binary
17+
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app ./cmd/api
18+
19+
# Production stage - Distroless
20+
FROM gcr.io/distroless/static-debian12
21+
22+
# Copy binary from builder
23+
COPY --from=builder /app /app
24+
25+
# Copy migrations (embedded, but useful for debugging)
26+
COPY --from=builder /build/migrations /migrations
27+
28+
# Copy keys if they exist (for JWT)
29+
COPY --from=builder /build/keys /keys
30+
31+
# Run as non-root user
32+
USER nonroot:nonroot
33+
34+
EXPOSE 8080
35+
36+
ENTRYPOINT ["/app"]
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# AngelaMos | 2026
2+
# Justfile
3+
4+
set dotenv-load := true
5+
6+
# Default recipe
7+
default:
8+
@just --list
9+
10+
# Development
11+
# -----------
12+
13+
# Run the API server with hot reload (requires air)
14+
dev:
15+
air -c .air.toml
16+
17+
# Run the API server without hot reload
18+
run:
19+
go run ./cmd/api
20+
21+
# Build the binary
22+
build:
23+
CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o bin/api ./cmd/api
24+
25+
# Run tests
26+
test:
27+
go test -v -race -coverprofile=coverage.out ./...
28+
29+
# Run tests with coverage report
30+
test-coverage: test
31+
go tool cover -html=coverage.out -o coverage.html
32+
33+
# Run linter
34+
lint:
35+
golangci-lint run --timeout=5m
36+
37+
# Format code
38+
fmt:
39+
gofumpt -w .
40+
goimports -w .
41+
42+
# Tidy dependencies
43+
tidy:
44+
go mod tidy
45+
46+
# Database
47+
# --------
48+
49+
# Run database migrations
50+
migrate-up:
51+
goose -dir migrations postgres "${DATABASE_URL}" up
52+
53+
# Rollback last migration
54+
migrate-down:
55+
goose -dir migrations postgres "${DATABASE_URL}" down
56+
57+
# Check migration status
58+
migrate-status:
59+
goose -dir migrations postgres "${DATABASE_URL}" status
60+
61+
# Create new migration
62+
migrate-create name:
63+
goose -dir migrations create {{name}} sql
64+
65+
# Docker
66+
# ------
67+
68+
# Start development containers
69+
up:
70+
docker compose -f dev.compose.yml up -d
71+
72+
# Stop development containers
73+
down:
74+
docker compose -f dev.compose.yml down
75+
76+
# View container logs
77+
logs:
78+
docker compose -f dev.compose.yml logs -f
79+
80+
# Rebuild and restart containers
81+
rebuild:
82+
docker compose -f dev.compose.yml up -d --build
83+
84+
# Build production image
85+
docker-build:
86+
docker build -t go-backend:latest .
87+
88+
# Keys
89+
# ----
90+
91+
# Generate ES256 keypair for JWT signing
92+
generate-keys:
93+
#!/usr/bin/env bash
94+
set -euo pipefail
95+
mkdir -p keys
96+
openssl ecparam -genkey -name prime256v1 -noout -out keys/private.pem
97+
openssl ec -in keys/private.pem -pubout -out keys/public.pem
98+
chmod 600 keys/private.pem
99+
echo "ES256 keypair generated in keys/"
100+
101+
# Clean
102+
# -----
103+
104+
# Remove build artifacts
105+
clean:
106+
rm -rf bin/ coverage.out coverage.html tmp/
107+
108+
# Full clean including containers
109+
clean-all: clean
110+
docker compose -f dev.compose.yml down -v

0 commit comments

Comments
 (0)