Skip to content

Commit 00c9334

Browse files
committed
FEATURE (docker): Refactor Dockerfile for platform compatibility and improved PostgreSQL setup
1 parent 21770b2 commit 00c9334

File tree

1 file changed

+106
-79
lines changed

1 file changed

+106
-79
lines changed

Dockerfile

Lines changed: 106 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,180 @@
11
# ========= BUILD FRONTEND =========
2-
FROM --platform=linux/arm64 node:24-alpine AS frontend-build
2+
FROM --platform=$BUILDPLATFORM node:24-alpine AS frontend-build
3+
34
WORKDIR /frontend
45

6+
# Add version for the frontend build
57
ARG APP_VERSION=dev
68
ENV VITE_APP_VERSION=$APP_VERSION
79

810
COPY frontend/package.json frontend/package-lock.json ./
911
RUN npm ci
1012
COPY frontend/ ./
1113

12-
RUN if [ ! -f .env ] && [ -f .env.production.example ]; then \
13-
cp .env.production.example .env; \
14+
# Copy .env file (with fallback to .env.production.example)
15+
RUN if [ ! -f .env ]; then \
16+
if [ -f .env.production.example ]; then \
17+
cp .env.production.example .env; \
18+
fi; \
1419
fi
1520

1621
RUN npm run build
1722

1823
# ========= BUILD BACKEND =========
19-
FROM --platform=linux/arm64 golang:1.23.3 AS backend-build
24+
# Backend build stage
25+
FROM --platform=$BUILDPLATFORM golang:1.23.3 AS backend-build
26+
27+
# Make TARGET args available early so tools built here match the final image arch
28+
ARG TARGETOS
29+
ARG TARGETARCH
30+
31+
# Install Go public tools needed in runtime. Use `go install` for goose so the
32+
# binary is compiled for the target architecture instead of downloading a
33+
# prebuilt binary which may have the wrong architecture (causes exec format
34+
# errors on ARM).
35+
RUN env GOBIN=/usr/local/bin GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
36+
go install github.com/pressly/goose/v3/cmd/goose@latest
37+
RUN go install github.com/swaggo/swag/cmd/[email protected]
38+
39+
# Set working directory
2040
WORKDIR /app
2141

22-
# Install Go tools for ARM64
23-
RUN go install github.com/pressly/goose/v3/cmd/goose@latest \
24-
&& go install github.com/swaggo/swag/cmd/[email protected]
25-
42+
# Install Go dependencies
2643
COPY backend/go.mod backend/go.sum ./
2744
RUN go mod download
2845

29-
# Copy frontend build into backend
46+
# Create required directories for embedding
3047
RUN mkdir -p /app/ui/build
48+
49+
# Copy frontend build output for embedding
3150
COPY --from=frontend-build /frontend/dist /app/ui/build
3251

52+
# Generate Swagger documentation
3353
COPY backend/ ./
3454
RUN swag init -d . -g cmd/main.go -o swagger
3555

36-
RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 \
56+
# Compile the backend
57+
ARG TARGETOS
58+
ARG TARGETARCH
59+
ARG TARGETVARIANT
60+
RUN CGO_ENABLED=0 \
61+
GOOS=$TARGETOS \
62+
GOARCH=$TARGETARCH \
3763
go build -o /app/main ./cmd/main.go
3864

65+
3966
# ========= RUNTIME =========
40-
FROM --platform=linux/arm64 debian:bookworm-slim
67+
FROM --platform=$TARGETPLATFORM debian:bookworm-slim
4168

69+
# Add version metadata to runtime image
4270
ARG APP_VERSION=dev
4371
LABEL org.opencontainers.image.version=$APP_VERSION
4472
ENV APP_VERSION=$APP_VERSION
4573

