Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .air.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ tmp_dir = "tmp"
"tmp",
"docs",
"database/infra",
"bin",
"storage/logs",
"storage/media",
"config/makefile",
Expand Down
6 changes: 1 addition & 5 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.env
.env.example
.env.production

.gitattributes
.github/
.gitignore
Expand All @@ -17,4 +13,4 @@ database/infra/
storage/media/
storage/logs/
tmp/
bin/
caddy/
33 changes: 16 additions & 17 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
# --- App secrets
# --- App
ENV_APP_NAME="Gus Blog"
ENV_APP_ENV_TYPE=local
ENV_APP_ENV=local

# --- App Logs secrets
ENV_APP_LOG_LEVEL=debug
ENV_APP_LOGS_DIR="./storage/logs/logs_%s.log"
ENV_APP_LOGS_DATE_FORMAT="2006_02_01"

# --- App Network secrets
ENV_HTTP_HOST=localhost
ENV_HTTP_PORT=8080

# --- App super admin credentials
# --- Auth
ENV_APP_TOKEN_PUBLIC=""
ENV_APP_TOKEN_PRIVATE=""

# --- App db secrets
ENV_DB_USER_NAME=gocanto-user
ENV_DB_USER_PASSWORD=gocanto-password
ENV_DB_DATABASE_NAME=gocanto-db
# --- DB
ENV_DB_USER_NAME="gus"
ENV_DB_USER_PASSWORD="password"
ENV_DB_DATABASE_NAME="oullin_db"
ENV_DB_PORT=5432
ENV_DB_HOST=localhost
ENV_DB_SSL_MODE=require
ENV_DB_TIMEZONE="Asia/Singapore"
EN_DB_BIN_DIR="" # Local posgreSQL instalation directory. Example: /Library/PostgreSQL/17/bin/
ENV_DB_URL="" # Example: postgresql://gocanto-user:gocanto-password@postgres:5432/gocanto-db?sslmode=require

# --- Sentry
ENV_SENTRY_DSN=""
ENV_SENTRY_CSP=""
# --- This flag is only needed/used for debugging purposes.
# Local posgreSQL instalation directory.
# Example: /Library/PostgreSQL/17/bin/
EN_DB_BIN_DIR=""

# --- This flag is only needed/used for docker purposes.
# The full db url value is only used for docker purposes given the application works in the -GORM DSN-
# Example: postgresql://gocanto-user:gocanto-password@postgres:5432/oullin_db?sslmode=require
ENV_DB_URL=""

13 changes: 0 additions & 13 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,6 @@
database/infra/data
tmp

