# Force Intel (amd64) architecture — required because Android SDK # command-line tools are only published for x86_64 (Linux/macOS). # On Apple Silicon hosts, Docker runs this image via Rosetta emulation. FROM --platform=linux/amd64 docker.io/library/debian:bookworm-slim # System dependencies + SSH server for intra-network access RUN apt-get update && apt-get install -y \ git curl unzip wget python3 python3-venv python3-pip \ openjdk-17-jdk-headless \ openssh-server \ xz-utils \ libcairo2 \ && rm -rf /var/lib/apt/lists/* # SSH server configuration RUN mkdir -p /run/sshd && \ ssh-keygen -A && \ chmod 644 /etc/ssh/ssh_host_*_key && \ sed -i 's/#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config && \ echo "UsePAM no" >> /etc/ssh/sshd_config && \ echo "PermitUserEnvironment yes" >> /etc/ssh/sshd_config # Set Java home — use /usr/lib/jvm/java-17-openjdk which is a stable # symlink provided by Debian's jdk package, regardless of architecture. ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 ENV PATH="$JAVA_HOME/bin:$PATH" # Install Flutter 3.41.8 ARG FLUTTER_VERSION=3.41.8 ARG FLUTTER_SDK_URL=https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz RUN wget -qO- $FLUTTER_SDK_URL | tar -xJ -C /opt \ && ln -s /opt/flutter/bin/flutter /usr/local/bin/flutter # Android SDK setup ENV ANDROID_HOME=/opt/android-sdk RUN mkdir -p $ANDROID_HOME/cmdline-tools # Download and install Android command-line tools RUN wget -qO /tmp/cmdline-tools.zip \ https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip \ && unzip -q /tmp/cmdline-tools.zip -d /tmp/cmdline-tools-extract \ && mv /tmp/cmdline-tools-extract/cmdline-tools $ANDROID_HOME/cmdline-tools/latest \ && rm -rf /tmp/cmdline-tools* # Accept licenses and install required SDK packages ENV CMDLINE_TOOLS=$ANDROID_HOME/cmdline-tools/latest/bin RUN yes | $CMDLINE_TOOLS/sdkmanager --licenses >/dev/null 2>&1 || true RUN $CMDLINE_TOOLS/sdkmanager "platform-tools" "platforms;android-35" "build-tools;35.0.0" # Create vscode user (UID 1000, matching devcontainer convention) RUN groupadd -g 1000 vscode && \ useradd -m -u 1000 -g 1000 -s /bin/bash vscode && \ chown -R vscode:vscode /opt/flutter /opt/android-sdk && \ mkdir -p /home/vscode && chown vscode:vscode /home/vscode # Give vscode a simple password: '123' RUN echo "vscode:123" | chpasswd # Set up Flutter for the vscode user USER vscode WORKDIR /home/vscode ENV PATH="/opt/flutter/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$JAVA_HOME/bin:$PATH" # Pre-cache Flutter artifacts RUN flutter precache --android # Set Android HOME for vscode user ENV ANDROID_HOME=/opt/android-sdk # SSH non-interactive shells don't inherit Docker ENV at all (not even # BASH_ENV). Use SSH's own ~/.ssh/environment file with # PermitUserEnvironment to guarantee variables are set on every connection. RUN mkdir -p /home/vscode/.ssh && \ echo 'JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' > /home/vscode/.ssh/environment && \ echo 'ANDROID_HOME=/opt/android-sdk' >> /home/vscode/.ssh/environment && \ echo 'PATH=/opt/flutter/bin:/opt/android-sdk/cmdline-tools/latest/bin:/opt/android-sdk/platform-tools:/usr/lib/jvm/java-17-openjdk-amd64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' >> /home/vscode/.ssh/environment && \ chown -R vscode:vscode /home/vscode/.ssh && \ chmod 700 /home/vscode/.ssh && \ chmod 644 /home/vscode/.ssh/environment # Set up Gradle home so the wrapper works correctly in SSH sessions. # org.gradle.daemon=false is required because SSH sessions are ephemeral # — a daemon started in one session can't be reused in the next. RUN mkdir -p /home/vscode/.gradle && \ echo 'org.gradle.daemon=false' > /home/vscode/.gradle/gradle.properties && \ echo 'org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+UseSerialGC' >> /home/vscode/.gradle/gradle.properties && \ echo 'org.gradle.workers.max=1' >> /home/vscode/.gradle/gradle.properties && \ echo 'org.gradle.parallel=false' >> /home/vscode/.gradle/gradle.properties && \ echo 'kotlin.daemon.jvmargs=-Xmx512m' >> /home/vscode/.gradle/gradle.properties && \ echo 'kotlin.incremental=false' >> /home/vscode/.gradle/gradle.properties && \ echo 'kotlin.compiler.execution.strategy=in-process' >> /home/vscode/.gradle/gradle.properties && \ echo 'android.enableParallelPlugin=false' >> /home/vscode/.gradle/gradle.properties && \ chown -R vscode:vscode /home/vscode/.gradle # Expose SSH for intra-network access from the api container EXPOSE 22 # Start SSH daemon and keep container alive CMD ["/usr/sbin/sshd", "-D"]