Issue
# Use an official Rust runtime as a parent image
FROM rust:bookworm as builder
# Set the working directory in the image to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
FROM --platform=$BUILDPLATFORM ubuntu:22.04
RUN apt-get update && apt-get install -y libssl-dev openssl curl
# Set the environment variables
ENV DATABASE_URL postgres://postgres:secret@pg:5432/mydatabase
ENV REDIS_URL=redis://redis/
ENV S3_ENDPOINT=http://minio1:9000
ENV S3_ACCESS_KEY=minioadmin
ENV S3_SECRET_KEY=minioadmin
ENV S3_BUCKET_NAME=mybucket
# Set the working directory
WORKDIR /app
# Copy the wait script to the image
COPY ee/k8s/readiness-probe.sh /app/readiness-probe.sh
RUN chmod +x /app/readiness-probe.sh
COPY ./target/release/run_consumer /app/run_consumer
COPY ./target/release/assistants-api-communication /app/assistants-api-communication
# Copy the entrypoint script
COPY docker/entrypoint.sh /app/entrypoint.sh
# Make the entrypoint script executable
RUN chmod +x /app/entrypoint.sh
# Run the entrypoint script when the container launches
ENTRYPOINT ["/app/entrypoint.sh"]
entrypoint.sh
#!/bin/bash
# Run the consumer and server applications concurrently
run_consumer &
assistants-api-communication &
# Wait for all background processes to finish
wait
Commands I run on a Mac M2:
cargo build --release --bin run_consumer
cargo build --release --bin assistants-api-communication
docker build -t foo:latest -f docker/Dockerfile .
docker run --env-file .env -p 8080:8080 foo:latest
The entrypoint.sh crashes with:
cannot execute binary file: Exec format error
What I tried:
- add
--platform linux/arm64
orlinux/arm64/v8
- inspecting the image architecture (arm64)
- copying the executable to host and do
file
on it (arm64) - executing the executable on host - works
- trying different runtime images (rust:bookworm, ubuntu, etc.)
- using same build and runtime image
- running the docker image one of the with the executable in
--entrypoint
directly
Note: I don't build the exec in the image for a specific reason that I don't want to change yet.
Any help would be appreciated
Solution
The problem was that I was putting a arm
executable in a non arm
environment (container), I also managed to build inside the Docker container by using
cargo sqlx prepare --workspace
Putting the .sqlx
in the build and setting ENV SQLX_OFFLINE true
FROM rust:bookworm as builder
# Set the working directory in the image to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY assistants-api-communication /app/assistants-api-communication
COPY assistants-core /app/assistants-core
COPY assistants-extra /app/assistants-extra
COPY Cargo.toml /app/Cargo.toml
COPY .sqlx /app/.sqlx
ENV SQLX_OFFLINE true
RUN cargo build --release --bin run_consumer && \
cargo build --release --bin assistants-api-communication
# Start a new stage to create a lean final image
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y libssl-dev openssl curl
# Set the environment variables
ENV DATABASE_URL postgres://postgres:secret@postgres:5432/mydatabase
ENV REDIS_URL=redis://redis/
ENV S3_ENDPOINT=http://minio1:9000
ENV S3_ACCESS_KEY=minioadmin
ENV S3_SECRET_KEY=minioadmin
ENV S3_BUCKET_NAME=mybucket
# Set the working directory
WORKDIR /app
# Copy the wait script to the image
COPY ./ee/k8s/readiness-probe.sh /app/readiness-probe.sh
RUN chmod +x /app/readiness-probe.sh
# Copy the binary from the builder stage
COPY --from=builder /app/target/release/run_consumer /usr/local/bin/run_consumer
COPY --from=builder /app/target/release/assistants-api-communication /usr/local/bin/assistants-api-communication
# Copy the entrypoint script
COPY ./docker/entrypoint.sh /app/entrypoint.sh
# Make the entrypoint script executable
RUN chmod +x /app/entrypoint.sh
# Run the entrypoint script when the container launches
ENTRYPOINT ["/app/entrypoint.sh"]
Thanks! It's open source: https://github.com/stellar-amenities/assistants
Answered By - Louis Beaumont Answer Checked By - Timothy Miller (WPSolving Admin)