# --- [API]: Bin
bin
!bin/.env
!bin/.gitkeep
bin/storage/logs/*.*
bin/storage/media/*.*
bin/storage/media/posts/*.*
bin/storage/media/users/*.*
!bin/storage/logs/.gitkeep
!bin/storage/media/.gitkeep
!bin/storage/media/posts/.gitkeep
!bin/storage/media/users/.gitkeep

# --- [API]: Storage
storage/logs/*.*
storage/media/*.*
Expand Down
32 changes: 13 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ SOURCE := go_bindata
ROOT_PATH := $(shell pwd)
APP_PATH := $(ROOT_PATH)/
STORAGE_PATH := $(ROOT_PATH)/storage
BIN_PATH := $(ROOT_PATH)/bin
BIN_LOGS_PATH := $(ROOT_PATH)/bin/storage/logs
REPO_OWNER := $(shell cd .. && basename "$$(pwd)")
VERSION := $(shell git describe --tags 2>/dev/null | cut -c 2-)

Expand All @@ -36,7 +34,6 @@ VERSION := $(shell git describe --tags 2>/dev/null | cut -c 2-)

include ./config/makefile/helpers.mk
include ./config/makefile/env.mk

include ./config/makefile/db.mk
include ./config/makefile/app.mk
include ./config/makefile/logs.mk
Expand All @@ -46,22 +43,19 @@ include ./config/makefile/build.mk
# -------------------------------------------------------------------------------------------------------------------- #

help:
@printf "$(BOLD)$(CYAN)Makefile Commands:$(NC)\n"
@printf "$(BOLD)$(CYAN)Applications Options$(NC)\n"
@printf "$(WHITE)Usage:$(NC) make $(BOLD)$(YELLOW)<target>$(NC)\n\n"

@printf "$(BOLD)$(BLUE)General Commands:$(NC)\n"
@printf " $(BOLD)$(GREEN)fresh$(NC) : Clean and reset various project components (logs, build, etc.).\n"
@printf " $(BOLD)$(GREEN)audit$(NC) : Run code audits and checks.\n"
@printf " $(BOLD)$(GREEN)watch$(NC) : Start a file watcher process.\n"
@printf " $(BOLD)$(GREEN)format$(NC) : Automatically format code.\n\n"
@printf " $(BOLD)$(GREEN)fresh$(NC) : Clean and reset various project components (logs, build, etc.).\n"
@printf " $(BOLD)$(GREEN)audit$(NC) : Run code audits and checks.\n"
@printf " $(BOLD)$(GREEN)watch$(NC) : Start a file watcher process.\n"
@printf " $(BOLD)$(GREEN)format$(NC) : Automatically format code.\n\n"

@printf "$(BOLD)$(BLUE)Build Commands:$(NC)\n"
@printf " $(BOLD)$(GREEN)build:app$(NC) : Build the main application executable.\n"
@printf " $(BOLD)$(GREEN)build:app:linux$(NC) : Build the application specifically for Linux.\n"
@printf " $(BOLD)$(GREEN)build:release$(NC) : Build a release version of the application.\n"
@printf " $(BOLD)$(GREEN)build:run$(NC) : Build and run the application.\n"
@printf " $(BOLD)$(GREEN)build:fresh$(NC) : Build and run a freshly instance of the application.\n"
@printf " $(BOLD)$(GREEN)build:flush$(NC) : Clean build artifacts and then build the application.\n\n"
@printf " $(BOLD)$(GREEN)build:local$(NC) : Build the main application for development.\n"
@printf " $(BOLD)$(GREEN)build:prod$(NC) : Build the main application for production.\n"
@printf " $(BOLD)$(GREEN)build:release$(NC) : Build a release version of the application.\n"

@printf "$(BOLD)$(BLUE)Database Commands:$(NC)\n"
@printf " $(BOLD)$(GREEN)db:local$(NC) : Set up or manage the local database environment.\n"
Expand All @@ -81,12 +75,12 @@ help:
@printf " $(BOLD)$(GREEN)db:migrate:force$(NC) : Force database migrations to run.\n\n"

@printf "$(BOLD)$(BLUE)Environment Commands:$(NC)\n"
@printf " $(BOLD)$(GREEN)env:check$(NC) : Verify environment configuration.\n"
@printf " $(BOLD)$(GREEN)env:fresh$(NC) : Refresh environment settings.\n"
@printf " $(BOLD)$(GREEN)env:init$(NC) : Initialize environment settings.\n"
@printf " $(BOLD)$(GREEN)env:print$(NC) : Display current environment settings.\n\n"
@printf " $(BOLD)$(GREEN)env:check$(NC) : Verify environment configuration.\n"
@printf " $(BOLD)$(GREEN)env:fresh$(NC) : Refresh environment settings.\n"
@printf " $(BOLD)$(GREEN)env:init$(NC) : Initialize environment settings.\n"
@printf " $(BOLD)$(GREEN)env:print$(NC) : Display current environment settings.\n\n"

@printf "$(BOLD)$(BLUE)Log Commands:$(NC)\n"
@printf " $(BOLD)$(GREEN)logs:fresh$(NC) : Clear application logs.\n"
@printf " $(BOLD)$(GREEN)logs:fresh$(NC) : Clear application logs.\n"

@printf "$(NC)"
Empty file removed bin/.gitkeep
Empty file.
43 changes: 20 additions & 23 deletions boost/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/oullin/pkg/llogs"
"log"
"strconv"
"strings"
"time"
)

Expand Down Expand Up @@ -56,49 +55,47 @@ func MakeLogs(env *env.Environment) *llogs.Driver {
return &lDriver
}

func MakeEnv(values map[string]string, validate *pkg.Validator) *env.Environment {
func MakeEnv(validate *pkg.Validator) *env.Environment {
errorSufix := "Environment: "

port, _ := strconv.Atoi(values["ENV_DB_PORT"])
port, _ := strconv.Atoi(env.GetEnvVar("ENV_DB_PORT"))

token := auth.Token{
Public: strings.TrimSpace(values["ENV_APP_TOKEN_PUBLIC"]),
Private: strings.TrimSpace(values["ENV_APP_TOKEN_PRIVATE"]),
Public: env.GetEnvVar("ENV_APP_TOKEN_PUBLIC"),
Private: env.GetEnvVar("ENV_APP_TOKEN_PRIVATE"),
}

app := env.AppEnvironment{
Name: strings.TrimSpace(values["ENV_APP_NAME"]),
Type: strings.TrimSpace(values["ENV_APP_ENV_TYPE"]),
Name: env.GetEnvVar("ENV_APP_NAME"),
Type: env.GetEnvVar("ENV_APP_ENV_TYPE"),
Credentials: token,
}

db := env.DBEnvironment{
UserName: strings.TrimSpace(values["ENV_DB_USER_NAME"]),
UserPassword: strings.TrimSpace(values["ENV_DB_USER_PASSWORD"]),
DatabaseName: strings.TrimSpace(values["ENV_DB_DATABASE_NAME"]),
UserName: env.GetEnvVar("ENV_DB_USER_NAME"),
UserPassword: env.GetEnvVar("ENV_DB_USER_PASSWORD"),
DatabaseName: env.GetEnvVar("ENV_DB_DATABASE_NAME"),
Port: port,
Host: strings.TrimSpace(values["ENV_DB_HOST"]),
DriverName: "postgres",
BinDir: strings.TrimSpace(values["EN_DB_BIN_DIR"]),
URL: strings.TrimSpace(values["ENV_DB_URL"]),
SSLMode: strings.TrimSpace(values["ENV_DB_SSL_MODE"]),
TimeZone: strings.TrimSpace(values["ENV_DB_TIMEZONE"]),
Host: env.GetEnvVar("ENV_DB_HOST"),
DriverName: database.DriverName,
SSLMode: env.GetEnvVar("ENV_DB_SSL_MODE"),
TimeZone: env.GetEnvVar("ENV_DB_TIMEZONE"),
}

logsCreds := env.LogsEnvironment{
Level: strings.TrimSpace(values["ENV_APP_LOG_LEVEL"]),
Dir: strings.TrimSpace(values["ENV_APP_LOGS_DIR"]),
DateFormat: strings.TrimSpace(values["ENV_APP_LOGS_DATE_FORMAT"]),
Level: env.GetEnvVar("ENV_APP_LOG_LEVEL"),
Dir: env.GetEnvVar("ENV_APP_LOGS_DIR"),
DateFormat: env.GetEnvVar("ENV_APP_LOGS_DATE_FORMAT"),
}

net := env.NetEnvironment{
HttpHost: strings.TrimSpace(values["ENV_HTTP_HOST"]),
HttpPort: strings.TrimSpace(values["ENV_HTTP_PORT"]),
HttpHost: env.GetEnvVar("ENV_HTTP_HOST"),
HttpPort: env.GetEnvVar("ENV_HTTP_PORT"),
}

sentryEnvironment := env.SentryEnvironment{
DSN: strings.TrimSpace(values["ENV_SENTRY_DSN"]),
CSP: strings.TrimSpace(values["ENV_SENTRY_CSP"]),
DSN: env.GetEnvVar("ENV_SENTRY_DSN"),
CSP: env.GetEnvVar("ENV_SENTRY_CSP"),
}

if _, err := validate.Rejects(app); err != nil {
Expand Down
12 changes: 4 additions & 8 deletions boost/ignite.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,10 @@ import (
"github.com/oullin/pkg"
)

func Ignite(envPath string) (*env.Environment, *pkg.Validator) {
validate := pkg.GetDefaultValidator()

envMap, err := godotenv.Read(envPath)

if err != nil {
panic("failed to read the .env file: " + err.Error())
func Ignite(envPath string, validate *pkg.Validator) *env.Environment {
if err := godotenv.Load(envPath); err != nil {
panic("failed to read the .env file/values: " + err.Error())
}

return MakeEnv(envMap, validate), validate
return MakeEnv(validate)
}
24 changes: 24 additions & 0 deletions caddy/Caddyfile.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Filename: caddy/Caddyfile

# This global options block explicitly disables Caddy's automatic HTTPS feature.
# This is the most reliable way to ensure Caddy acts as a simple HTTP proxy.
{
auto_https off
}

# This is a robust configuration for a containerized environment.
# It tells Caddy to listen on its internal port 80 for any incoming hostname.
# Docker Compose maps your host port (8080) to this container port.
:80 {
# Define a logging format for easier debugging.
log {
output stdout
format console
}

# Reverse proxy all incoming requests to the 'api' service.
# The service name 'api' is resolved by Docker's internal DNS to the
# correct container IP on the 'caddy_net' network.
# The API container listens on port 8080 (from your ENV_HTTP_PORT).
reverse_proxy api:8080
}
23 changes: 23 additions & 0 deletions caddy/Caddyfile.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Filename: caddy/Caddyfile.prod
# Caddy will automatically provision a Let's Encrypt certificate.

gocanto.dev {
# Enable compression to reduce bandwidth usage.
encode gzip zstd

# Add security-related headers to protect against common attacks.
header {
# Enable HSTS to ensure browsers only connect via HTTPS.
Strict-Transport-Security "max-age=31536000;"
# Prevent clickjacking attacks.
X-Frame-Options "SAMEORIGIN"
# Prevent content type sniffing.
X-Content-Type-Options "nosniff"
# Enhances user privacy.
Referrer-Policy "strict-origin-when-cross-origin"
}

# Reverse proxy all requests to the Go application service.
# 'api' is the service name defined in docker-compose.yml.
reverse_proxy api:8080
}
13 changes: 13 additions & 0 deletions caddy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Filename: caddy/Dockerfile
# This Dockerfile builds a Caddy image using a specific, stable version number.

# Define a build argument for the Caddy version with a sensible default.
# This allows the version to be easily overridden from the docker-compose.yml file.
ARG CADDY_VERSION=2.10.0

# Use the official Caddy image with the latest tag.
FROM caddy:${CADDY_VERSION}

# Copy your custom Caddyfile into the container.
# This overwrites the default Caddyfile.
COPY Caddyfile.local /etc/caddy/Caddyfile
2 changes: 1 addition & 1 deletion cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var guard gate.Guard
var environment *env.Environment

func init() {
secrets, _ := boost.Ignite("./../.env")
secrets := boost.Ignite("./../.env", pkg.GetDefaultValidator())

environment = secrets
guard = gate.MakeGuard(environment.App.Credentials)
Expand Down
6 changes: 3 additions & 3 deletions config/makefile/app.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ fresh:

audit:
$(call external_deps,'.')
$(call external_deps,'./bin/...')
$(call external_deps,'./app/...')
$(call external_deps,'./database/...')
$(call external_deps,'./docs/...')

watch:
# --- Works with (air).
# https://github.com/air-verse/air
# https://github.com/air-verse/air
cd $(APP_PATH) && air

install-air:
# https://github.com/air-verse/air
# --- Works with (air).
# https://github.com/air-verse/air
@echo "Installing air ..."
@go install github.com/air-verse/air@latest
Loading
Loading