I need to provide a POC as argument for the migration of workflows in my current job. Currently we do this:
- People code on Netbeans
- People click on build on netbeans
- Deploy locally
- Apply code changes
- Netbeans rebuilds and redeploy the code.
Things to know:
- It seems tomcat detects when a new WAR is put in the directory and hot-deploys it;
- What I aim to automate is not the hot-deploy(since this is already a tomcat feature), but the build process;
- We are using Maven to build the project.
- I'm using docker-compose to get everything up in one single specification.
So far I was able to containerize the Postgres database, the PGAdmin we use and the initial build of the application using a multi-stage Dockerfile.
Tomcat app Dockerfile
FROM maven AS buildserver
ADD . /usr/src/mymaven/
WORKDIR /usr/src/mymaven
# build the project
RUN mvn -f pom.xml clean package -DskipTests
FROM tomcat:latest
COPY conf-tomcat/tomcat-users.xml /usr/local/tomcat/conf/
COPY conf-tomcat/server.xml /usr/local/tomcat/conf/
COPY conf-tomcat/context.xml /usr/local/tomcat/webapps/manager/META-INF/
# Copy the built war file into webapps folder of tomcat container
COPY --from=buildserver /usr/src/mymaven/target/*.war /usr/local/tomcat/webapps
What I am having trouble with is triggering the rebuild when there's code changes (imitating what netbeans does). I can't find in either maven's or netbeans documentation how that detection and triggering works.
I am using volumes to map the app source directory to the container in hopes that it would just work, but I was wrong.
My docker-compose.yml is as follows:
version: '3'
services:
pgadmin:
container_name: pgadmin
image: dpage/pgadmin4
env_file:
- ../db-postgres/pgadmin/pgadmin.env
depends_on:
- pg-dev
networks:
- dev-network
volumes:
- pgadmin-data:/var/lib/pgadmin
ports:
- "88:80"
pg-dev:
container_name: pg-dev
image: pg-dev:latest
env_file:
- ../db-postgres/db-dev/pg-dev.env
volumes:
- pg-data:/var/lib/postgresql/data
networks:
- dev-network
ports:
- "5433:5432"
app:
container_name: app
build: .
volumes:
- app-src:/usr/src/mymaven
- artifacts:/usr/src/mymaven/target
- maven-repo:/root/.m2
networks:
- dev-network
ports:
- "8888:8080"
depends_on:
- pg-dev
volumes:
maven-repo:
driver: local
driver_opts:
type: bind
device: $HOME/.m2
o: bind
app-src:
driver: local
driver_opts:
type: bind
device: .
o: bind
artifacts:
driver: local
driver_opts:
type: bind
device: target/
o: bind
pg-data:
pgadmin-data:
networks:
dev-network:
Any help in coming up with a solution for this is appreciated, as well as any general advice in how to make this workflow/build improve.
UPDATE
I came up with somewhat of a work around, but now I am having problem testing it.
I defined a maven container to work as a build server:
FROM maven
ADD . /usr/src/mymaven/
WORKDIR /usr/src/mymaven
RUN apt update && apt install entr -y
# build the project
RUN mvn -f pom.xml clean package -DskipTests
and now I am defining the entrypoint on the docker-compose.yml:
...
buildserver:
container_name: buildserver
build:
context: .
dockerfile: maven-builder.Dockerfile
volumes:
- app-src:/usr/src/mymaven
- maven-repo:/root/.m2
- artifacts:/usr/src/mymaven/target
networks:
- dev-network
entrypoint: sh -c 'find src/ | entr mvn -f pom.xml clean package -DskipTests --batch-mode'
...
But now I am getting an error message when this container gets up:
find: ‘src/’: No such file or directory
entr: No regular files to watch
Which is weird to me as I successfully build the project in the first run, but the entry-point seems to be failing.
Clarification: What I am being asked is come up with a workflow that removes the need to use the deploy from Netbeans (they want everything automatic). I looked around for a Jenkins workflow, but could not really find a way to achieve the desired results.