From 5279657b46a6aeceaca0fb528ad2fe04b506e2da Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sat, 5 Jul 2025 11:58:57 +0800 Subject: [PATCH 01/18] add example file --- .env.prod.example | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .env.prod.example diff --git a/.env.prod.example b/.env.prod.example new file mode 100644 index 00000000..40391143 --- /dev/null +++ b/.env.prod.example @@ -0,0 +1,7 @@ +# --- Caddy +CADDY_LOGS_PATH=/storage/logs/caddy + +# --- Database Secrets +POSTGRES_USER_SECRET_PATH=/database/infra/secrets/postgres_user +POSTGRES_PASSWORD_SECRET_PATH=/database/infra/secrets/postgres_password +POSTGRES_DB_SECRET_PATH=/database/infra/secrets/postgres_db From 203ad792d8ddf3e2937d4404962631cfdf9d1f11 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sat, 5 Jul 2025 12:00:18 +0800 Subject: [PATCH 02/18] format --- .env.prod.example | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.env.prod.example b/.env.prod.example index 40391143..48b49047 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -1,7 +1,7 @@ # --- Caddy -CADDY_LOGS_PATH=/storage/logs/caddy +CADDY_LOGS_PATH=./storage/logs/caddy # --- Database Secrets -POSTGRES_USER_SECRET_PATH=/database/infra/secrets/postgres_user -POSTGRES_PASSWORD_SECRET_PATH=/database/infra/secrets/postgres_password -POSTGRES_DB_SECRET_PATH=/database/infra/secrets/postgres_db +POSTGRES_USER_SECRET_PATH=./database/infra/secrets/postgres_user +POSTGRES_PASSWORD_SECRET_PATH=./database/infra/secrets/postgres_password +POSTGRES_DB_SECRET_PATH=./database/infra/secrets/postgres_db From 876aa48c3b3ef800288958c87fd1582c9465ec98 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sat, 5 Jul 2025 16:25:10 +0800 Subject: [PATCH 03/18] work on names --- .env.prod.example | 8 ++-- config/makefile/build.mk | 6 +-- .../infra/secrets/{postgres_db => pg_dbname} | 0 .../{postgres_password => pg_password} | 0 .../secrets/{postgres_user => pg_username} | 0 docker-compose.yml | 44 ++++++++++--------- 6 files changed, 30 insertions(+), 28 deletions(-) rename database/infra/secrets/{postgres_db => pg_dbname} (100%) rename database/infra/secrets/{postgres_password => pg_password} (100%) rename database/infra/secrets/{postgres_user => pg_username} (100%) diff --git a/.env.prod.example b/.env.prod.example index 48b49047..eefcf7d5 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -1,7 +1,7 @@ # --- Caddy -CADDY_LOGS_PATH=./storage/logs/caddy +CADDY_LOGS_DIR=./storage/logs/caddy # --- Database Secrets -POSTGRES_USER_SECRET_PATH=./database/infra/secrets/postgres_user -POSTGRES_PASSWORD_SECRET_PATH=./database/infra/secrets/postgres_password -POSTGRES_DB_SECRET_PATH=./database/infra/secrets/postgres_db +DB_SECRET_USERNAME=./database/infra/secrets/pg_username +DB_SECRET_PASSWORD=./database/infra/secrets/pg_password +DB_SECRET_DBNAME=./database/infra/secrets/pg_dbname diff --git a/config/makefile/build.mk b/config/makefile/build.mk index ead8bf07..165e32df 100644 --- a/config/makefile/build.mk +++ b/config/makefile/build.mk @@ -11,9 +11,9 @@ build\:prod: # --- The following lines take the variables passed to 'make' and export them # into the shell environment for only the docker-compose command. # These variable names now EXACTLY match what the Go application expects. - @POSTGRES_USER_SECRET_PATH="$(POSTGRES_USER_SECRET_PATH)" \ - POSTGRES_PASSWORD_SECRET_PATH="$(POSTGRES_PASSWORD_SECRET_PATH)" \ - POSTGRES_DB_SECRET_PATH="$(POSTGRES_DB_SECRET_PATH)" \ + @DB_SECRET_USERNAME="$(DB_SECRET_USERNAME)" \ + DB_SECRET_PASSWORD="$(DB_SECRET_PASSWORD)" \ + DB_SECRET_DBNAME="$(DB_SECRET_DBNAME)" \ ENV_DB_USER_NAME="$(ENV_DB_USER_NAME)" \ ENV_DB_USER_PASSWORD="$(ENV_DB_USER_PASSWORD)" \ ENV_DB_DATABASE_NAME="$(ENV_DB_DATABASE_NAME)" \ diff --git a/database/infra/secrets/postgres_db b/database/infra/secrets/pg_dbname similarity index 100% rename from database/infra/secrets/postgres_db rename to database/infra/secrets/pg_dbname diff --git a/database/infra/secrets/postgres_password b/database/infra/secrets/pg_password similarity index 100% rename from database/infra/secrets/postgres_password rename to database/infra/secrets/pg_password diff --git a/database/infra/secrets/postgres_user b/database/infra/secrets/pg_username similarity index 100% rename from database/infra/secrets/postgres_user rename to database/infra/secrets/pg_username diff --git a/docker-compose.yml b/docker-compose.yml index bdd974ba..9059c280 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,11 @@ # Define the source of the secrets on the host machine. secrets: - postgres_user: - file: ${POSTGRES_USER_SECRET_PATH:-./database/infra/secrets/postgres_user} - postgres_password: - file: ${POSTGRES_PASSWORD_SECRET_PATH:-./database/infra/secrets/postgres_password} - postgres_db: - file: ${POSTGRES_DB_SECRET_PATH:-./database/infra/secrets/postgres_db} + pg_username: + file: ${DB_SECRET_USERNAME:-./database/infra/secrets/pg_username} + pg_password: + file: ${DB_SECRET_PASSWORD:-./database/infra/secrets/pg_password} + pg_dbname: + file: ${DB_SECRET_DBNAME:-./database/infra/secrets/pg_dbname} volumes: caddy_data: @@ -83,9 +83,9 @@ services: networks: - oullin_net secrets: - - postgres_user - - postgres_password - - postgres_db + - pg_username + - pg_password + - pg_dbname depends_on: api-db: condition: service_healthy @@ -109,9 +109,9 @@ services: container_name: oullin_api restart: unless-stopped secrets: - - postgres_user - - postgres_password - - postgres_db + - pg_username + - pg_password + - pg_dbname depends_on: api-db: condition: service_healthy @@ -130,9 +130,9 @@ services: - ./database/infra/migrations:/migrations - ./database/infra/scripts/run-migration.sh:/run-migration.sh secrets: - - postgres_user - - postgres_password - - postgres_db + - pg_username + - pg_password + - pg_dbname entrypoint: /run-migration.sh command: "" depends_on: @@ -157,9 +157,9 @@ services: # --- Use Docker Secrets instead of .env files for credentials. # The given postgres image automatically reads from files specified by these _FILE variables. environment: - POSTGRES_USER_FILE: /run/secrets/postgres_user - POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password - POSTGRES_DB_FILE: /run/secrets/postgres_db + POSTGRES_USER_FILE: /run/secrets/pg_username + POSTGRES_PASSWORD_FILE: /run/secrets/pg_password + POSTGRES_DB_FILE: /run/secrets/pg_dbname PGDATA: /var/lib/postgresql/data/pgdata # --- Securing port binding. @@ -173,19 +173,21 @@ services: # --- Define which secrets this service has access to. # These secrets are mounted securely in memory at /run/secrets/ secrets: - - postgres_user - - postgres_password - - postgres_db + - pg_username + - pg_password + - pg_dbname volumes: # Use a Docker Named Volume for data persistence. # This decouples my critical data from the host's file structure, making it # more robust, portable, and managed entirely by Docker. - oullin_db_data:/var/lib/postgresql/data + # Mount SSL certs and config files as read-only (:ro) for security. - ./database/infra/ssl/server.crt:/etc/ssl/certs/server.crt:ro - ./database/infra/ssl/server.key:/etc/ssl/private/server.key - ./database/infra/config/postgresql.conf:/etc/postgresql/postgresql.conf:ro - ./database/infra/scripts/healthcheck.sh:/healthcheck.sh:ro + command: postgres -c config_file=/etc/postgresql/postgresql.conf logging: From ecc0fe2d9a705b2d303a9efdc9e0417b64ddae51 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sat, 5 Jul 2025 16:32:01 +0800 Subject: [PATCH 04/18] make the image names explicit --- config/makefile/build.mk | 3 --- docker-compose.yml | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/config/makefile/build.mk b/config/makefile/build.mk index 165e32df..f7d0cf94 100644 --- a/config/makefile/build.mk +++ b/config/makefile/build.mk @@ -14,9 +14,6 @@ build\:prod: @DB_SECRET_USERNAME="$(DB_SECRET_USERNAME)" \ DB_SECRET_PASSWORD="$(DB_SECRET_PASSWORD)" \ DB_SECRET_DBNAME="$(DB_SECRET_DBNAME)" \ - ENV_DB_USER_NAME="$(ENV_DB_USER_NAME)" \ - ENV_DB_USER_PASSWORD="$(ENV_DB_USER_PASSWORD)" \ - ENV_DB_DATABASE_NAME="$(ENV_DB_DATABASE_NAME)" \ docker compose --profile prod up --build -d build\:release: diff --git a/docker-compose.yml b/docker-compose.yml index 9059c280..37e0540c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,6 +27,7 @@ networks: services: caddy_prod: + image: api-caddy_prod build: context: ./caddy dockerfile: Dockerfile @@ -91,6 +92,7 @@ services: condition: service_healthy api: + image: api-api env_file: - .env environment: From de8df21e54adf078e3587e785fd4db52b41f91e1 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sat, 5 Jul 2025 16:34:12 +0800 Subject: [PATCH 05/18] Empty - Commit From c64a6d848aa63566c7dbd2d615c16fbee68497a6 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sat, 5 Jul 2025 17:04:18 +0800 Subject: [PATCH 06/18] wip --- config/makefile/build.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/makefile/build.mk b/config/makefile/build.mk index f7d0cf94..165e32df 100644 --- a/config/makefile/build.mk +++ b/config/makefile/build.mk @@ -14,6 +14,9 @@ build\:prod: @DB_SECRET_USERNAME="$(DB_SECRET_USERNAME)" \ DB_SECRET_PASSWORD="$(DB_SECRET_PASSWORD)" \ DB_SECRET_DBNAME="$(DB_SECRET_DBNAME)" \ + ENV_DB_USER_NAME="$(ENV_DB_USER_NAME)" \ + ENV_DB_USER_PASSWORD="$(ENV_DB_USER_PASSWORD)" \ + ENV_DB_DATABASE_NAME="$(ENV_DB_DATABASE_NAME)" \ docker compose --profile prod up --build -d build\:release: From eb3345f86104f4658e1a50c074e9dc695c52535c Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sat, 5 Jul 2025 17:06:31 +0800 Subject: [PATCH 07/18] wip --- config/makefile/build.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/makefile/build.mk b/config/makefile/build.mk index 165e32df..11979440 100644 --- a/config/makefile/build.mk +++ b/config/makefile/build.mk @@ -17,7 +17,7 @@ build\:prod: ENV_DB_USER_NAME="$(ENV_DB_USER_NAME)" \ ENV_DB_USER_PASSWORD="$(ENV_DB_USER_PASSWORD)" \ ENV_DB_DATABASE_NAME="$(ENV_DB_DATABASE_NAME)" \ - docker compose --profile prod up --build -d + docker compose --profile prod up --build -d && docker compose logs oullin_db build\:release: @printf "\n$(YELLOW)Tagging images to be released.$(NC)\n" From 888b0851ed4a1dbd0303000f2321f00a048ea0fd Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sat, 5 Jul 2025 17:08:47 +0800 Subject: [PATCH 08/18] wip --- config/makefile/build.mk | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/config/makefile/build.mk b/config/makefile/build.mk index 11979440..f7d0cf94 100644 --- a/config/makefile/build.mk +++ b/config/makefile/build.mk @@ -14,10 +14,7 @@ build\:prod: @DB_SECRET_USERNAME="$(DB_SECRET_USERNAME)" \ DB_SECRET_PASSWORD="$(DB_SECRET_PASSWORD)" \ DB_SECRET_DBNAME="$(DB_SECRET_DBNAME)" \ - ENV_DB_USER_NAME="$(ENV_DB_USER_NAME)" \ - ENV_DB_USER_PASSWORD="$(ENV_DB_USER_PASSWORD)" \ - ENV_DB_DATABASE_NAME="$(ENV_DB_DATABASE_NAME)" \ - docker compose --profile prod up --build -d && docker compose logs oullin_db + docker compose --profile prod up --build -d build\:release: @printf "\n$(YELLOW)Tagging images to be released.$(NC)\n" From 0d6f784a08245914f98aec895d65f667c24aa774 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 14:08:59 +0800 Subject: [PATCH 09/18] wip --- docker-compose.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 37e0540c..2b015427 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -110,13 +110,13 @@ services: - APP_GROUP=${ENV_DOCKER_USER_GROUP} container_name: oullin_api restart: unless-stopped - secrets: - - pg_username - - pg_password - - pg_dbname - depends_on: - api-db: - condition: service_healthy +# secrets: +# - pg_username +# - pg_password +# - pg_dbname +# depends_on: +# api-db: +# condition: service_healthy expose: - ${ENV_HTTP_PORT} networks: From 6e980a82a05c92a91cd6f59781e86b249af7c575 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 14:13:23 +0800 Subject: [PATCH 10/18] Empty - Commit From 3415de06c276467f0b8ab68efec1e156486aa654 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 14:22:10 +0800 Subject: [PATCH 11/18] wip --- database/infra/scripts/healthcheck.sh | 4 ++-- docker-compose.yml | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/database/infra/scripts/healthcheck.sh b/database/infra/scripts/healthcheck.sh index ad3bf8bf..5e354574 100755 --- a/database/infra/scripts/healthcheck.sh +++ b/database/infra/scripts/healthcheck.sh @@ -4,8 +4,8 @@ set -e # Read the secrets into variables. This is more robust than direct command substitution. -DB_USER=$(cat /run/secrets/postgres_user) -DB_NAME=$(cat /run/secrets/postgres_db) +DB_USER=$(cat /run/secrets/pg_username) +DB_NAME=$(cat /run/secrets/pg_dbname) # Explicitly check if the user variable is empty. If it is, fail immediately. # This prevents the "role -d does not exist" error. diff --git a/docker-compose.yml b/docker-compose.yml index 2b015427..37e0540c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -110,13 +110,13 @@ services: - APP_GROUP=${ENV_DOCKER_USER_GROUP} container_name: oullin_api restart: unless-stopped -# secrets: -# - pg_username -# - pg_password -# - pg_dbname -# depends_on: -# api-db: -# condition: service_healthy + secrets: + - pg_username + - pg_password + - pg_dbname + depends_on: + api-db: + condition: service_healthy expose: - ${ENV_HTTP_PORT} networks: From 89ea4c5224d449478876b25812b4eaf7125825aa Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 14:34:24 +0800 Subject: [PATCH 12/18] wip --- .env.example | 4 ++++ .github/workflows/deploy.yml | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/.env.example b/.env.example index 2521ea30..795819fc 100644 --- a/.env.example +++ b/.env.example @@ -34,3 +34,7 @@ ENV_DB_URL="" # --- The logs directory for Caddy to persists its logs. CADDY_LOGS_PATH="./storage/logs/caddy" + +# --- Docker (Local envs) +ENV_DOCKER_USER="gocanto" +ENV_DOCKER_USER_GROUP="ggroup" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f5899383..d00a2288 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -44,6 +44,22 @@ jobs: run: echo "${{ secrets.ENV_FILE_CONTENT }}" > .env shell: bash + - name: 🧐 Verify .env file content + run: | + echo "--- .env file content ---" + cat .env + echo "-------------------------" + + - name: 🌳 Verify directory structure + run: | + echo "--- Current Directory ---" + pwd + echo "--- Listing storage/logs ---" + ls -la ./storage/logs + + - name: ⚙️ Verify Docker Compose config + run: docker compose --profile prod config + - name: Build with Makefile run: make build:prod From e2567d791cc8227791b7dccefc79cafcda070d84 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 14:52:15 +0800 Subject: [PATCH 13/18] wip --- .github/workflows/deploy.yml | 24 ++++-------------------- config/makefile/build.mk | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d00a2288..c60fa083 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -44,26 +44,10 @@ jobs: run: echo "${{ secrets.ENV_FILE_CONTENT }}" > .env shell: bash - - name: 🧐 Verify .env file content - run: | - echo "--- .env file content ---" - cat .env - echo "-------------------------" - - - name: 🌳 Verify directory structure - run: | - echo "--- Current Directory ---" - pwd - echo "--- Listing storage/logs ---" - ls -la ./storage/logs - - - name: ⚙️ Verify Docker Compose config - run: docker compose --profile prod config - - - name: Build with Makefile - run: make build:prod - - - name: Log in to GitHub Container Registry + - name: Build Release Images + run: make build:ci + + - name: Log in to GitHub Registry uses: docker/login-action@v3 with: registry: ghcr.io diff --git a/config/makefile/build.mk b/config/makefile/build.mk index f7d0cf94..17c44ab3 100644 --- a/config/makefile/build.mk +++ b/config/makefile/build.mk @@ -1,4 +1,4 @@ -.PHONY: build\:local build\:prod build\:release +.PHONY: build\:local build\:prod build\:release build\:deploy BUILD_VERSION ?= latest BUILD_PACKAGE_OWNER := oullin @@ -6,16 +6,25 @@ BUILD_PACKAGE_OWNER := oullin build\:local: docker compose --profile local up --build -d +build\:ci: + @printf "\n$(CYAN)Building production images for CI$(NC)\n" + # This 'build' command only builds the images; it does not run them. + @docker compose --profile prod build + +# --- Deprecated +# We should always deploy builds from the CI and not build again in servers. build\:prod: - @printf "\n$(CYAN)docker compose --profile prod up --build -d$(NC)\n" - # --- The following lines take the variables passed to 'make' and export them - # into the shell environment for only the docker-compose command. - # These variable names now EXACTLY match what the Go application expects. @DB_SECRET_USERNAME="$(DB_SECRET_USERNAME)" \ DB_SECRET_PASSWORD="$(DB_SECRET_PASSWORD)" \ DB_SECRET_DBNAME="$(DB_SECRET_DBNAME)" \ docker compose --profile prod up --build -d +build\:deploy: + @DB_SECRET_USERNAME="$(DB_SECRET_USERNAME)" \ + DB_SECRET_PASSWORD="$(DB_SECRET_PASSWORD)" \ + DB_SECRET_DBNAME="$(DB_SECRET_DBNAME)" \ + docker compose --profile prod up -d + build\:release: @printf "\n$(YELLOW)Tagging images to be released.$(NC)\n" docker tag api-api ghcr.io/$(BUILD_PACKAGE_OWNER)/oullin_api:$(BUILD_VERSION) && \ From f25a3215b841714ed299cb37ac90c0f3b11e9306 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 14:57:07 +0800 Subject: [PATCH 14/18] Empty - Commit From 436c2f5f53ebcb45e9e955672706bc6c7b32f394 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 14:59:10 +0800 Subject: [PATCH 15/18] Empty - Commit From 33d169064b1a1f242ab51a6aa78a82a0698c0074 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 15:01:20 +0800 Subject: [PATCH 16/18] wip --- .env.gh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .env.gh diff --git a/.env.gh b/.env.gh new file mode 100644 index 00000000..4d18b68a --- /dev/null +++ b/.env.gh @@ -0,0 +1,4 @@ +ENV_HTTP_PORT=8080 +ENV_DOCKER_USER=gocanto +ENV_DOCKER_USER_GROUP=ggroup +CADDY_LOGS_PATH=./storage/logs/caddy From bf45bbf40d746c0322970282a0dba2d4fa93716b Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 15:02:15 +0800 Subject: [PATCH 17/18] message --- database/infra/scripts/healthcheck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/infra/scripts/healthcheck.sh b/database/infra/scripts/healthcheck.sh index 5e354574..856e848f 100755 --- a/database/infra/scripts/healthcheck.sh +++ b/database/infra/scripts/healthcheck.sh @@ -10,7 +10,7 @@ DB_NAME=$(cat /run/secrets/pg_dbname) # Explicitly check if the user variable is empty. If it is, fail immediately. # This prevents the "role -d does not exist" error. if [ -z "$DB_USER" ]; then - echo "Healthcheck Error: The postgres_user secret is empty or could not be read." >&2 + echo "Healthcheck Error: The pg_username secret is empty or could not be read." >&2 exit 1 fi From 91a9c93fbfb56f114145271a48252f076f259b78 Mon Sep 17 00:00:00 2001 From: Gustavo Ocanto Date: Sun, 6 Jul 2025 15:06:17 +0800 Subject: [PATCH 18/18] wip --- .env.gh => .env.gh.example | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .env.gh => .env.gh.example (100%) diff --git a/.env.gh b/.env.gh.example similarity index 100% rename from .env.gh rename to .env.gh.example