Skip to content
Merged
65 changes: 65 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# .dockerignore — files excluded from Docker build context

# Maven / Gradle build output (compiled on container, not copied)
target/
!.mvn/wrapper/

# IDE files
.idea/
*.iml
.vscode/
.eclipse/
*.swp
*.swo
*~

# Git
.git/
.gitignore
.gitattributes

# Environment and secrets
.env
.env.*
*.env
!.env.example

# Documentation (not needed inside the image)
*.md
README.md
CONTEXT.md
DECISIONS.md
SECURITY.md
AGENTS.md
HELP.md
CONTRIBUTING.md
CODE_OF_CONDUCT.md
LICENSE

# Logs (generated at runtime)
logs/
*.log

# Database scripts (only used by PostgreSQL container, not the app)
database/

# Docker files (not needed inside the image)
docker-compose.yml
docker-compose.*.yml
Dockerfile
.dockerignore

# Scripts
script/

# CI/CD
.github/

# OS junk
.DS_Store
Thumbs.db

# Dependency vulnerability reports
owasp-suppressions.xml
dependency-check-report.*
target/dependency-check-*/
38 changes: 38 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Stage 1: Build — compiles the project and produces the .jar
FROM maven:3.9-eclipse-temurin-17-alpine AS build

WORKDIR /app

# Copy pom.xml first to leverage Docker layer caching.
# If pom.xml hasn't changed, this layer is reused and dependencies
# are not downloaded again.
COPY pom.xml .

# Download all dependencies without compiling.
# This creates a separate cacheable layer independent of source code.
RUN mvn dependency:go-offline -B

COPY src ./src
RUN mvn package -B -DskipTests

# Stage 2: Run — lightweight final image, only JRE + .jar
FROM eclipse-temurin:17-jre-alpine AS run

# Create non-root user for security.
# OWASP A05: never run container processes as root.
RUN addgroup -S wallet && adduser -S wallet -G wallet

WORKDIR /app

# Copy the .jar from the build stage and set owner in one step.
# The *.jar pattern works because there is only one .jar in target/
# (the sources jar is excluded in assembly config).
COPY --from=build --chown=wallet:wallet /app/target/*.jar app.jar

# Switch to non-root user before running the app.
USER wallet

# This does NOT open the port — docker-compose or docker run -p does that.
EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]
26 changes: 26 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,32 @@ services:
cpus: '0.5'
memory: 256M

wallet-api:
build:
context: .
dockerfile: Dockerfile
container_name: secure-wallet-api
restart: no
environment:
SPRING_PROFILES_ACTIVE: dev
# POSTGRES_HOST=postgres because inside the Docker network
# services resolve by service name, not localhost.
POSTGRES_HOST: postgres
POSTGRES_PORT: ${POSTGRES_PORT}
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
# JWT from .env
JWT_SECRET: ${JWT_SECRET}
SERVER_PORT: ${SERVER_PORT:-8080}
ports:
- "${SERVER_PORT:-8080}:${SERVER_PORT:-8080}"
networks:
- wallet-network
depends_on:
postgres:
condition: service_healthy

pgadmin:
image: dpage/pgadmin4:latest
container_name: secure-wallet-pgadmin
Expand Down
Loading