diff --git a/.github/workflows/development_workflow.yml b/.github/workflows/development_workflow.yml index e40f9875..37cae534 100644 --- a/.github/workflows/development_workflow.yml +++ b/.github/workflows/development_workflow.yml @@ -77,11 +77,17 @@ jobs: - name: Build run: gradle clean installDist -x test - - name: Start valkey - run: docker run -d --name valkey -p 6379:6379 valkey/valkey:8.1-alpine - - name: Start services run: docker compose up -d --build --wait + - name: Show logs on failure + if: failure() + run: | + echo "=== CONTAINER STATUS ===" + docker compose ps -a + echo "=== CONTAINER LOGS ===" + docker compose logs + - name: Stop services + if: always() run: docker compose down \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index db9794a7..cba89ded 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,11 @@ FROM amazoncorretto:${JAVA_VERSION} AS java FROM node:25-bookworm-slim ARG PLAYWRIGHT_VERSION -RUN npx -y playwright@${PLAYWRIGHT_VERSION} install --with-deps firefox +ENV PLAYWRIGHT_BROWSERS_PATH=/opt/playwright +RUN mkdir -p ${PLAYWRIGHT_BROWSERS_PATH} && \ + npx -y playwright@${PLAYWRIGHT_VERSION} install --with-deps firefox && \ + rm -rf ~/.npm + ARG JAVA_VERSION COPY --from=java /usr/lib/jvm/java-${JAVA_VERSION}-amazon-corretto /usr/lib/jvm/java-${JAVA_VERSION}-amazon-corretto @@ -13,18 +17,23 @@ ENV LANG=C.UTF-8 \ JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-amazon-corretto \ TZ=Europe/Paris \ DEBIAN_FRONTEND=noninteractive \ - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 \ + PLAYWRIGHT_BROWSERS_PATH=/opt/playwright # Install necessary packages and set timezone RUN apt-get update && \ - apt-get install -y --no-install-recommends ca-certificates curl fonts-dejavu tzdata webp && \ + apt-get install -y --no-install-recommends ca-certificates curl fonts-dejavu tzdata webp gosu && \ rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* && \ ln -snf /usr/share/zoneinfo/"$TZ" /etc/localtime && \ echo "$TZ" > /etc/timezone && \ - dpkg-reconfigure --frontend noninteractive tzdata + dpkg-reconfigure --frontend noninteractive tzdata && \ + groupadd -r -g 1001 appuser && useradd -r -u 1001 -g appuser -m -d /home/appuser appuser && \ + chown -R appuser:appuser ${PLAYWRIGHT_BROWSERS_PATH} -COPY build/install/core hibernate.cfg.xml /app/ +COPY --chown=appuser:appuser build/install/core hibernate.cfg.xml /app/ +COPY --chmod=755 entrypoint.sh /usr/local/bin/entrypoint.sh WORKDIR /app EXPOSE 37100 +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["./bin/core", "--enable-jobs"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 502ac256..a5949b0d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,4 +43,5 @@ services: test: curl --fail http://localhost:37100/ || exit 1 interval: 30s timeout: 10s - retries: 5 \ No newline at end of file + retries: 5 + start_period: 20s \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 00000000..be37050a --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -e + +# Applique les droits à TOUT le dossier courant (/app) de manière récursive. +# Cela inclut donc 'data', 'dumps' et tout autre volume monté dans ce dossier. +chown -R appuser:appuser . 2>/dev/null || true + +# Lance la commande en tant que 'appuser' +exec gosu appuser "$@" \ No newline at end of file diff --git a/src/main/kotlin/fr/shikkanime/utils/Constant.kt b/src/main/kotlin/fr/shikkanime/utils/Constant.kt index b4315e4b..ebbdf881 100644 --- a/src/main/kotlin/fr/shikkanime/utils/Constant.kt +++ b/src/main/kotlin/fr/shikkanime/utils/Constant.kt @@ -12,6 +12,8 @@ import java.time.ZonedDateTime import kotlin.io.path.createTempDirectory object Constant { + private val logger = LoggerFactory.getLogger(this::class.java) + const val NAME = "Shikkanime" const val PORT = 37100 @@ -26,25 +28,25 @@ object Constant { val dataFolder: File get() { val folder = if (isTest) tmpDirectory else File("data") - if (!folder.exists()) folder.mkdirs() + if (!folder.exists()) folder.mkdirs().ifFalse { logger.warning("Failed to created folder '${folder.name}'") } return folder } val configFolder: File get() { val folder = File(dataFolder, "config") - if (!folder.exists()) folder.mkdirs() + if (!folder.exists()) folder.mkdirs().ifFalse { logger.warning("Failed to created folder '${folder.name}'") } return folder } val imagesFolder: File get() { val folder = File(dataFolder, "images") - if (!folder.exists()) folder.mkdirs() + if (!folder.exists()) folder.mkdirs().ifFalse { logger.warning("Failed to created folder '${folder.name}'") } return folder } val exportsFolder: File get() { val folder = File(dataFolder, "exports") - if (!folder.exists()) folder.mkdirs() + if (!folder.exists()) folder.mkdirs().ifFalse { logger.warning("Failed to created folder '${folder.name}'") } return folder } diff --git a/src/main/kotlin/fr/shikkanime/utils/Extensions.kt b/src/main/kotlin/fr/shikkanime/utils/Extensions.kt index 70e33599..c3d49e39 100644 --- a/src/main/kotlin/fr/shikkanime/utils/Extensions.kt +++ b/src/main/kotlin/fr/shikkanime/utils/Extensions.kt @@ -36,4 +36,6 @@ fun Array.toTreeSet(): TreeSet where T : Comparable = TreeSet(). fun Iterable.toTreeSet(comparator: Comparator): TreeSet = TreeSet(comparator).also { it.addAll(this) } fun Iterable.toTreeSet(): TreeSet where T : Comparable = TreeSet().also { it.addAll(this) } -fun ByteArray?.isNullOrEmpty(): Boolean = this == null || this.isEmpty() \ No newline at end of file +fun ByteArray?.isNullOrEmpty(): Boolean = this == null || this.isEmpty() + +fun Boolean.ifFalse(block: () -> Unit) = if (!this) block() else null \ No newline at end of file