######################################## # Combined Single Container # Flutter (APK) + Spring Boot + MySQL ######################################## ######################################## # Global build arguments (must be re-declared # in every stage that needs them) ######################################## ARG GITEA_USER ARG GITEA_PASS ARG GITEA_URL=157.66.191.31:3000 ARG GITEA_ORG ARG REPO_NAME ARG GIT_BRANCH=main ARG JAR_NAME=app-1.0.0.jar # Subpath INSIDE the "*-b" folder where the pom.xml root lives # e.g. authsec_springboot/backend ARG BACKEND_SUBPATH # Subpath INSIDE the "*-f" folder where the flutter project # (pubspec.yaml) root lives # e.g. authsec_flutter_new/frontend/flutter_new ARG FRONTEND_SUBPATH # Final apk name copied into the image ARG APK_NAME=app-release.apk ######################################## # Stage 1 - Clone Repository + Auto-discover modules ######################################## FROM alpine/git:latest AS source ARG GITEA_USER ARG GITEA_PASS ARG GITEA_URL ARG GITEA_ORG ARG REPO_NAME ARG GIT_BRANCH WORKDIR /src RUN git clone --branch ${GIT_BRANCH} --single-branch \ http://${GITEA_USER}:${GITEA_PASS}@${GITEA_URL}/${GITEA_ORG}/${REPO_NAME}.git ######################################## # Auto-discover backend (*-b), frontend (*-f), and # db (*-d) top-level folders, regardless of the service ######################################## RUN set -e; \ BACKEND_DIR=$(find /src/${REPO_NAME} -maxdepth 1 -type d -name "*-b" | head -n1); \ FRONTEND_DIR=$(find /src/${REPO_NAME} -maxdepth 1 -type d -name "*-f" | head -n1); \ DB_DIR=$(find /src/${REPO_NAME} -maxdepth 1 -type d -name "*-d" | head -n1); \ if [ -z "$BACKEND_DIR" ]; then \ echo "ERROR: No backend module folder (ending in -b) found under /src/${REPO_NAME}"; \ ls -la /src/${REPO_NAME}; \ exit 1; \ fi; \ if [ -z "$FRONTEND_DIR" ]; then \ echo "ERROR: No frontend module folder (ending in -f) found under /src/${REPO_NAME}"; \ ls -la /src/${REPO_NAME}; \ exit 1; \ fi; \ if [ -z "$DB_DIR" ]; then \ echo "WARNING: No db module folder (ending in -d) found under /src/${REPO_NAME}"; \ fi; \ echo "Backend module found : $BACKEND_DIR"; \ echo "Frontend module found : $FRONTEND_DIR"; \ echo "DB module found : $DB_DIR"; \ ln -s "$BACKEND_DIR" /src/backend-module; \ ln -s "$FRONTEND_DIR" /src/frontend-module; \ if [ -n "$DB_DIR" ]; then ln -s "$DB_DIR" /src/db-module; fi ######################################## # Stage 2 - Backend Build ######################################## FROM maven:3.9.3-eclipse-temurin-8 AS backend-build ARG BACKEND_SUBPATH WORKDIR /workspace/backend COPY --from=source \ /src/backend-module/${BACKEND_SUBPATH}/ \ ./ RUN mvn clean package -DskipTests ######################################## # Stage 3 - Frontend Build (Flutter APK) ######################################## FROM ghcr.io/cirruslabs/flutter:3.27.3 AS frontend-build ARG FRONTEND_SUBPATH WORKDIR /workspace/frontend COPY --from=source \ /src/frontend-module/${FRONTEND_SUBPATH}/ \ ./ RUN flutter pub get # Optional project-specific cleanup script, skipped if absent RUN if [ -f ./remove_unused.sh ]; then \ chmod +x ./remove_unused.sh && ./remove_unused.sh; \ else \ echo "remove_unused.sh not found, skipping"; \ fi RUN flutter clean RUN flutter pub get RUN flutter build apk --target-platform android-arm64 ######################################## # Stage 4 - Runtime ######################################## FROM ubuntu:22.04 ARG REPO_NAME ARG JAR_NAME ARG APK_NAME ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y \ openjdk-17-jre \ mysql-server \ nginx \ supervisor \ curl \ wget \ git \ nano \ net-tools \ procps \ ca-certificates && \ rm -f /etc/nginx/conf.d/default.conf && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* ######################################## # Create Directories ######################################## RUN mkdir -p \ /opt/backend \ /opt/database \ /usr/share/nginx/html \ /var/log/supervisor ######################################## # Backend ######################################## COPY --from=backend-build \ /workspace/backend/target/${JAR_NAME} \ /opt/backend/app.jar ######################################## # SQL Files (optional - only copied if present in repo) ######################################## COPY --from=source \ /src/backend-module/${BACKEND_SUBPATH}/src/main/resources/schema.sql \ /opt/database/schema.sql COPY --from=source \ /src/backend-module/${BACKEND_SUBPATH}/src/main/resources/data.sql \ /opt/database/data.sql ######################################## # Frontend (APK served for download) ######################################## COPY --from=frontend-build \ /workspace/frontend/build/app/outputs/flutter-apk/app-release.apk \ /usr/share/nginx/html/${APK_NAME} ######################################## # Configuration Files ######################################## COPY --from=source \ /src/${REPO_NAME}/sureops/entrypoint.sh \ /usr/local/bin/entrypoint.sh COPY --from=source \ /src/${REPO_NAME}/sureops/init-db.sh \ /usr/local/bin/init-db.sh COPY --from=source \ /src/${REPO_NAME}/sureops/supervisord.conf \ /etc/supervisor/conf.d/supervisord.conf COPY --from=source \ /src/${REPO_NAME}/sureops/nginx.conf \ /etc/nginx/nginx.conf ######################################## # Permissions ######################################## RUN chmod +x /usr/local/bin/entrypoint.sh && \ chmod +x /usr/local/bin/init-db.sh ######################################## # Ports ######################################## EXPOSE 80 EXPOSE 9292 ######################################## # Start ######################################## ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]