46-
# Install PostgreSQL clients (13–17) and runtime deps
47-
RUN apt-get update \
48-
&& apt-get install -y --no-install-recommends wget ca-certificates gnupg lsb-release sudo gosu \
49-
&& echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
50-
> /etc/apt/sources.list.d/pgdg.list \
51-
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor \
52-
> /etc/apt/trusted.gpg.d/postgresql.gpg \
53-
&& apt-get update \
54-
&& apt-get install -y --no-install-recommends \
55-
postgresql-17 \
56-
postgresql-client-13 \
57-
postgresql-client-14 \
58-
postgresql-client-15 \
59-
postgresql-client-16 \
60-
postgresql-client-17 \
61-
&& rm -rf /var/lib/apt/lists/*
62-
63-
# Create data dir and set ownership (postgres user already exists)
64-
RUN mkdir -p /postgresus-data/pgdata \
65-
&& chown -R postgres:postgres /postgresus-data
74+
# Install PostgreSQL server and client tools (versions 13-17)
75+
RUN apt-get update && apt-get install -y --no-install-recommends \
76+
wget ca-certificates gnupg lsb-release sudo gosu && \
77+
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \
78+
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
79+
> /etc/apt/sources.list.d/pgdg.list && \
80+
apt-get update && \
81+
apt-get install -y --no-install-recommends \
82+
postgresql-17 postgresql-client-13 postgresql-client-14 postgresql-client-15 \
83+
postgresql-client-16 postgresql-client-17 && \
84+
rm -rf /var/lib/apt/lists/*
85+
86+
# Create postgres user and set up directories
87+
RUN useradd -m -s /bin/bash postgres || true && \
88+
mkdir -p /postgresus-data/pgdata && \
89+
chown -R postgres:postgres /postgresus-data/pgdata
6690

6791
WORKDIR /app
6892

69-
# Copy goose and app binary from build stage
70-
COPY --from=backend-build /go/bin/goose /usr/local/bin/goose
93+
# Copy Goose from build stage
94+
COPY --from=backend-build /usr/local/bin/goose /usr/local/bin/goose
95+
96+
# Copy app binary
7197
COPY --from=backend-build /app/main .
72-
COPY --from=backend-build /app/ui/build ./ui/build
73-
COPY --from=backend-build /app/swagger ./swagger
98+
99+
# Copy migrations directory
74100
COPY backend/migrations ./migrations
75101

76-
# Copy env file if present
102+
# Copy UI files
103+
COPY --from=backend-build /app/ui/build ./ui/build
104+
105+
# Copy .env file (with fallback to .env.production.example)
77106
COPY backend/.env* /app/
78-
RUN if [ ! -f /app/.env ] && [ -f /app/.env.production.example ]; then \
79-
cp /app/.env.production.example /app/.env; \
107+
RUN if [ ! -f /app/.env ]; then \
108+
if [ -f /app/.env.production.example ]; then \
109+
cp /app/.env.production.example /app/.env; \
110+
fi; \
80111
fi
81112

82-
# Startup script (no rogue \q, DSN format for goose)
83-
COPY <<'EOF' /app/start.sh
113+
# Create startup script
114+
COPY <<EOF /app/start.sh
84115
#!/bin/bash
85116
set -e
86117

118+
# PostgreSQL 17 binary paths
87119
PG_BIN="/usr/lib/postgresql/17/bin"
88120

121+
# Ensure proper ownership of data directory
89122
echo "Setting up data directory permissions..."
90123
mkdir -p /postgresus-data/pgdata
91124
chown -R postgres:postgres /postgresus-data
92125

126+
# Initialize PostgreSQL if not already initialized
93127
if [ ! -s "/postgresus-data/pgdata/PG_VERSION" ]; then
94-
echo "Initializing PostgreSQL database..."
95-
gosu postgres $PG_BIN/initdb -D /postgresus-data/pgdata --encoding=UTF8 --locale=C.UTF-8
96-
echo "host all all 127.0.0.1/32 md5" >> /postgresus-data/pgdata/pg_hba.conf
97-
echo "local all all trust" >> /postgresus-data/pgdata/pg_hba.conf
98-
echo "port = 5437" >> /postgresus-data/pgdata/postgresql.conf
99-
echo "listen_addresses = 'localhost'" >> /postgresus-data/pgdata/postgresql.conf
100-
echo "shared_buffers = 256MB" >> /postgresus-data/pgdata/postgresql.conf
101-
echo "max_connections = 100" >> /postgresus-data/pgdata/postgresql.conf
128+
echo "Initializing PostgreSQL database..."
129+
gosu postgres \$PG_BIN/initdb -D /postgresus-data/pgdata --encoding=UTF8 --locale=C.UTF-8
130+
131+
# Configure PostgreSQL
132+
echo "host all all 127.0.0.1/32 md5" >> /postgresus-data/pgdata/pg_hba.conf
133+
echo "local all all trust" >> /postgresus-data/pgdata/pg_hba.conf
134+
echo "port = 5437" >> /postgresus-data/pgdata/postgresql.conf
135+
echo "listen_addresses = 'localhost'" >> /postgresus-data/pgdata/postgresql.conf
136+
echo "shared_buffers = 256MB" >> /postgresus-data/pgdata/postgresql.conf
137+
echo "max_connections = 100" >> /postgresus-data/pgdata/postgresql.conf
102138
fi
103139

140+
# Start PostgreSQL in background
104141
echo "Starting PostgreSQL..."
105-
gosu postgres $PG_BIN/postgres -D /postgresus-data/pgdata -p 5437 &
106-
POSTGRES_PID=$!
142+
gosu postgres \$PG_BIN/postgres -D /postgresus-data/pgdata -p 5437 &
143+
POSTGRES_PID=\$!
107144

145+
# Wait for PostgreSQL to be ready
108146
echo "Waiting for PostgreSQL to be ready..."
109147
for i in {1..30}; do
110-
if gosu postgres $PG_BIN/pg_isready -p 5437 -h localhost >/dev/null 2>&1; then
111-
echo "PostgreSQL is ready!"
112-
break
113-
fi
114-
if [ $i -eq 30 ]; then
115-
echo "PostgreSQL failed to start"
116-
exit 1
117-
fi
118-
sleep 1
148+
if gosu postgres \$PG_BIN/pg_isready -p 5437 -h localhost >/dev/null 2>&1; then
149+
echo "PostgreSQL is ready!"
150+
break
151+
fi
152+
if [ \$i -eq 30 ]; then
153+
echo "PostgreSQL failed to start"
154+
exit 1
155+
fi
156+
sleep 1
119157
done
120158

159+
# Create database and set password for postgres user
121160
echo "Setting up database and user..."
122-
gosu postgres $PG_BIN/psql -p 5437 -h localhost -d postgres <<'SQL'
161+
gosu postgres \$PG_BIN/psql -p 5437 -h localhost -d postgres << 'SQL'
123162
ALTER USER postgres WITH PASSWORD 'Q1234567';
163+
CREATE DATABASE "postgresus" OWNER postgres;
164+
\q
124165
SQL
125166

126-
# Create the database using createdb (avoids running CREATE DATABASE inside a function)
127-
if ! gosu postgres $PG_BIN/psql -p 5437 -h localhost -tAc "SELECT 1 FROM pg_database WHERE datname='postgresus'" | grep -q 1; then
128-
echo "Creating database 'postgresus'..."
129-
gosu postgres $PG_BIN/createdb -p 5437 -h localhost -O postgres postgresus || {
130-
echo "Failed to create database 'postgresus'"
131-
exit 1
132-
}
133-
else
134-
echo "Database 'postgresus' already exists"
135-
fi
136-
137-
echo "Running database migrations..."
138-
# Use goose with explicit driver and DB string; also export env vars so goose can pick them up if it expects
139-
export GOOSE_DRIVER=postgres
140-
export GOOSE_DBSTRING="postgres://postgres:Q1234567@localhost:5437/postgresus?sslmode=disable"
141-
# Run goose with env vars set (goose recognizes GOOSE_DRIVER and GOOSE_DBSTRING)
142-
/usr/local/bin/goose -dir ./migrations up
143-
167+
# Start the main application
144168
echo "Starting Postgresus application..."
145169
exec ./main
146170
EOF
147171

148172
RUN chmod +x /app/start.sh
149173

150174
EXPOSE 4005
175+
176+
# Volume for PostgreSQL data
151177
VOLUME ["/postgresus-data"]
152178

153-
CMD ["/app/start.sh"]
179+
ENTRYPOINT ["/app/start.sh"]
180+
CMD []

0 commit comments

Comments
 (0)