diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6bfd6a4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,26 @@ +# Version control +.git +.github + +# Gradle build outputs / caches (must always be rebuilt fresh inside the image) +.gradle +build/ +.kotlin +!gradle/wrapper/gradle-wrapper.jar + +# IDE +.idea +.vscode +.run +*.iml +*.iws +*.ipr + +# Docker-only local files (secrets/env must never be baked into the image) +docker/.env +docker/*.env.docker +docker/*.secret + +# Misc +*.hprof +.gradle-docker-cache/ diff --git a/build.gradle.kts b/build.gradle.kts index 8e02f94..79a446e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -58,40 +58,6 @@ tasks.withType().configureEach { jvmArgs("-javaagent:$agentJar") } } -tasks.test { - dependsOn("copyEnv") -} - -tasks.register("copyEnv") { - group = "docker" - description = "copy the default dotenv file" - from("docker") - into("docker") - rename { - it.removeSuffix(".template") - } - include(".env.template") - eachFile { - if (File("docker/$name").exists()) { - exclude() - } - } - val files = - buildList { - add(File("docker/postgresql.secret")) - if (!project.hasProperty("ci")) { - add(File("docker/pgadmin.secret")) - } - } - outputs.files(*files.toTypedArray()) - doLast { - files.forEach { - if (!it.exists()) { - it.writeText("changeit") - } - } - } -} dependencies { implementation("io.ktor:ktor-server-core-jvm") diff --git a/doc/installation.md b/doc/installation.md index 0fced39..01eecca 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -1,12 +1,24 @@ Installation ============ -To run the stack: +To run the stack in production: ```shell docker compose -f docker\docker-compose-prod.yaml -p event-demo up -d ``` +To run only the app dependencies in development mode and run the app localy (not in docker): + +```shell +docker compose -f docker\docker-compose-dev.yaml up -d +``` + +To run the tests in docker (it's designed for the CI): + +```shell +docker compose -f docker\docker-compose-test.yaml up -d +``` + Api url: - [Backend API](http://api.traefik.me/) - [Frontend web site](http://app.traefik.me/) (WIP) diff --git a/docker/.env.docker b/docker/.env.docker new file mode 100644 index 0000000..d9a32c6 --- /dev/null +++ b/docker/.env.docker @@ -0,0 +1,3 @@ +REDIS_URL=redis://redis +POSTGRESQL_URL=jdbc:postgresql://postgresql/event-demo +RABBITMQ_URL=rabbitmq diff --git a/docker/.env.template b/docker/.env.template deleted file mode 100644 index f4e167b..0000000 --- a/docker/.env.template +++ /dev/null @@ -1 +0,0 @@ -PGADMIN_DEFAULT_EMAIL= \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index 0d6ed75..2eef580 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ # Stage 1: Cache Gradle dependencies -FROM gradle:latest AS cache +FROM gradle:9.6.1-jdk21-alpine AS cache RUN mkdir -p /home/gradle/cache_home ENV GRADLE_USER_HOME=/home/gradle/cache_home COPY build.gradle.* gradle.properties /home/gradle/app/ @@ -7,7 +7,7 @@ WORKDIR /home/gradle/app RUN gradle build -i -x check # Stage 2: Build Application -FROM gradle:latest AS build +FROM gradle:9.6.1-jdk21-alpine AS build COPY --from=cache /home/gradle/cache_home /home/gradle/.gradle COPY --chown=gradle:gradle . /home/gradle/src WORKDIR /home/gradle/src @@ -16,8 +16,8 @@ WORKDIR /home/gradle/src RUN gradle buildFatJar --no-daemon # Stage 3: Create the Runtime Image -FROM amazoncorretto:21 AS runtime +FROM eclipse-temurin:21-jre-alpine AS runtime EXPOSE 8080 RUN mkdir /app -COPY --from=build /home/gradle/src/build/libs/*.jar /app/event-demo-all.jar +COPY --from=build /home/gradle/src/build/libs/*-all.jar /app/event-demo-all.jar ENTRYPOINT ["java","-jar","/app/event-demo-all.jar"] \ No newline at end of file diff --git a/docker/DockerfileTest b/docker/DockerfileTest index 183ddcd..aae096a 100644 --- a/docker/DockerfileTest +++ b/docker/DockerfileTest @@ -1,8 +1,8 @@ # Image officielle Gradle avec JDK 21 déjà installé FROM gradle:9.6.1-jdk21 - + WORKDIR /app - + # Copie du wrapper et des fichiers de config en premier pour profiter du cache Docker COPY build.gradle.kts settings.gradle.kts ./ diff --git a/docker/docker-compose-ci.yaml b/docker/docker-compose-ci.yaml deleted file mode 100644 index 78ccfde..0000000 --- a/docker/docker-compose-ci.yaml +++ /dev/null @@ -1,5 +0,0 @@ -name: event-demo-ci -include: - - path: - - parts/docker-compose-databases.yaml - - parts/docker-compose-databases-expose.yaml \ No newline at end of file diff --git a/docker/docker-compose-dev.yaml b/docker/docker-compose-dev.yaml index 87b6cbf..6574721 100644 --- a/docker/docker-compose-dev.yaml +++ b/docker/docker-compose-dev.yaml @@ -1,8 +1,17 @@ -name: event-demo-test +name: event-demo-dev include: - path: - parts/docker-compose-databases.yaml - parts/docker-compose-databases-expose.yaml - parts/docker-compose-tools.yaml - parts/docker-compose-tools-local.yaml - - parts/docker-compose-traefik.yaml \ No newline at end of file + - parts/docker-compose-traefik.yaml + +services: + postgresql: + environment: + POSTGRES_PASSWORD: "changeit" + + pgadmin: + environment: + PGADMIN_DEFAULT_PASSWORD: "changeit" \ No newline at end of file diff --git a/docker/docker-compose-prod.yaml b/docker/docker-compose-prod.yaml index f5a1142..673849b 100644 --- a/docker/docker-compose-prod.yaml +++ b/docker/docker-compose-prod.yaml @@ -5,3 +5,16 @@ include: - parts/docker-compose-app.yaml - parts/docker-compose-tools.yaml - parts/docker-compose-traefik.yaml + +services: + postgresql: + environment: + POSTGRES_PASSWORD_FILE: /run/secrets/postgresql_password + volumes: + - ./postgresql.secret:/run/secrets/postgresql_password:ro + + pgadmin: + environment: + PGADMIN_DEFAULT_PASSWORD_FILE: /run/secrets/pgadmin_password + volumes: + - ./pgadmin.secret:/run/secrets/pgadmin_password:ro \ No newline at end of file diff --git a/docker/docker-compose-test.yaml b/docker/docker-compose-test.yaml index c338ab7..91205c9 100644 --- a/docker/docker-compose-test.yaml +++ b/docker/docker-compose-test.yaml @@ -3,4 +3,9 @@ include: - path: - parts/docker-compose-databases.yaml - parts/docker-compose-test.yaml - - parts/docker-compose-traefik.yaml \ No newline at end of file + - parts/docker-compose-traefik.yaml + +services: + postgresql: + environment: + POSTGRES_PASSWORD: "changeit" \ No newline at end of file diff --git a/docker/parts/docker-compose-app.yaml b/docker/parts/docker-compose-app.yaml index 6fe1537..59a1b91 100644 --- a/docker/parts/docker-compose-app.yaml +++ b/docker/parts/docker-compose-app.yaml @@ -12,6 +12,8 @@ services: condition: service_healthy redis: condition: service_healthy + env_file: + - ../.env.docker labels: - "traefik.http.routers.api.rule=Host(`api.traefik.me`)" - "traefik.http.services.api.loadbalancer.server.port=8080" diff --git a/docker/parts/docker-compose-databases.yaml b/docker/parts/docker-compose-databases.yaml index 8f1d81a..491d9bd 100644 --- a/docker/parts/docker-compose-databases.yaml +++ b/docker/parts/docker-compose-databases.yaml @@ -22,7 +22,6 @@ services: image: postgres:18.4 command: postgres -c 'max_connections=500' environment: - POSTGRES_PASSWORD_FILE: /run/secrets/postgresql_password POSTGRES_USER: event-demo healthcheck: test: ["CMD-SHELL", "sh -c 'pg_isready -U event-demo'"] @@ -31,7 +30,6 @@ services: retries: 10 volumes: - postgresql_data:/var/lib/postgresql - - ../postgresql.secret:/run/secrets/postgresql_password:ro rabbitmq: image: rabbitmq:4-management-alpine diff --git a/docker/parts/docker-compose-test.yaml b/docker/parts/docker-compose-test.yaml index 0e5d60b..d36f9f9 100644 --- a/docker/parts/docker-compose-test.yaml +++ b/docker/parts/docker-compose-test.yaml @@ -15,6 +15,8 @@ services: condition: service_healthy redis: condition: service_healthy + env_file: + - ../.env.docker volumes: gradle-cache: \ No newline at end of file diff --git a/docker/parts/docker-compose-tools.yaml b/docker/parts/docker-compose-tools.yaml index ee35d57..d5d9be0 100644 --- a/docker/parts/docker-compose-tools.yaml +++ b/docker/parts/docker-compose-tools.yaml @@ -2,10 +2,7 @@ services: pgadmin: image: dpage/pgadmin4 environment: - PGADMIN_DEFAULT_EMAIL: $PGADMIN_DEFAULT_EMAIL - PGADMIN_DEFAULT_PASSWORD_FILE: /run/secrets/pgadmin_password - secrets: - - pgadmin_password + PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-admin@event-demo.dev} volumes: - pgadmin_data:/var/lib/pgadmin configs: @@ -45,9 +42,5 @@ configs: } } -secrets: - pgadmin_password: - file: ../pgadmin.secret - volumes: pgadmin_data: \ No newline at end of file diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 0280eae..66a0f43 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -13,12 +13,12 @@ jwt { } redis { - url = "redis://redis:6379" + url = "redis://localhost:6379" url = ${?REDIS_URL} } postgresql { - url = "jdbc:postgresql://postgresql/event-demo" + url = "jdbc:postgresql://localhost:5432/event-demo" url = ${?POSTGRESQL_URL} username = "event-demo" @@ -29,7 +29,7 @@ postgresql { } rabbitmq { - url = "rabbitmq" + url = "localhost" url = ${?RABBITMQ_URL} port = "5672"