diff --git a/README.md b/README.md index 7d8a26eff..d397cb502 100644 --- a/README.md +++ b/README.md @@ -16,24 +16,43 @@ Antenna uses [Docker](https://docs.docker.com/get-docker/) & [Docker Compose](ht 127.0.0.1 minio 127.0.0.1 django ``` +3) The following commands will build all services, run them in the background, and then stream the logs. + 1) Standard development: will use a pre-built version of the frontend that will not have hot-reloading enabled. However, it will make startup time faster when restarting the stack. + ```sh + # Start the whole compose stack + docker compose up -d -2) The following commands will build all services, run them in the background, and then stream the logs. + # To stream the logs + docker compose logs -f django celeryworker ui + # Ctrl+c to close the logs + + NOTE: If you see docker build errors such as `At least one invalid signature was encountered`, these could happen if docker runs out of space. Commands like `docker image prune -f` and `docker system prune` can be helpful to clean up space. + + ``` + To update the UI Docker container, use the following command to rebuild the frontend and load the new changes + (and remember to refresh your browser after!). + ```sh + docker compose stop ui && docker compose build ui && docker compose up ui -d + ``` + + 2) With Hot Reload UI**: Hot reload is enabled for frontend development, but the primary web interface will be slow to load at startup and later restarts. + ```sh + # Run docker compose with the override config + docker compose -f docker-compose.yml -f docker-compose-frontend-dev.override.yml up -d + ``` + _**Do note that this will create a `ui/node_modules` folder if one does not exist yet. This folder is created by the mounting of the `/ui` folder + in the [docker-compose-frontend-dev.override.yml](docker-compose-frontend-dev.override.yml), and is written by a `root` user. + It will need to be removed, or you will need to modify its access permissions with the `chown` command if you later want to work on the frontend using the [instructions here](#frontend)._ -```sh - docker compose up -d - docker compose logs -f django celeryworker ui - # Ctrl+c to close the logs -``` -NOTE: If you see docker build errors such as `At least one invalid signature was encountered`, these could happen if docker runs out of space. Commands like `docker image prune -f` and `docker system prune` can be helpful to clean up space. -3) Optionally, run additional ML processing services: `processing_services` defines ML backends which wrap detections in our FastAPI response schema. The `example` app demos how to add new pipelines, algorithms, and models. See the detailed instructions in `processing_services/README.md`. +4) Optionally, run additional ML processing services: `processing_services` defines ML backends which wrap detections in our FastAPI response schema. The `example` app demos how to add new pipelines, algorithms, and models. See the detailed instructions in `processing_services/README.md`. ``` docker compose -f processing_services/example/docker-compose.yml up -d # Once running, in Antenna register a new processing service called: http://ml_backend_example:2000 ``` -4) Access the platform with the following URLs: +5) Access the platform with the following URLs: - Primary web interface: http://localhost:4000 - API browser: http://localhost:8000/api/v2/ @@ -48,7 +67,7 @@ A default user will be created with the following credentials. Use these to log - Email: `antenna@insectai.org` - Password: `localadmin` -5) Stop all services with: +6) Stop all services with: $ docker compose down diff --git a/compose/local/ui/Dockerfile b/compose/local/ui/Dockerfile index f3493dd60..47b1287a2 100644 --- a/compose/local/ui/Dockerfile +++ b/compose/local/ui/Dockerfile @@ -4,14 +4,21 @@ FROM node:18 # Set the working directory in the container WORKDIR /app +COPY ./ /app + # Configure git to trust the /app directory +# Not necessary for default, but needed for frontend compose override to have proper +# build number RUN git config --global --add safe.directory /app # Don't try to open a browser ENV BROWSER=none +# Build the ui +RUN yarn install \ + && yarn build + # Expose the port the app runs on EXPOSE 4000 -# Check for changed app dependencies on every start -CMD ["sh", "-c", "yarn install && yarn start --debug --host 0.0.0.0 --port 4000"] +CMD ["sh", "-c", "yarn preview --debug --host 0.0.0.0 --port 4000"] diff --git a/docker-compose-frontend-dev.override.yml b/docker-compose-frontend-dev.override.yml new file mode 100644 index 000000000..defd03a72 --- /dev/null +++ b/docker-compose-frontend-dev.override.yml @@ -0,0 +1,8 @@ +# This docker compose configuration should only be used to override the development compose file, docker-compose.yml + +services: + ui: + volumes: + - ./.git:/app/.git:ro + - ./ui:/app + entrypoint: ["sh", "-c", "yarn install && yarn start --debug --host 0.0.0.0 --port 4000"] diff --git a/docker-compose.yml b/docker-compose.yml index e1588478d..5d6bfefae 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -56,31 +56,12 @@ services: dockerfile: ../compose/local/ui/Dockerfile ports: - "4000:4000" - volumes: - - ./.git:/app/.git:ro - - ./ui:/app - - node_modules:/app/node_modules depends_on: - django environment: - CHOKIDAR_USEPOLLING=true - API_PROXY_TARGET=http://django:8000 - docs: - image: ami_local_docs - build: - context: . - dockerfile: ./compose/local/docs/Dockerfile - env_file: - - ./.envs/.local/.django - volumes: - - ./docs:/docs:z - - ./config:/app/config:z - - ./ami:/app/ami:z - ports: - - "9025:9000" - command: /start-docs - redis: image: redis:6 container_name: ami_local_redis diff --git a/ui/.dockerignore b/ui/.dockerignore new file mode 100644 index 000000000..3e2e84b08 --- /dev/null +++ b/ui/.dockerignore @@ -0,0 +1,2 @@ +build/ +node_modules/ diff --git a/ui/vite.config.ts b/ui/vite.config.ts index d15cf415e..d65ecd750 100644 --- a/ui/vite.config.ts +++ b/ui/vite.config.ts @@ -5,9 +5,18 @@ import eslint from 'vite-plugin-eslint' import svgr from 'vite-plugin-svgr' import viteTsconfigPaths from 'vite-tsconfig-paths' -const commitHash = childProcess - .execSync('git rev-parse --short HEAD') - .toString() +let temporaryCommitHash: string +try { + temporaryCommitHash = childProcess + .execSync('git rev-parse --short HEAD') + .toString() +} catch (error) { + console.warn('Could not get git commit hash:', error) + temporaryCommitHash = '- Local docker image: please ensure this is the latest version -' +} + +const commitHash = temporaryCommitHash + export default defineConfig(({ mode }) => { // Load env file based on `mode` in the current working directory.