https://github.com/borisboc/docker_image_annotations
Docker compose dedicated to image annotations and visualisation : to quickly deploy the needed tools to create datasets of images and annotate them.
https://github.com/borisboc/docker_image_annotations
annotation-tool annotations docker docker-compose fiftyone labeling-tool labelstudio mongodb segment-anything
Last synced: about 2 months ago
JSON representation
Docker compose dedicated to image annotations and visualisation : to quickly deploy the needed tools to create datasets of images and annotate them.
- Host: GitHub
- URL: https://github.com/borisboc/docker_image_annotations
- Owner: borisboc
- License: mit
- Created: 2024-12-09T17:29:30.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2026-02-12T13:55:05.000Z (4 months ago)
- Last Synced: 2026-02-12T22:37:43.740Z (4 months ago)
- Topics: annotation-tool, annotations, docker, docker-compose, fiftyone, labeling-tool, labelstudio, mongodb, segment-anything
- Language: Python
- Homepage:
- Size: 263 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Docker Image Annotations
This repository is meant to help you create Docker containers dedicated to image annotations.
Currently, this is based on :
* [fiftyone](https://docs.voxel51.com/index.html)
* [label-studio](https://labelstud.io/)
* [Segment Anything Model 2 (SAM2)](https://github.com/facebookresearch/sam2)
## Requirements & some important remarks
You must have [docker](https://docs.docker.com/get-started/) installed.
Please note that if you installed and use [docker desktop](https://docs.docker.com/get-started/get-docker/), it starts with a context called `desktop-linux`. In this context, you can have access to GPU only with sudo privilege.
If you don't want to run with privilege, you must run [docker in rootless mode](https://docs.docker.com/engine/security/rootless/). In this case, you can switch to rootless context by running
`docker context use rootless`
If you want the containers to have access to the NVIDIA GPUs please follow the instructions given in [docker : Access an NVIDIA GPU](https://docs.docker.com/engine/containers/resource_constraints/#gpu). Briefly, you will have to install NVIDIA driver and NVIDIA container toolkit. Once done, you should be able to successfully run the following command :
`docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi`
If you need sudo privilege for this command, please read the remark above (same paragraph).
If you run with rootless privilege, all the folders (volumes) that will be created with the containers (e.g. `fiftyone_data`, `label_studio_data` etc.) will NOT be owned by your current user. Which may be anoying for some usage. In this case, you may `chmod -R g+w` each folder.
## Installation
Start docker.
Clone this repository with the following command :
```
git clone https://github.com/borisboc/docker_image_annotations.git && cd docker_image_annotations
```
Copy the example file [.env.example](.env.example) into a `.env` file :
```shell
cp .env.example .env
```
Edit the copied file `.env`. At first, just change the values of the 2 environment variables :
```
MONGO_INITDB_ROOT_USERNAME=YourMongoDbUsernameHere
MONGO_INITDB_ROOT_PASSWORD=YourMongoDbPasswordHere
```
In order to set a proper user name and password for the MongoDB database (used by FiftyOne). Please do **NOT** use the `@` symbol (for both username and password).
Build and start the containers with the following command :
* If you have GPU access :
* `./start_gpu.sh --build`
* Otherwise, for CPU :
* `./start_cpu.sh --build`
If you use Windows, you can execute the shell scripts using GitBash.
Open your web browser and and go to URL : http://localhost:8080/.
Then log in [label-studio](https://labelstud.io/).
Sign-up / create an account (you have to create an account at first start if you started from empty label_studio_data volume).
Get your label-studio API KEY (acces token). Somewhere in 2025, Label Studio have changed their authorization / tokens methods. But FiftyOne still uses the old method.
So you first need to go to `Organization > API Tokens Settings` and activate `Legacy Tokens`.
Then go to your `account & settings` page, go to `Legacy Token` section and copy the `Access Token`, and paste it inside the file `.env`.
```
LABELSTUDIO_API_KEY="PLEASE PASTE YOUR LABEL STUDIO ACCESS TOKEN HERE, WITHIN THE DOUBLE QUOTES"
```
Stop the containers. Please refer to dedicated paragraph bellow.
Restart the containers (see docker compose command above) so that FiftyOne environment is updated.
## Usage : starting the docker compose
Please make sure that installation is done. See dedicated paragraph above.
Start docker.
Then choose one of the following method.
### Method 1: Traditional approach using shell scripts (.sh files)
For users who prefer the simple, straightforward approach, you can continue using the existing shell scripts:
Start the containers with the following command :
* If you have GPU access :
* `./start_gpu.sh`
* Otherwise, for CPU :
* `./start_cpu.sh`
You can pass extra arguments for docker, for instance : `./start_gpu.sh -d`, `./start_gpu.sh --build`, etc.
If you use Windows, you can execute the shell scripts using GitBash.
### Method 2: Modern approach using Python script (config_manager.py)
The `config_manager.py` script provides a more flexible approach to manage configurations. It allows you to combine different parameters without having to create a script file for each configuration.
**Basic usage:**
```bash
# CPU configuration
python config_manager.py --profile cpu
# GPU configuration
python config_manager.py --profile gpu
```
`cpu` will start all containers using CPU processor.
`gpu` will start all containers using GPU processor.
`--profile` (or simply `-p`) argument is a list : you can concatenate several profile to create your own custom network of containers.
For instance, if you just want to start FiftyOne and your mongodb server (where your FiftyOne datasets are stored) :
```bash
# Just starting fiftyone and mongodb in the compose, thanks to profiles
python config_manager.py --profile mongodb cpu-fiftyone
```
What to know which profiles are available, here is how to list :
```bash
# List available profiles in the compose file
python config_manager.py --list-profiles
```
And for all available arguments with default values :
```bash
# Print help including default values for arguments
python config_manager.py --help
```
**Advanced options:**
```bash
# Use a different compose file
python config_manager.py --compose-file compose_local_files.yaml --profile gpu
# Add custom environment variables
python config_manager.py --profile cpu --env-var "CUSTOM_MOUNT=/path/to/data"
# Pass additional arguments to docker compose (like --build)
python config_manager.py --profile cpu --extra-args --build
```
**Advantages of the Python method:**
- More flexible: Combine different parameters without creating new scripts
- Cross-platform: Works on Linux, Windows, and macOS
- Extensible: Easy to add new parameters
- Modular: Handles different compose files and profiles
## Stopping the containers
To stop the containers you can do this :
* CTRL+C in the terminal you upped the containers, since they are not started detached by default
* calling `docker compose -f compose_local_files.yaml -p img-ann --profile gpu down` (assuming you started with the `gpu` profile, please adapt to your profile)
* using Docker Desktop
* using VS Code extension [Container Tools](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-containers)
## Usage : how to use the different services
Please make sure that you have installed and started the containers and composition (see dedicated paragraphs above).
Create a subfolder inside folder `local_images/` with the name of your project. E.g. `local_images/myproject`. Place your images within this folder.
Open your web browser and and go to URL : http://localhost:5151/ to use the [FiftyOne App](https://docs.voxel51.com/user_guide/app.html).
If you don't have any dataset yet, you can create one by clicking on link on the webpage.
TODO : Screenshot when creating a dataset for the first time.
Then you can add samples by clicking on the link `click here` on the webpage.

Choose what you want to import. It depends on your data : if you have only media (i.e. the images) or you also have the annotations. For more details, you can refere to [FiftyOne import_samples operator](https://github.com/voxel51/fiftyone-plugins/blob/main/plugins/io/README.md#import_samples).

Then import either all the content of a directory (but not the subdirectories recursively). Or using a glob pattern.
In both cases, your images will be in the folder `/home/local_images` as there is a binding between the container and the folder on your host machine.
In the case you want to browse the folder with the FiftyOne Web App, see the screenshots bellow.
Access the root directory by clicking on the arrow up close to the text bar.

Then go to your directory containing your media. E.g., if your subfolder is named `myproject` (as proposed above), you will find it at the path `/home/local_images/myproject`
.
Then press execute.
From now you have a dataset created, and some samples. You can see the subparagraphs of this readme depending on what you want to do next.
You need more tips and tricks specific to FiftyOne ? Please look at the dedicated file : [TIPS_FIFTYONE](TIPS_FIFTYONE.md)
### Workflow for annotations
CAUTION : annotation name (also call `anno_key`) cannot start with numbers ! E.g. `20250724_ann_key` is **NOT** valid !
And then request for annotations with Label-Studio backend.
TODO : finish this paragraph and add screenshots.
You need more tips and tricks specific to FiftyOne ? Please look at the dedicated file : [TIPS_FIFTYONE](TIPS_FIFTYONE.md)
### Using Segment Anything Model 2 during annotations
During annotations on Label-Studio, if you need to annotate segmentation (e.g. semantic segmentation, or instance segmentation) you can use Segment Anything Model 2 ([SAM2](https://github.com/facebookresearch/sam2)) to generate you segmentations/masks from a provided seed on the image (which can be some keypoints, a brushed region, or a axis-aligend rectangle). The result of SAM2 will be `BrushLabel`.
You can find a [youtube video tutorial](https://youtu.be/FTg8P8z4RgY?feature=shared) from Label Studio, to show you how to use SAM2.
Concerning the configuration in the menu `Settings > Model`, in our case, please set the following Backend URL :
```
http://img-ann-sa2-label-studio:9090
```
And toggle ON the parameter `Interactive preannotations`.
For further details, please refer to [label-studio-ml-backend github : using sam2](https://github.com/HumanSignal/label-studio-ml-backend/tree/master/label_studio_ml/examples/segment_anything_2_image#using-sam2-with-label-studio-for-image-annotation)
Remark : for keypoints, add a "belong to" point with left click, and a "does not belong to" with ALT + left click.
For the labeling interface, you use SAM2 with keypoints or rectangle, you can base it on the example in [labeling_interface_sam2.xml](PythonUtils/labeling_interface_sam2.xml)
### Connect another instance of FiftyOne to the same database
Because the MongoDB database used by FiftyOne runs in its own container, and ports are bound, it is fine to connect another instance of FiftyOne to this database. The typical use case is that you develop a neural network on your host machine, or inside another container, and you want to access the samples in one of your FiftyOne dataset.
Do do so, in the session running your own FiftyOne instance, you can either modify the fiftyone configuration json file, or declare the environment variable `FIFTYONE_DATABASE_URI`, which is the preferred option explained bellow.
In your session, please export :
```
export FIFTYONE_DATABASE_URI=mongodb://YourMongoDbUsernameHere:YourMongoDbPasswordHere@127.0.0.1:27017
```
Please set the correct values for your mongodb username and password. They must match the content in file [fiftyone_image/fiftyone_secrets.env](fiftyone_image/fiftyone_secrets.env)
Once exported, you can run all your python codes with FiftyOne and access the FiftyOne datasets. E.g. :
``` python
import fiftyone as fo
ds = fo.load_dataset("NameOfYouDatasetHere")
```
A convenient way is to save this command with the correct connection details within a `.sh`file. And you can `source` this file.
If your FiftyOne session is within another container, please :
* place your container on the same docker network, i.e. `img-ann-net`. If you are on a different docker compose file, you have to declare this network as external. Here is the snippet :
```
networks:
img-ann-net:
name: img-ann-net
external: true
```
* use the mongodb container name. E.g. :
```
export FIFTYONE_DATABASE_URI=mongodb://YourMongoDbUsernameHere:YourMongoDbPasswordHere@img-ann-mongodb:27017
```
This is what is done in file [fiftyone_image/fiftyone.env](fiftyone_image/fiftyone.env)
For further details, please refere to [FiftyOne : configuring mongodb connection](https://docs.voxel51.com/user_guide/config.html#configuring-mongodb-connection).
You need more tips and tricks specific to FiftyOne ? Please look at the dedicated file : [TIPS_FIFTYONE](TIPS_FIFTYONE.md)
### Accessing a container, program with jupyter notebook
#### For label-studio container
To start a jupyter notebook server on the label-studio container, simply start a new terminal and run :
```
./jupyter_label_studio.sh
```
You will see the URL with the AUTH token printed in the console. Go to this URL on the web browser to work with jupyter notebook. For instance, you may want to use the scripts that are in `PythonUtils/` folder.
#### For fiftyone container
Same as for label-studio container, but instead you may run :
```
./jupyter_fiftyone.sh
```
#### For other containers
You can use Visual Studio Code remote connexion on a `Dev Container`. Or `Docker Desktop`.
Connect on the container you want to play with (let's say `img-ann-fiftyone` ).
Inside a container terminal, go to relevant folder. E.g. `/home/local_images/` , then type
```
jupyter notebook --ip 0.0.0.0 --no-browser --allow-root
```
Click on the link provided in the terminal output to start a notebook.
### Managing Fiftyone one plugins
Once the container started, you can fully call the `fiftyone plugins` CLI on the container, for instance :
```bash
docker exec -it img-ann-fiftyone fiftyone plugins list
```
## Sources
[label-studio on dockerhub](https://hub.docker.com/r/heartexlabs/label-studio)
[label-studio : persist data with Docker](https://labelstud.io/guide/storedata#Persist-data-with-Docker)
[label-studio tuto import yolo annotations](https://labelstud.io/blog/tutorial-importing-local-yolo-pre-annotated-images-to-label-studio/)
[label-studio local storage](https://labelstud.io/guide/storage.html#Set-up-connection-in-the-Label-Studio-UI-4)
[label-studio-ml-backend github : using sam2](https://github.com/HumanSignal/label-studio-ml-backend/tree/master/label_studio_ml/examples/segment_anything_2_image#using-sam2-with-label-studio-for-image-annotation)
[Access Jupyter notebook running on Docker container](https://stackoverflow.com/questions/38830610/access-jupyter-notebook-running-on-docker-container)
[FiftyOne on dockerhub](https://hub.docker.com/r/voxel51/fiftyone)
[FiftyOne : Loading data into FiftyOne](https://docs.voxel51.com/user_guide/dataset_creation/index.html#)
[FiftyOne : Using the FiftyOne App](https://docs.voxel51.com/user_guide/app.html)
[FiftyOne : configuring mongodb connection](https://docs.voxel51.com/user_guide/config.html#configuring-mongodb-connection)
[Docker and MongoDB](https://www.mongodb.com/resources/products/compatibilities/docker)
[docker : Access an NVIDIA GPU](https://docs.docker.com/engine/containers/resource_constraints/#gpu)
## TODOs
Screenshot when creating a dataset for the first time.
More documentation and more screenshots.