From 5ce129e38de419b0a02b067a9be0d8b8d27b2be0 Mon Sep 17 00:00:00 2001 From: Ciznia Date: Sun, 2 Nov 2025 17:17:08 +0100 Subject: [PATCH 1/5] build(mobile): add dockerfile that build the apk --- front/.gitignore | 1 + front/android/.gitignore | 1 + front/android/Dockerfile | 58 +++++++++++++++++++++++++++++++++ front/android/app/build.gradle | 14 +++++++- front/android/gradle.properties | 22 ------------- front/entrypoint.sh | 29 +++++++++++++++++ 6 files changed, 102 insertions(+), 23 deletions(-) create mode 100644 front/android/Dockerfile delete mode 100644 front/android/gradle.properties create mode 100644 front/entrypoint.sh diff --git a/front/.gitignore b/front/.gitignore index 65b27d6..f716dd0 100644 --- a/front/.gitignore +++ b/front/.gitignore @@ -6,3 +6,4 @@ node_modules dist dist-ssr *.local +*.jks diff --git a/front/android/.gitignore b/front/android/.gitignore index 4bf83a8..86c68a7 100644 --- a/front/android/.gitignore +++ b/front/android/.gitignore @@ -12,6 +12,7 @@ out/ .gradle/ build/ local.properties +gradle.properties *.log diff --git a/front/android/Dockerfile b/front/android/Dockerfile new file mode 100644 index 0000000..b2545b1 --- /dev/null +++ b/front/android/Dockerfile @@ -0,0 +1,58 @@ +FROM node:20-bookworm-slim + +# --- System Dependencies --- +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + bash curl unzip git ca-certificates && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# --- Install OpenJDK 21 (Temurin) --- +RUN curl -L https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9+10/OpenJDK21U-jdk_x64_linux_hotspot_21.0.9_10.tar.gz \ + -o /tmp/jdk21.tar.gz && \ + mkdir -p /usr/lib/jvm && \ + tar -xzf /tmp/jdk21.tar.gz -C /usr/lib/jvm && \ + rm /tmp/jdk21.tar.gz && \ + ln -s /usr/lib/jvm/jdk-21*/bin/java /usr/bin/java && \ + ln -s /usr/lib/jvm/jdk-21*/bin/javac /usr/bin/javac + +ENV JAVA_HOME=/usr/lib/jvm/jdk-21.0.9+10/ +ENV PATH="$JAVA_HOME/bin:$PATH" + + +# --- Install Android SDK --- +ENV ANDROID_SDK_ROOT="/sdk" \ + ANDROID_HOME="/sdk" \ + PATH="$PATH:/sdk/cmdline-tools/bin:/sdk/platform-tools" + +RUN mkdir /sdk && \ + curl -s https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -o /cmdline-tools.zip && \ + unzip /cmdline-tools.zip -d /sdk/ && \ + rm /cmdline-tools.zip && \ + mkdir -p /sdk/cmdline-tools/latest && \ + mv /sdk/cmdline-tools/* /sdk/cmdline-tools/latest/ || true && \ + yes | /sdk/cmdline-tools/latest/bin/sdkmanager --sdk_root=/sdk --install \ + "platform-tools" "platforms;android-35" "build-tools;35.0.0" "cmdline-tools;latest" + +# --- Install Gradle --- +RUN curl -sL https://services.gradle.org/distributions/gradle-8.10-bin.zip -o gradle.zip && \ + mkdir /opt/gradle && \ + unzip gradle.zip -d /opt/gradle && \ + rm gradle.zip +ENV PATH="/opt/gradle/gradle-8.10/bin:$PATH" + +# --- Install pnpm --- +RUN npm install -g pnpm + +# --- Web Build --- +WORKDIR /build +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile + +COPY . . +RUN pnpm run build:web +RUN npx cap sync android + +# --- Prepare Android Build --- +RUN chmod +x /build/entrypoint.sh + +CMD ["bash", "entrypoint.sh"] diff --git a/front/android/app/build.gradle b/front/android/app/build.gradle index 55c89ad..c66e170 100644 --- a/front/android/app/build.gradle +++ b/front/android/app/build.gradle @@ -3,6 +3,7 @@ apply plugin: 'com.android.application' android { namespace "io.github.sigmapitech" compileSdk rootProject.ext.compileSdkVersion + defaultConfig { applicationId "io.github.sigmapitech" minSdkVersion rootProject.ext.minSdkVersion @@ -13,15 +14,26 @@ android { ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~' } } + + signingConfigs { + release { + storeFile file(RELEASE_STORE_FILE) + storePassword RELEASE_STORE_PASSWORD + keyAlias RELEASE_KEY_ALIAS + keyPassword RELEASE_KEY_PASSWORD + } + } + buildTypes { release { minifyEnabled false + signingConfig signingConfigs.release } } } repositories { - flatDir{ + flatDir { dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' } } diff --git a/front/android/gradle.properties b/front/android/gradle.properties deleted file mode 100644 index 2e87c52..0000000 --- a/front/android/gradle.properties +++ /dev/null @@ -1,22 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true - -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true diff --git a/front/entrypoint.sh b/front/entrypoint.sh new file mode 100644 index 0000000..6946ce7 --- /dev/null +++ b/front/entrypoint.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Output dir +OUTPUT_DIR=/app +APK_NAME=client.apk + +# Ensure output folder exist +mkdir -p $OUTPUT_DIR +npx cap sync android +cd android +# Clean previous build +./gradlew clean + +# Sync dependencies +./gradlew build --no-daemon --refresh-dependencies + +# Build project for release +./gradlew assembleRelease + +# Copy apk to output dir +cp /build/android/app/build/outputs/apk/release/app-release.apk $OUTPUT_DIR/$APK_NAME + +# Ensure build success +if [ -f "$OUTPUT_DIR/$APK_NAME" ]; then + echo "APK successfully generated : $OUTPUT_DIR/$APK_NAME" +else + echo "APK generation failed." + exit 1 +fi From ea836fbe57b4367b79e227daedd13302b70a0bf5 Mon Sep 17 00:00:00 2001 From: Ciznia Date: Sun, 2 Nov 2025 18:30:27 +0100 Subject: [PATCH 2/5] build(nix): readd a nix builder for the front --- flake.nix | 1 + front/default.nix | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 front/default.nix diff --git a/flake.nix b/flake.nix index 73e00ea..c31047b 100644 --- a/flake.nix +++ b/flake.nix @@ -141,6 +141,7 @@ packages = forAllSystems (pkgs: { back = pkgs.callPackage ./back {}; + front = pkgs.callPackage ./front {}; }); }; } diff --git a/front/default.nix b/front/default.nix new file mode 100644 index 0000000..91da451 --- /dev/null +++ b/front/default.nix @@ -0,0 +1,62 @@ +{ + lib, + stdenvNoCC, + nodejs, + pnpm, + serve, + mode ? "web", +}: +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "area-front"; + version = "0.0.0"; + + src = ./.; + + nativeBuildInputs = [ + nodejs + pnpm.configHook + ]; + + pnpmDeps = pnpm.fetchDeps { + inherit (finalAttrs) pname src; + + fetcherVersion = 2; + hash = "sha256-FSQA/Li1XsqQwwosbItC42e1OjCN0soe4Yhn3Od7frA="; + }; + + # using sass-embedded fails at executing dart-sass from node-modules + preBuild = '' + rm -rf node_modules/{.pnpm/,}sass-embedded* + ''; + + buildPhase = '' + runHook preBuild + + pnpm run build:${mode} + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/area-front + cp -r dist/* $out/share/area-front/ + + mkdir -p $out/bin + cat > $out/bin/web <<'EOF' + #!${stdenvNoCC.shell} + exec ${lib.getExe serve} "$out/share/area-front" -p 8081 + EOF + chmod +x $out/bin/web + + runHook postInstall + ''; + + meta = { + description = "Area front-end"; + maintainers = with lib.maintainers; [sigmanificient]; + license = lib.licenses.bsd3; + mainProgram = "web"; + }; +}) From 976a96bd2f78db00f97ef776c36b52757d33a911 Mon Sep 17 00:00:00 2001 From: Ciznia Date: Tue, 4 Nov 2025 13:16:27 +0100 Subject: [PATCH 3/5] fix(docker): fix mobile/back docker WIP --- back/Dockerfile | 3 ++- back/app/main.py | 2 +- docker-compose.yml | 37 +++++++++++++++++++++---------------- front/default.nix | 2 +- front/entrypoint.sh | 2 +- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/back/Dockerfile b/back/Dockerfile index 6f40538..a469405 100644 --- a/back/Dockerfile +++ b/back/Dockerfile @@ -21,10 +21,11 @@ FROM scratch # Copy /nix/store and the built result COPY --from=builder /tmp/nix-store-closure /nix/store COPY --from=builder /tmp/build/result /app +COPY --from=builder /tmp/build/back/config.toml /app/config.toml # Expose server port and run ENV PORT=8080 WORKDIR /app EXPOSE 8080 # Pass "dev" to enable the CORS branch in app.main -CMD ["/app/bin/area", "dev"] +CMD ["/app/bin/area", "run"] diff --git a/back/app/main.py b/back/app/main.py index 17bb1a1..2577a06 100644 --- a/back/app/main.py +++ b/back/app/main.py @@ -33,4 +33,4 @@ async def lifespan(_: FastAPI): def main(): - uvicorn.run(app, host="127.0.0.1", port=8080) + uvicorn.run(app, host="0.0.0.0", port=8080) diff --git a/docker-compose.yml b/docker-compose.yml index b5edab1..dd374f0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,17 @@ services: + client_mobile: + build: + context: front + dockerfile: ./android/Dockerfile + volumes: + - shared-artifacts:/shared + # Optional: wait for a short while on first run to produce the APK + healthcheck: + test: ["CMD", "test", "-f", "/shared/client.apk"] + interval: 10s + timeout: 5s + retries: 30 + server: build: context: . @@ -6,33 +19,25 @@ services: ports: - "8080:8080" working_dir: /app - volumes: - - ./back/config.toml:/app/config.toml:ro - - # client_mobile: - # build: - # context: . - # dockerfile: front/android/Dockerfile - # volumes: - # - shared-artifacts:/shared - # # Optional: wait for a short while on first run to produce the APK - # healthcheck: - # test: ["CMD", "test", "-f", "/shared/client.apk"] - # interval: 10s - # timeout: 5s - # retries: 30 client_web: build: context: . dockerfile: front/Dockerfile depends_on: - server: condition: service_started + client_mobile: + condition: service_completed_successfully + networks: + - backToFront ports: - "8081:8081" volumes: - ./shared-artifacts:/app/share/www +volumes: + shared-artifacts: +networks: + backToFront: diff --git a/front/default.nix b/front/default.nix index 91da451..507b5c6 100644 --- a/front/default.nix +++ b/front/default.nix @@ -21,7 +21,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { inherit (finalAttrs) pname src; fetcherVersion = 2; - hash = "sha256-FSQA/Li1XsqQwwosbItC42e1OjCN0soe4Yhn3Od7frA="; + hash = "sha256-igUdfQtmFH8arU+dpLRBziJZ75108yq0kN5Jqf/Nuew="; }; # using sass-embedded fails at executing dart-sass from node-modules diff --git a/front/entrypoint.sh b/front/entrypoint.sh index 6946ce7..1043c49 100644 --- a/front/entrypoint.sh +++ b/front/entrypoint.sh @@ -1,7 +1,7 @@ #!/bin/bash # Output dir -OUTPUT_DIR=/app +OUTPUT_DIR=/shared APK_NAME=client.apk # Ensure output folder exist From 2f9879641bfe8223b843d4b3ae240eeb7de1e0a3 Mon Sep 17 00:00:00 2001 From: Ciznia Date: Tue, 4 Nov 2025 20:15:25 +0100 Subject: [PATCH 4/5] fix(docker): fix the dockerfile for the front and serve the apk at the good endpoint --- docker-compose.yml | 10 +++++--- flake.nix | 1 - front/Dockerfile | 48 +++++++++++++++++++---------------- front/default.nix | 62 ---------------------------------------------- front/nginx.conf | 19 ++++++++++++++ 5 files changed, 52 insertions(+), 88 deletions(-) delete mode 100644 front/default.nix create mode 100644 front/nginx.conf diff --git a/docker-compose.yml b/docker-compose.yml index dd374f0..4abe949 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,14 +16,16 @@ services: build: context: . dockerfile: back/Dockerfile + networks: + - backToFront ports: - "8080:8080" working_dir: /app client_web: build: - context: . - dockerfile: front/Dockerfile + context: front + dockerfile: ./Dockerfile depends_on: server: condition: service_started @@ -32,9 +34,9 @@ services: networks: - backToFront ports: - - "8081:8081" + - "8081:80" volumes: - - ./shared-artifacts:/app/share/www + - shared-artifacts:/shared/:ro volumes: shared-artifacts: diff --git a/flake.nix b/flake.nix index c31047b..73e00ea 100644 --- a/flake.nix +++ b/flake.nix @@ -141,7 +141,6 @@ packages = forAllSystems (pkgs: { back = pkgs.callPackage ./back {}; - front = pkgs.callPackage ./front {}; }); }; } diff --git a/front/Dockerfile b/front/Dockerfile index 0a8e887..ebcf49e 100644 --- a/front/Dockerfile +++ b/front/Dockerfile @@ -1,27 +1,33 @@ -# Nix builder -FROM nixos/nix:latest AS builder +FROM node:22-bookworm-slim AS build -# Copy our source and setup our working dir. -COPY .. /tmp/build -WORKDIR /tmp/build +ENV DEBIAN_FRONTEND=noninteractive -# Build our Nix environment (front-web helper) -RUN nix \ - --extra-experimental-features "nix-command flakes" \ - --option filter-syscalls false \ - build .#front +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl \ + ca-certificates && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* -# Copy the Nix store closure into a directory. -RUN mkdir /tmp/nix-store-closure -RUN cp -R $(nix-store -qR result/) /tmp/nix-store-closure +RUN corepack enable && corepack prepare pnpm@latest --activate -# Final image is based on scratch. -FROM scratch +RUN npm install -g serve -# Copy /nix/store and the built result -COPY --from=builder /tmp/nix-store-closure /nix/store -COPY --from=builder /tmp/build/result /app +WORKDIR /app -# Expose client_web port and run -EXPOSE 8081 -CMD ["/app/bin/web"] +COPY package.json pnpm-lock.yaml ./ + +ENV CI=true +RUN pnpm install --frozen-lockfile + +COPY . . + +RUN pnpm build:web + +FROM nginx:alpine +COPY --from=build /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# Expose to 80 and remap it in compose since nginx defaults to 80 without parameters possible +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/front/default.nix b/front/default.nix deleted file mode 100644 index 507b5c6..0000000 --- a/front/default.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ - lib, - stdenvNoCC, - nodejs, - pnpm, - serve, - mode ? "web", -}: -stdenvNoCC.mkDerivation (finalAttrs: { - pname = "area-front"; - version = "0.0.0"; - - src = ./.; - - nativeBuildInputs = [ - nodejs - pnpm.configHook - ]; - - pnpmDeps = pnpm.fetchDeps { - inherit (finalAttrs) pname src; - - fetcherVersion = 2; - hash = "sha256-igUdfQtmFH8arU+dpLRBziJZ75108yq0kN5Jqf/Nuew="; - }; - - # using sass-embedded fails at executing dart-sass from node-modules - preBuild = '' - rm -rf node_modules/{.pnpm/,}sass-embedded* - ''; - - buildPhase = '' - runHook preBuild - - pnpm run build:${mode} - - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - - mkdir -p $out/share/area-front - cp -r dist/* $out/share/area-front/ - - mkdir -p $out/bin - cat > $out/bin/web <<'EOF' - #!${stdenvNoCC.shell} - exec ${lib.getExe serve} "$out/share/area-front" -p 8081 - EOF - chmod +x $out/bin/web - - runHook postInstall - ''; - - meta = { - description = "Area front-end"; - maintainers = with lib.maintainers; [sigmanificient]; - license = lib.licenses.bsd3; - mainProgram = "web"; - }; -}) diff --git a/front/nginx.conf b/front/nginx.conf new file mode 100644 index 0000000..a346006 --- /dev/null +++ b/front/nginx.conf @@ -0,0 +1,19 @@ +server { + listen 80; + + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri /index.html =404; + } + + location /client.apk { + alias /shared/client.apk; + } + + location /shared/ { + alias /shared/; + autoindex on; + } +} From 0a89fc806c7c0a3d8bb520cf1a4c95d83e60dd47 Mon Sep 17 00:00:00 2001 From: Sigmanificient Date: Tue, 4 Nov 2025 23:50:03 +0100 Subject: [PATCH 5/5] fix(front): setup api url properly --- front/nginx.conf | 5 +++++ front/src/api_url.ts | 4 +++- front/src/routes/login/index.tsx | 2 +- front/src/routes/register/index.tsx | 2 +- front/vite-env.d.ts | 8 ++++++++ 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/front/nginx.conf b/front/nginx.conf index a346006..00b072f 100644 --- a/front/nginx.conf +++ b/front/nginx.conf @@ -8,6 +8,11 @@ server { try_files $uri /index.html =404; } + location /api/ { + proxy_pass http://server:8080/; + proxy_set_header Host $host; + } + location /client.apk { alias /shared/client.apk; } diff --git a/front/src/api_url.ts b/front/src/api_url.ts index 51e40d0..95b0033 100644 --- a/front/src/api_url.ts +++ b/front/src/api_url.ts @@ -1 +1,3 @@ -export const API_BASE_URL = "http://127.0.0.1:8080"; +export const API_BASE_URL = import.meta.env.PROD + ? "http://localhost:8081/api" + : "http://localhost:8080"; diff --git a/front/src/routes/login/index.tsx b/front/src/routes/login/index.tsx index a23e584..f86c90e 100644 --- a/front/src/routes/login/index.tsx +++ b/front/src/routes/login/index.tsx @@ -57,7 +57,7 @@ export default function LoginPage() { const { email, password } = formData; handleFormSubmit({ - url: `${API_BASE_URL}/auth/login/`, + url: `${API_BASE_URL}/auth/login`, body: { email, password }, onSuccess: (data) => { login(data.token); diff --git a/front/src/routes/register/index.tsx b/front/src/routes/register/index.tsx index da79af6..321b53d 100644 --- a/front/src/routes/register/index.tsx +++ b/front/src/routes/register/index.tsx @@ -94,7 +94,7 @@ export default function RegisterPage() { } handleFormSubmit({ - url: `${API_BASE_URL}/auth/register/`, + url: `${API_BASE_URL}/auth/register`, body: { email, name, password }, onSuccess: (data) => { login(data.token); diff --git a/front/vite-env.d.ts b/front/vite-env.d.ts index c934b98..c555498 100644 --- a/front/vite-env.d.ts +++ b/front/vite-env.d.ts @@ -2,4 +2,12 @@ /// +interface ImportMetaEnv { + readonly PROD: boolean; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} + declare const __APP_PLATFORM__: "mobile" | "web";