diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..7d6d3f012d5fd7c460b6eb9544e272a301dd3b44
--- /dev/null
+++ b/README.md
@@ -0,0 +1,237 @@
+# Installation d'un environnement de dev
+
+## Pré-requis
+
+- Python 3.9
+- Poetry (avec les modules poetry-plugin-export, poetry-dotenv-plugin, poetry-plugin-sort)
+- Docker
+
+## Créer un environnement virtuel avec Poetry
+
+Créer un environnement virtuel en python 3.9 : `poetry env use 3.9`
+
+Installer les dépendances : `poetry install`
+
+Installer les hooks de pre-commit : `poetry run pre-commit install`
+
+## Fichier `.env` à la racine du projet
+
+Créer un fichier `.env` avec les variables suivantes :
+
+```
+DJANGO_SETTINGS_MODULE=pount.settings.dev
+DEFAULT_DB_NAME=pount
+DEFAULT_DB_USER=pount
+DEFAULT_DB_PASSWORD=pount
+DEFAULT_DB_HOST=localhost
+DEFAULT_DB_PORT=5432
+SIGNING_KEY_PASSWORD=pount
+AWS_ACCESS_KEY_ID=ACCESSKEYID
+AWS_SECRET_ACCESS_KEY=***********************************
+AWS_STORAGE_BUCKET_NAME=pount-dev-3if
+RABBITMQ_SERVER='localhost:5672'
+RABBITMQ_VHOST='pount'
+RABBITMQ_USER='pount'
+RABBITMQ_PASSWORD='pount'
+MONGODB_USER=pount_dev
+MONGODB_PASSWORD=pount_dev
+MONGODB_HOST=localhost
+MONGODB_DATABASE=pount_dev
+```
+
+Seules les credentials S3 doivent être remplacés. Les autres variables sont les valeurs par défaut
+en environnement de dev.
+
+En environnement de dev, par habitude le nom du bucket S3 est `pount-dev-<pn>`
+où `pn` sont les initiales du dévéloppeur.
+
+## Configuration dans `pount/settings/dev.py`
+
+`CAS_SERVER_URL`: URL du serveur CAS
+
+Configurer un serveur SMTP ou utiliser un outil tel que maildev
+(`docker run -p 1080:1080 -p 1025:1025 maildev/maildev`)
+
+## Création des clés JWT
+
+```bash
+ssh-keygen -t rsa -b 4096 -m PEM -f keys/jwt.key  # (mettre un mot de passe vide)
+openssl rsa -in keys/jwt.key -pubout -outform PEM -out keys/jwt.key.pub
+```
+
+## Bases de données, cache, autres services
+
+Les services dockérisés sont définis dans `docker-compose.yml`
+
+### Rabbitmq
+
+Se connecter au serveur RabbitMQ (localhost:15672) avec le compte admin par défaut (`guest:guest`).
+
+Créer un compte `pount` avec le mot de passe `pount`. Créer un vhost `pount` et donner les droits
+à l'utilisateur `pount` sur le vhost.
+
+### MongoDB
+
+Créer une base de données `pount_dev` avec l'utilisateur `pount_dev`
+
+```bash
+mongosh "mongodb://locahost" -u pount -p pount
+
+# créer une base pount_dev
+use pount_dev
+
+# créer l'utilisateur pount_dev
+db.createUser({
+    user: "pount_dev",
+    pwd: "pount_dev",
+    roles: [
+        { role: "readWrite", db: "pount_dev" }
+    ]
+})
+
+# créer la collection referential_levels
+db.createCollection("referential_levels")
+
+# créer les index sur la collection
+db.referential_levels.setIndices([
+  {
+    v: 2,
+    key: { _id: 1 },
+    name: '_id_',
+    collation: {
+      locale: 'fr',
+      caseLevel: false,
+      caseFirst: 'off',
+      strength: 3,
+      numericOrdering: false,
+      alternate: 'non-ignorable',
+      maxVariable: 'punct',
+      normalization: false,
+      backwards: false,
+    }
+  },
+  {
+    v: 2,
+    key: { id: 1 },
+    name: 'id_1',
+    unique: true,
+    collation: {
+      locale: 'fr',
+      caseLevel: false,
+      caseFirst: 'off',
+      strength: 3,
+      numericOrdering: false,
+      alternate: 'non-ignorable',
+      maxVariable: 'punct',
+      normalization: false,
+      backwards: false,
+    }
+  },
+  {
+    v: 2,
+    key: { referential_id: 1, order: 1 },
+    name: 'referential_id_1_order_1',
+    collation: {
+      locale: 'fr',
+      caseLevel: false,
+      caseFirst: 'off',
+      strength: 3,
+      numericOrdering: false,
+      alternate: 'non-ignorable',
+      maxVariable: 'punct',
+      normalization: false,
+      backwards: false,
+    }
+  }
+])
+
+# créer la collection referential_nodes
+db.createCollection("referential_nodes")
+
+# créer les index sur la collection
+db.referential_nodes.setIndices([
+  {
+    v: 2,
+    key: { _id: 1 },
+    name: '_id_',
+    collation: {
+      locale: 'fr',
+      caseLevel: false,
+      caseFirst: 'off',
+      strength: 3,
+      numericOrdering: false,
+      alternate: 'non-ignorable',
+      maxVariable: 'punct',
+      normalization: false,
+      backwards: false,
+    }
+  },
+  {
+    v: 2,
+    key: { id: 1 },
+    name: 'id_1',
+    unique: true,
+    collation: {
+      locale: 'fr',
+      caseLevel: false,
+      caseFirst: 'off',
+      strength: 3,
+      numericOrdering: false,
+      alternate: 'non-ignorable',
+      maxVariable: 'punct',
+      normalization: false,
+      backwards: false,
+    }
+  },
+  {
+    v: 2,
+    key: { referential_id: 1, level_id: 1, ancestors: 1, order: 1 },
+    name: 'referential_id_1_level_id_1_ancestors_1_order_1',
+    collation: {
+      locale: 'fr',
+      caseLevel: false,
+      caseFirst: 'off',
+      strength: 3,
+      numericOrdering: false,
+      alternate: 'non-ignorable',
+      maxVariable: 'punct',
+      normalization: false,
+      backwards: false,
+    }
+  }
+])
+
+```
+
+## Indexation des items dans Elasticsearch
+
+Pour réinitialiser les index Elasticsearch : `poetry run python manage.py searchindex rebuild-indices`
+
+## Initialiser le projet
+
+`poetry run python manage.py makemigrations`
+
+Création des modèles nécessaires (roles, modèle de méta-données datacite) : `poetry run python manage.py create_models`
+
+Les comptes utilisateurs sont créés à la première connexion. Par contre, pour pouvoir créer un projet
+un utilisateur doit avoir explicitement ce droit. Il est donc nécessaire de créer un super-utilisateur (`manage.py createsuperuser`)
+qui pourra attribuer ce droit aux utilisateurs dans l'admin Django.
+
+Lors de la création des utilisateurs, les attributs suivants sont remontés du serveur CAS et utilisés
+pour la création : `username`, `first_name`, `last_name`, `email` et `affiliation`. Le serveur CAS est configuré pour
+remonter ces attributs lorsque le nom du service commence par `pount-`.
+
+## Lancement du serveur
+
+Serveur Django : `poetry run python manage.py runserver`
+
+Worker Celery : `poetry run python celery -A pount worker -l INFO`
+
+## Upload de fichiers sur S3
+
+L'ajout de fichiers se fait directement sur S3. Pour cela, le client demande une URL S3 pré-signée au backend (`/api/items/{id}/post_url/`) et
+télécharge le fichier via cette URL sans passer par Django. Il faut ensuite associer ce fichier à un item (`POST` sur `/api/items/{items_pk}/mediafiles/`.
+
+## Documentation de l'API
+
+[Swagger UI](http://localhost:8000/api/doc/)
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 461453e0c095550325db6d1b742a9650ddfd63fc..0000000000000000000000000000000000000000
--- a/README.rst
+++ /dev/null
@@ -1,106 +0,0 @@
-Setup a virtual environment
----------------------------
-
-.. code-block:: bash
-   virtualenv -p /usr/bin/python3.8 venv
-   source venv/bin/activate
-
-
-Install PostgreSQL
-------------------
-
-Install dependencies:
-.. code-block:: bash
-   sudo apt instal postgresql postgresql-server-dev-10
-
-Change to user 'postgres', login to postgresql prompt and (if necessary) set password:
-.. code-block:: bash
-   sudo -u postgres -i
-   psql
-   /password password
-Yeah, there's a space before CREATE DATABASE...
-
-Create database and chech it is created with:
-.. code-block:: bash
- CREATE DATABASE pount-db;
-   /l
-
-Alternative:
-.. code-block:: bash
-   psql
-    CREATE USER username;
-   /du
-   /q
-   psql pount-db
-    GRANT ALL PRIVILEGES ON DATABASE pount-db TO username;
-
-
-Elasticsearch
--------------
-
-Elasticsearch is used for indexing and searching.
-The `ICU plugin <https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-icu.html>`_ is used for
-extended Unicode support and must be installed.
-
-When models are updated, data must be reindexed in Elasticsearch. This process can possibly take time as many
-related objects may be involved. Therefore, it is advised that this reindexing process is performed
-asynchronously. Pount uses Celery and Rabbitmq for these asynchronous tasks.
-
-When running unittests, we don't want this reindexing taking place. Therefore we use a DummySignalProcessor class
-defined in :code:`pount.settings.unittest`:
-:code:`ELASTICSEARCH_DSL_SIGNAL_PROCESSOR = "pount.apps.api.signals.DummySignalProcessor"`
-
-For local development the :code:`docker-compose.yml` file provides services for:
- * Elasticsearch
- * Rabbitmq
- * Postgresql
-
-The following environment variables are expected for Rabbitmq:
-
-.. code-block:: bash
-  # $VIRTUAL_ENV/bin/postactivate
-  export RABBITMQ_SERVER='localhost:5672
-  export RABBITMQ_VHOST='pount'
-  export RABBITMQ_USER='pount'
-  export RABBITMQ_PASSWORD='pount'
-
-Start the Celery worker:
-
-.. code-block:: bash
-  celery -A pount worker -l INFO
-
-
-To reindex data in Elasticsearch
-
-.. code-block:: bash
-   python manage.py search_index --rebuild
-
-
-Create Django project
----------------------
-
-Create requirements file:
-.. literalinclude:: requirements.txt
-
-Install requirements.
-Please make sure your venv is activated first !
-.. code-block:: bash
-   pip install -r requirements.txt
-
-Create a Django project, and create an app in it:
-.. code-block:: bash
-  django-admin startproject elasticsearchproject
-  cd elasticsearchproject
-  python manage.py startapp elasticsearchapp
-
-Edit elasticsearchapp/models.py.
-Edit elasticsearchapp/admin.py.
-Edit settings.py to add 'elasticsearchapp' to INSTALLED_APPS.
-
-.. code-block:: bash
-   python manage.py makemigrations
-   python manage.py migrate
-   python manage.py createsuperuser
-   python manage.py runserver
-
-Create elasticsearchapp/search.py
diff --git a/tox.ini b/tox.ini
index c00c2226100f13690e78723e67dcf3c3e493fb5f..b5fb60109619a49dec6b5898cee8ac57da943911 100644
--- a/tox.ini
+++ b/tox.ini
@@ -14,6 +14,8 @@ passenv=
     DEFAULT_DB_PORT
     SIGNING_KEY_PASSWORD
     AWS_STORAGE_BUCKET_NAME
+    AWS_ACCESS_KEY_ID
+    AWS_SECRET_ACCESS_KEY
 deps=
     -rrequirements/dev.txt
 commands=