Switch backend to wait for SQL Server and use direct INSERTs

Replace stored procedure calls with inline INSERT statements and
SCOPE_IDENTITY()
Add netcat for readiness check in new entrypoint.sh
Introduce dedicated SQL Server and init-db services in docker-compose
This commit is contained in:
2026-02-22 09:36:38 -05:00
parent c780dff015
commit 2d1f55eea1
6 changed files with 120 additions and 21 deletions

View File

@@ -20,15 +20,19 @@ FROM alpine:3.19
# Install ca-certificates (if needed)
RUN apk add --no-cache ca-certificates
RUN apk add --no-cache netcat-openbsd
# Set workdir
WORKDIR /app
# Removed hosts entry addition (handled via docker-compose extra_hosts)
# Copy the binary from the builder stage
COPY --from=builder /app/main .
# Expose the application port (default for the Go server)
COPY entrypoint.sh .
RUN chmod +x entrypoint.sh
EXPOSE 8080
# Command to run the binary
CMD ["./main"]
CMD ["./entrypoint.sh"]

24
backend/entrypoint.sh Normal file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env sh
# entrypoint.sh wait for the SQL Server container to become ready
# before starting the Go backend binary.
set -e
# Default environment variables (can be overridden in docker-compose)
: "${DB_SERVER:=sql}"
: "${DB_USER:=sa}"
: "${DB_PASSWORD:=Ou812@12!@}"
# Wait until netcat can successfully connect to the SQL Server port
while ! nc -z "$DB_SERVER" 1433; do
echo "⏳ Waiting for SQL Server at $DB_SERVER:1433..."
sleep 1
done
# Add a short pause after the port is open to let SQL Server finish startup
sleep 5
# Add a short pause after the port is open to let SQL Server finish startup
sleep 2
echo "✅ SQL Server is ready. Starting backend."
exec ./main

View File

@@ -41,17 +41,9 @@ func main() {
// -----------------------------------------------------------------
var newCustID int
insertCustSQL := `
DECLARE @NewID int;
EXEC dbo.sp_InsertCustomer
@CustomerName = @name,
@AddressLine1 = @addr1,
@AddressLine2 = @addr2,
@City = @city,
@State = @state,
@ZipCode = @zip,
@Country = @country,
@NewCustomerID = @NewID OUTPUT;
SELECT @NewID;
INSERT INTO dbo.Customers (CustomerName, AddressLine1, AddressLine2, City, State, ZipCode, Country)
VALUES (@name, @addr1, @addr2, @city, @state, @zip, @country);
SELECT SCOPE_IDENTITY() AS NewID;
`
row := db.QueryRow(insertCustSQL,
sql.Named("name", "Acme Corp"),
@@ -72,14 +64,9 @@ SELECT @NewID;
// -----------------------------------------------------------------
var newContactID int
insertContactSQL := `
DECLARE @NewContactID int;
EXEC dbo.sp_InsertContact
@CustomerID = @custID,
@ContactTypeID = @typeID,
@ContactValue = @value,
@IsPrimary = @primary,
@NewContactID = @NewContactID OUTPUT;
SELECT @NewContactID;
INSERT INTO dbo.Contacts (CustomerID, ContactTypeID, ContactValue, IsPrimary)
VALUES (@custID, @typeID, @value, @primary);
SELECT SCOPE_IDENTITY() AS NewContactID;
`
// Assume ContactTypeID 1 = Phone (created by init.sql)
row = db.QueryRow(insertContactSQL,

27
db/Dockerfile Normal file
View File

@@ -0,0 +1,27 @@
# Dockerfile for DB init service
FROM mcr.microsoft.com/mssql/server:2022-latest
# Set SQL Server environment variables
ENV SA_PASSWORD=Ou812@12!@ \
ACCEPT_EULA=Y
# Set working directory inside the container
WORKDIR /usr/src/app
# Copy the initialization script and SQL file into the image
COPY --chmod=0755 init.sh .
COPY init.sql .
# Make the script executable
# Start SQL Server, wait until it is ready, then run the init script
CMD /opt/mssql/bin/sqlservr & \
/bin/bash -c "\
until /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $$SA_PASSWORD -Q \"SELECT 1\" >/dev/null 2>&1; do \
sleep 1; \
done && \
./init.sh && \
tail -f /dev/null \
"

32
db/init.sh Normal file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# init.sh - Initialize the SQL Server database with the schema and sample data.
# This script is intended to be run inside the SQL Server container (or from the host
# with sqlcmd reachable). It executes the init.sql script located in the same
# directory.
set -euo pipefail
# Default connection settings can be overridden via environment variables
: "${DB_SERVER:=localhost}"
: "${DB_USER:=sa}"
: "${DB_PASSWORD:=YourStrong!Passw0rd}"
: "${DB_NAME:=CustomerDB}"
: "${SQLCMD_PATH:=sqlcmd}" # Path to the sqlcmd executable
# Path to the init script (relative to this script's location)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INIT_SQL="${SCRIPT_DIR}/init.sql"
if [[ ! -f "${INIT_SQL}" ]]; then
echo "❌ init.sql not found at ${INIT_SQL}"
exit 1
fi
echo "🚀 Running database initialization..."
"${SQLCMD_PATH}" -S "${DB_SERVER}" -U "${DB_USER}" -P "${DB_PASSWORD}" -d "master" -Q "IF DB_ID(N'${DB_NAME}') IS NULL CREATE DATABASE ${DB_NAME};"
# Run the init script against the newly created database
"${SQLCMD_PATH}" -S "${DB_SERVER}" -U "${DB_USER}" -P "${DB_PASSWORD}" -d "${DB_NAME}" -i "${INIT_SQL}"
echo "✅ Database ${DB_NAME} initialized successfully."

View File

@@ -1,14 +1,39 @@
services:
sql:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: sql
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=Ou812@12!@
ports:
- "1433:1433"
backend:
build:
context: ./backend
dockerfile: Dockerfile
depends_on:
- sql
container_name: backend
environment:
- DB_SERVER=homelab.local
- DB_SERVER=sql
- DB_USER=sa
- DB_PASSWORD=Ou812@12!@
- DB_NAME=CustomerDB
ports:
- "8080:8080"
command: ./main
extra_hosts:
- "homelab.local:192.168.1.129"
init-db:
build:
context: ./db
dockerfile: Dockerfile
container_name: init-db
depends_on:
- sql
environment:
- DB_SERVER=sql
- DB_USER=sa
- DB_PASSWORD=Ou812@12!@
- DB_NAME=CustomerDB