Skip to content

Commit

Permalink
Docker image for armv7 architecture (#14)
Browse files Browse the repository at this point in the history
* test armv7

* test armv7 again

* testing old python version

* working on new docker containers

* trying to build finally

* testing installing after workdir

* pointed github action to the correct file for frontend

* working on conditional logic

* new image tag for armv7

* fixed backend dockerfile

* fixed backend dockerfile again

* changed docker compose

---------

Co-authored-by: Max McKelvey <maxmckelvey@Maxs-MBP.positronix.local>
Co-authored-by: Max McKelvey <maxmckelvey@Maxs-MacBook-Pro.local>
  • Loading branch information
3 people committed Aug 4, 2023
1 parent 2e1a629 commit 2c90ffe
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 11 deletions.
86 changes: 80 additions & 6 deletions .github/workflows/build_docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: Build Docker Images

on: [push, workflow_dispatch]

# old: linux/arm/v7, windows/amd64, mac/amd64, mac/arm64

jobs:
build-frontend:
name: Build Frontend Image
Expand Down Expand Up @@ -38,14 +36,52 @@ jobs:
- name: Build and Push Image
uses: docker/build-push-action@v3
with:
tags: docker.io/maxatgroundlight/groundlight-edge-client-frontend:latest
tags: docker.io/maxatgroundlight/detector-builder-frontend:latest
platforms: linux/amd64,linux/arm64
# platforms: linux/amd64,linux/arm64,linux/arm/v7
file: ./frontend.Dockerfile
push: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

build-frontend-armv7:
name: Build Frontend armv7 Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to container registry
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
registry: docker.io

# So now you can use Actions' own caching!
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build and Push Image
uses: docker/build-push-action@v3
with:
tags: docker.io/maxatgroundlight/detector-builder-frontend-armv7:latest
platforms: linux/arm/v7
file: ./frontend-armv7.Dockerfile
push: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

build-backend:
name: Build Backend Image
runs-on: ubuntu-latest
Expand Down Expand Up @@ -78,12 +114,50 @@ jobs:
- name: Build and Push Image
uses: docker/build-push-action@v3
with:
tags: docker.io/maxatgroundlight/groundlight-edge-client-backend:latest
tags: docker.io/maxatgroundlight/detector-builder-backend:latest
platforms: linux/amd64,linux/arm64
# platforms: linux/amd64,linux/arm64,linux/arm/v7
file: ./backend.Dockerfile
push: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

build-backend-armv7:
name: Build Backend armv7 Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to container registry
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
registry: docker.io

# So now you can use Actions' own caching!
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build and Push Image
uses: docker/build-push-action@v3
with:
tags: docker.io/maxatgroundlight/detector-builder-backend-armv7:latest
platforms: linux/arm/v7
file: ./backend-armv7.Dockerfile
push: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
# go here (https://evilmartians.com/chronicles/build-images-on-github-actions-with-docker-layer-caching)
# if cache is overflowing and is breaking
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,41 @@ The Detector Builder has a simple web interface (depected below) that allows you
```yaml
services:
frontend:
image: docker.io/maxatgroundlight/groundlight-edge-client-frontend:latest
image: docker.io/maxatgroundlight/detector-builder-frontend:latest
ports:
- "3000:3000"
depends_on:
- backend
backend:
image: docker.io/maxatgroundlight/groundlight-edge-client-backend:latest
image: docker.io/maxatgroundlight/detector-builder-backend:latest
ports:
- "8000:8000"
devices:
- /dev/video0:/dev/video0
- /dev/video1:/dev/video1
- /dev/video2:/dev/video2
- /dev/video3:/dev/video3
privileged: true
volumes:
- /dev/bus/usb:/dev/bus/usb
```

2. Run `docker-compose up` in the same directory as the `docker-compose.yml` file.

## Running from Docker on 32-bit ARM (armv7)

1. Create the file `docker-compose.yml` with the following contents:

```yaml
services:
frontend:
image: docker.io/maxatgroundlight/detector-builder-frontend-armv7:latest
ports:
- "3000:3000"
depends_on:
- backend
backend:
image: docker.io/maxatgroundlight/detector-builder-backend-armv7:latest
ports:
- "8000:8000"
devices:
Expand Down
1 change: 1 addition & 0 deletions api/gl_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def run_process(idx: int, logger, detector: dict, api_key: str, endpoint: str,
if "notifications" in detector["config"]:
try:
logger.error(f"Sending notifications for detector {detector['id']}...")
# logger.error(detector["config"]["notifications"])
send_notifications(detector["name"], detector["query"], query.result.label, detector["config"]["notifications"], frame, logger)
except Exception as e:
print(f"Error sending notifications: {e}")
Expand Down
26 changes: 26 additions & 0 deletions backend-armv7.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM python:3.9-slim-buster

WORKDIR /app

# COPY ./requirements.txt /app/requirements.txt
COPY ./pi_requirements.txt /app/requirements.txt

# RUN pip3 install opencv-python-headless==4.4.0.44
# RUN pip3 install --no-cache-dir --upgrade -r /app/requirements.txt
# RUN pip3 install opencv-python-headless=4.4.0.44

# RUN pip install --index-url=https://www.piwheels.org/simple --no-cache-dir opencv-python-headless
# RUN pip install --index-url=https://www.piwheels.org/simple --no-cache-dir fastapi==0.95.2
# RUN pip install --index-url=https://www.piwheels.org/simple --no-cache-dir uvicorn
# RUN pip install --index-url=https://www.piwheels.org/simple --no-cache-dir pyyaml
# RUN pip install --index-url=https://www.piwheels.org/simple --no-cache-dir pillow
RUN pip install --index-url=https://www.piwheels.org/simple --no-cache-dir -r /app/requirements.txt
RUN pip install --no-deps groundlight
RUN pip install --no-deps framegrab
RUN pip install pypylon

COPY ./api /app/api

EXPOSE 8000

CMD ["uvicorn", "api.index:app", "--host", "0.0.0.0", "--port", "8000"]
9 changes: 8 additions & 1 deletion backend.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
FROM python:3.11-slim-bookworm
FROM python:3.9-slim-bookworm
# FROM python:3.9-alpine

WORKDIR /app

COPY ./requirements.txt /app/requirements.txt
# COPY ./pi_requirements.txt /app/pi_requirements.txt

RUN pip3 install --no-cache-dir --upgrade -r /app/requirements.txt
RUN pip3 install opencv-python-headless

RUN pip install --index-url=https://www.piwheels.org/simple --no-cache-dir -r /app/requirements.txt
RUN pip install --no-deps groundlight
RUN pip install --no-deps framegrab
RUN pip install pypylon

COPY ./api /app/api

EXPOSE 8000
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
services:
frontend:
image: docker.io/maxatgroundlight/groundlight-edge-client-frontend:latest
image: docker.io/maxatgroundlight/detector-builder-frontend:latest
ports:
- "3000:3000"
depends_on:
- backend
backend:
image: docker.io/maxatgroundlight/groundlight-edge-client-backend:latest
image: docker.io/maxatgroundlight/detector-builder-backend:latest
ports:
- "8000:8000"
devices:
Expand Down
72 changes: 72 additions & 0 deletions frontend-armv7.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#syntax=docker/dockerfile:1.4
FROM node:18-buster-slim AS base

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
# RUN apk add --no-cache libc6-compat
# RUN apt install -y libc6-dev
WORKDIR /app

# Install Extra dependencies
RUN apt-get update || : && apt-get install python3 -y
RUN apt install sudo -y
RUN sudo apt update && sudo apt upgrade -y
RUN sudo apt install make
RUN sudo apt install build-essential -y
RUN sudo apt install libudev-dev

# Install dependencies based on the preferred package manager
COPY --link package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
# RUN npm i sharp@0.11.4
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps --link /app/node_modules ./node_modules
COPY --link . .

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN yarn build

# If using npm comment out above and use below instead
# RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN \
addgroup --system --gid 1001 nodejs; \
adduser --system --uid 1001 nextjs

COPY --from=builder --link /app/public ./public

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --link --chown=1001:1001 /app/.next/standalone ./
COPY --from=builder --link --chown=1001:1001 /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV HOSTNAME localhost

CMD ["node", "server.js"]
13 changes: 13 additions & 0 deletions pi_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fastapi==0.95.2
uvicorn[standard]

certifi>=2021.10.8
frozendict>=2.3.2
pillow>=9.0.0 # TODO: We may want to mark pillow (and numpy) as extra (https://python-poetry.org/docs/master/pyproject#extras)
pydantic>=1.7.4
python-dateutil>=2.8.2
requests>=2.28.2
urllib3>=1.26.9

opencv-python-headless>=4.4.0.44
pyyaml>=6.0.1

0 comments on commit 2c90ffe

Please sign in to comment.