I am currently working on a Robotic automation application based on Java 17, The build tool used in this application is Maven 3.9.2.
I have been successful in building this application in a local development environment. To do so the used command was
mvn clean install -Pdev -DactiveProfile=dev -DconfigFile=config-dev.properties
This command is used to build and install a Maven project with specific profiles and configuration properties. In summary, the command is cleaning the project, compiling and packaging it, and then installing it in the local Maven repository. It’s also activating the "dev" profile and specifying a configuration file named "config-dev.properties" for use during the build. The specifics of the "dev" profile and "config-dev.properties" are listed below.
Special parameters were used in the maven command to handle special scenarios related to the project at hand.
-Pdev: This activates the Maven profile named "dev". Maven profiles allow you to customize the build process for different environments or scenarios. In this case, the "dev" profile is being activated.
-DactiveProfile=dev: This sets a system property named "activeProfile" with the value "dev". This can be used within the Maven build to conditionally execute certain tasks based on the active profile.
-DconfigFile=config-dev.properties: This sets a system property named "configFile" with the value "config-dev.properties". Similar to the "activeProfile" property, this allows configuration parameters to be passed to the Maven build. In this case, it specifies a configuration file to be used during the build.
For multiple environments, I have maintained multiple config files with development environment-specific information.
Config-dev.properties,config_localqa.properties, config_clientqa.properties, etc.
Configuration.xlsm with rapport preferences is also available which the selenium application uses as a reference. these files are in the resource folder.
Related POM.xml contents
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>report-automation</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Default config file for fallback -->
<config.file>config.properties</config.file>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.0</version> <!-- Use your specific version -->
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
<includes>
<include>**/*Model.java</include>
</includes>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>Configuration.xlsm</exclude>
</excludes>
</resource>
</resources>
</build>
<profiles>
<!-- Profile for Development Environment -->
<profile>
<id>dev</id>
<properties>
<config.file>config-dev.properties</config.file>
<activeProfile>dev</activeProfile>
</properties>
</profile>
<!-- Profile for Local QA Environment -->
<profile>
<id>localqa</id>
<properties>
<config.file>config-localqa.properties</config.file>
<activeProfile>localqa</activeProfile>
</properties>
</profile>
<!-- Add profiles for other environments -->
<!--
<profile>
<id>clientuat</id>
<properties>
<config.file>config-clientuat.properties</config.file>
<activeProfile>clientuat</activeProfile>
</properties>
</profile>
<profile>
<id>clientqa</id>
<properties>
<config.file>config-clientqa.properties</config.file>
<activeProfile>clientqa</activeProfile>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<config.file>config-production.properties</config.file>
<activeProfile>production</activeProfile>
</properties>
</profile>
-->
</profiles>
<dependencies>
<!-- Selenium -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.11.0</version>
</dependency>
<!-- TestNG -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.4.0</version>
</dependency>
<!-- ExtentReports -->
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>5.0.9</version>
</dependency>
<!-- SLF4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>2.0.5</version>
</dependency>
<!-- OpenCSV -->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.7.1</version>
</dependency>
<!-- Apache POI -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
</dependency>
<!-- Log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>
<!-- maven-invoker -->
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-invoker</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Config-dev.properties contents
Backup-File Location
relativeDownloadLocation = Downloads/
File-Location for Back-End Service
absoluteDownloadLocation = ../backend-service/src/main/resources/report/
configFilePath
configFilePath = src/main/resources/config-dev.properties
Project Directory
project.directory=.
Project Resource Directory
resource.directory=src/main/resources/
Maven Home - change according to environment
maven.home=/rezsystem/apache-maven-3.9.2
Availability Report properties
availabilityReportFileName=Availability Report.csv
comprehensive report properties
comprehensiveReportFileName=Comprehensive Sales Report Detailed.csv
My Issue is when I attempt to Dockerize this application I am facing a few issues.
I attempted to update the Docker file to handle the local development scenario.
Docker File
# Use the official Maven image as a build stage
FROM maven:3.8-openjdk-17 AS builder
# Set the working directory
WORKDIR /app
# Copy the source code to the working directory
COPY . .
# Build the Maven project and create the JAR file
ARG MAVEN_OPTS="-Pdev -DactiveProfile=dev -DconfigFile=config-dev.properties"
RUN mvn clean install $MAVEN_OPTS
# Use the official OpenJDK 17 image as the final image
FROM openjdk:17
# Set the working directory inside the container
WORKDIR /app
# Copy the JAR file from the builder stage
COPY --from=builder /app/target/report-automation.jar /app/report-automation.jar
# Copy the appropriate config file based on Maven profile
COPY src/main/resources/config-dev.properties /app/src/main/resources/config-dev.properties
# Copy the Configuration.xlsm file from the source to the working directory in the container
COPY src/main/resources/Configuration.xlsm /app/src/main/resources/Configuration.xlsm
# Expose the port (if your application listens on a specific port)
# EXPOSE 8080
# Set the entry point for the container (replace with your main class)
ENTRYPOINT ["java", "-jar", "report-automation.jar"]
Docker build command used
docker build –build-arg MAVEN_OPTS="-Pdev -DactiveProfile=dev -DconfigFile=config-dev.properties" -t selenium-app .
Encountered Error
docker build --build-arg MAVEN_OPTS="-Pdev -DactiveProfile=dev -DconfigFile=config-dev.properties" -t selenium-app .
[+] Building 3.7s (10/14)
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 1.19kB 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/openjdk:17 2.6s
=> [internal] load metadata for docker.io/library/maven:3.8-openjdk-17 2.6s
=> [internal] load build context 0.1s
=> => transferring context: 33.52kB 0.0s
=> [builder 1/4] FROM docker.io/library/maven:3.8-openjdk-17@sha256:3a9c30b3af6278a8ae0007d3a3bf00fff80ec3ed7ae4eb9bfa1772853101549b 0.0s
=> [stage-1 1/5] FROM docker.io/library/openjdk:17@sha256:528707081fdb9562eb819128a9f85ae7fe000e2fbaeaf9f87662e7b3f38cb7d8 0.0s
=> CACHED [builder 2/4] WORKDIR /app 0.0s
=> [builder 3/4] COPY . . 0.6s
=> ERROR [builder 4/4] RUN mvn clean install -Pdev -DactiveProfile=dev -DconfigFile=config-dev.properties 0.4s
------
> [builder 4/4] RUN mvn clean install -Pdev -DactiveProfile=dev -DconfigFile=config-dev.properties:
#0 0.291 Unrecognized option: -Pdev
#0 0.291 Error: Could not create the Java Virtual Machine.
#0 0.291 Error: A fatal exception has occurred. Program will exit.
------
ERROR: failed to solve: executor failed running [/bin/sh -c mvn clean install $MAVEN_OPTS]: exit code: 1
How can I resolve these issues encountered when attempting to Dockerize the application? Are there any updates required in the Docker file?
2
Answers
You can switch from shell form to exec form to make this work:
Common Docker Deployment Issues and Solutions
Container Configuration Errors:
Problem: Incorrect Dockerfile instructions, missing dependencies, or environment variables.
Solution: Review your Dockerfile for accuracy, ensure all necessary dependencies are included, and set required environment variables.
Network Connectivity Issues:
Problem: Containers not able to communicate with each other or with external services.
Solution: Configure Docker networking correctly, using bridges, overlays, or host networks as needed. Ensure ports are correctly exposed and mapped.
Volume Mounting Problems:
Problem: Data persistence issues or access denied errors when trying to mount volumes.
Solution: Check volume paths, permissions, and ensure that Docker has access to the directories you’re trying to mount.
Compatibility Issues:
Problem: Application runs on local machine but fails in Docker due to differences in environments.
Solution: Use the same base images for development and production. Ensure all environmental dependencies are declared and met.
Resource Constraints:
Problem: Application performance issues due to insufficient CPU or memory allocation.
Solution: Allocate more resources to the container through Docker settings or limit resource usage of the application if possible.
Logging and Monitoring:
Problem: Difficulty in debugging issues due to lack of logs or monitoring.
Solution: Implement logging in your application and configure Docker to capture these logs. Use monitoring tools to keep track of container health and performance.
Best Practices for Docker Deployment
Use Docker Compose: For multi-container setups, Docker Compose can simplify the configuration and management of your containers.
Keep Images Lightweight: Minimize the size of your Docker images by using smaller base images and removing unnecessary dependencies.
Environment Consistency: Ensure development, testing, and production environments are as similar as possible to avoid "it works on my machine" issues.
Security Practices: Follow best practices for Docker security, like using non-root users inside containers and scanning images for vulnerabilities.
Regular Updates: Keep your Docker images and containers updated with the latest security patches and software versions.