diff --git a/.gitignore b/.gitignore
index 27f16a33f27618aef0ce47b4f036b7f613d32391..8ace5268a8f0f565480fa8a19fb481f3c373d19f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,13 +11,11 @@
 # production
 /build
 
+# local environment
+/local.env
+
 # misc
 .DS_Store
-.env
-.env.local
-.env.development.local
-.env.test.local
-.env.production.local
 *.swp
 
 npm-debug.log*
diff --git a/README.md b/README.md
index 0888ee67ccc048dc2360193ee6c79c2e4c88c9d0..92e512f5bf8fd1c996d917f609f7c761325ca7f6 100644
--- a/README.md
+++ b/README.md
@@ -1,65 +1,123 @@
 # Stackspin Dashboard
 
-This repo hosts the Stackspin Dashboard frontend code.
-The backend code is located at
-<https://open.greenhost.net/stackspin/dashboard-backend>.
+This repo hosts the Stackspin Dashboard, both frontend and backend code.
+
+## Project structure
+
+### Frontend
+
+The frontend code lives in the `frontend` directory.
+
+### Backend
+
+The backend code lives in the `backend` directory. Apart from the dashboard
+backend itself, it also contains a flask application that functions as the
+identity provider, login, consent and logout endpoints for the OpenID Connect
+(OIDC) process.
+
+The application relies on the following components:
+
+ - **Hydra**: Hydra is an open source OIDC server.
+   It means applications can connect to Hydra to start a session with a user.
+   Hydra provides the application with the username
+   and other roles/claims for the application.
+   Hydra is developed by Ory and has security as one of their top priorities.
+
+ - **Kratos**: This is Identity Manager
+   and contains all the user profiles and secrets (passwords).
+   Kratos is designed to work mostly between UI (browser) and kratos directly,
+   over a public API endpoint.
+   Authentication, form-validation, etc. are all handled by Kratos.
+   Kratos only provides an API and not UI itself.
+   Kratos provides an admin API as well,
+   which is only used from the server-side flask app to create/delete users.
+
+ - **MariaDB**: The login application, as well as Hydra and Kratos, need to store data.
+   This is done in a MariaDB database server.
+   There is one instance with three databases.
+   As all databases are very small we do not foresee resource limitation problems.
+
+If Hydra hits a new session/user, it has to know if this user has access.
+To do so, the user has to login through a login application.
+This application is developed by the Stackspin team (Greenhost)
+and is part of this repository.
+It is a Python Flask application
+The application follows flows defined in Kratos,
+and as such a lot of the interaction is done in the web-browser,
+rather then server-side.
+As a result,
+the login application has a UI component which relies heavily on JavaScript.
+As this is a relatively small application,
+it is based on traditional Bootstrap + JQuery.
 
 ## Development environment
 
-### Setup
+After this process is finished, the following will run locally:
 
-Create a `.env` file in the project root directory:
+- the dashboard frontend
+- the dashboard backend
 
-    cp .env.example .env
+The following will be available locally through a proxy and port-forwards:
 
-and adjust the `REACT_APP_HYDRA_PUBLIC_URL` to the SSO URL of your cluster.
+- Hydra admin API
+- Kratos admin API and public API
+- The MariaDB database
 
-#### `yarn start`
+These need to be available locally, because Kratos wants to run on the same
+domain as the front-end that serves the login interface.
+
+### Setup
 
-Runs the app in the development mode.
-Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
+Please read through all subsections to set up your environment before
+attempting to run the dashboard locally.
 
-The page will reload if you make edits.
-You will also see any lint errors in the console.
+#### 1. Stackspin cluster
 
-#### `yarn test`
+To develop the Dashboard, you need a Stackspin cluster that is set up as a
+development environment. Follow the instructions [in the
+dashboard-dev-overrides
+repository](https://open.greenhost.net/stackspin/dashboard-dev-overrides#dashboard-dev-overrides)
+in order to set up a development-capable cluster. The end-points for the
+Dashboard, as well as Kratos and Hydra, will point to
+`http://stackspin_proxy:8081` in that cluster. As a result, you can run
+components using the `docker-compose.yml` file in this repository, and still log
+into Stackspin applications that run on the cluster.
 
-Launches the test runner in the interactive watch mode.
-See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests)
-for more information.
+#### 2. Environment for frontend
 
-#### `yarn build`
+The frontend needs to know where the backend API and hydra can be reached. To
+configure it, create a `local.env` file in the project root directory:
+
+    cp local.env.example local.env
+
+and adjust the `REACT_APP_HYDRA_PUBLIC_URL` to the SSO URL of your cluster.
 
-Builds the app for production to the `build` folder.
-It correctly bundles React in production mode and optimizes the build
-for the best performance.
+#### 3. Setup hosts file
 
-The build is minified and the filenames include the hashes.
-Your app is ready to be deployed!
+The application will run on `http://stackspin_proxy`. Add the following line to
+`/etc/hosts` to be able to access that from your browser:
 
-See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment)
-for more information.
+```
+127.0.0.1	stackspin_proxy
+```
 
-#### `yarn eject`
+#### 4. Kubernetes access
 
-**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
+The script needs you to have access to the Kubernetes cluster that runs
+Stackspin. Point the `KUBECONFIG` environment variable to a kubectl config. Attention points:
 
-If you aren’t satisfied with the build tool and configuration choices,
-you can `eject` at any time. This command will remove the single build dependency
-from your project.
+* that kubeconfig will be mounted inside docker containers, so also make sure
+  your Docker user can read it.
+* The bind-mount done by docker might not work if the file pointed to is
+  part of a filesystem such as sshfs. In that case, copy the file to a local
+  drive first.
 
-Instead, it will copy all the configuration files and the transitive dependencies
-(webpack, Babel, ESLint, etc) right into your project so you have full control
-over them.
-All of the commands except `eject` will still work, but they will point to the
-copied scripts so you can tweak them. At this point you’re on your own.
+### Build and run
 
-You don’t have to ever use `eject`. The curated feature set is suitable for
-small and middle deployments, and you shouldn’t feel obligated
-to use this feature.
-However we understand that this tool wouldn’t be useful
-if you couldn’t customize it when you are ready for it.
+After you've finished all setup steps, you can now run everything using
 
-## Learn More
+    ./run_app.sh
 
-You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
+This will sets a few environment variables based on what is in your cluster
+secrets, and run `docker compose up` to build and run all necessary components,
+including a reverse proxy as well as the backend flask application.
diff --git a/backend/README.md b/backend/README.md
deleted file mode 100644
index 6c1a6fe898c476a4791c88a0de5d3c7c00f49492..0000000000000000000000000000000000000000
--- a/backend/README.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Stackspin dashboard backend
-
-Backend for the [Stackspin dashboard](https://open.greenhost.net/stackspin/dashboard)
-
-## Login application
-
-Apart from the dashboard backend this repository contains a flask application
-that functions as the identity provider, login, consent and logout endpoints
-for the OpenID Connect (OIDC) process.
-The application relies on the following components:
-
- - **Hydra**: Hydra is an open source OIDC server.
-   It means applications can connect to Hydra to start a session with a user.
-   Hydra provides the application with the username
-   and other roles/claims for the application.
-   Hydra is developed by Ory and has security as one of their top priorities.
-
- - **Kratos**: This is Identity Manager
-   and contains all the user profiles and secrets (passwords).
-   Kratos is designed to work mostly between UI (browser) and kratos directly,
-   over a public API endpoint.
-   Authentication, form-validation, etc. are all handled by Kratos.
-   Kratos only provides an API and not UI itself.
-   Kratos provides an admin API as well,
-   which is only used from the server-side flask app to create/delete users.
-
- - **MariaDB**: The login application, as well as Hydra and Kratos, need to store data.
-   This is done in a MariaDB database server.
-   There is one instance with three databases.
-   As all databases are very small we do not foresee resource limitation problems.
-
-If Hydra hits a new session/user, it has to know if this user has access.
-To do so, the user has to login through a login application.
-This application is developed by the Stackspin team (Greenhost)
-and is part of this repository.
-It is a Python Flask application
-The application follows flows defined in Kratos,
-and as such a lot of the interaction is done in the web-browser,
-rather then server-side.
-As a result,
-the login application has a UI component which relies heavily on JavaScript.
-As this is a relatively small application,
-it is based on traditional Bootstrap + JQuery.
-
-# Development
-
-To develop the Dashboard,
-you need a Stackspin cluster that is set up as a development environment.
-Follow the instructions [in the dashboard-dev-overrides
-repository](https://open.greenhost.net/stackspin/dashboard-dev-overrides#dashboard-dev-overrides)
-in order to set up a development-capable cluster.
-The end-points for the Dashboard,
-as well as Kratos and Hydra, will point to `http://stackspin_proxy:8081` in that cluster.
-As a result, you can run components using the `docker-compose` file in
-this repository, and still log into Stackspin applications that run on the cluster.
-
-
-## Setting up the local development environment
-
-After this process is finished, the following will run locally:
-
-- The [dashboard](https://open.greenhost.net/stackspin/dashboard)
-- The
-  [dashboard-backend](https://open.greenhost.net/stackspin/dashboard-backend)
-
-The following will be available locally through a proxy and port-forwards:
-
-- Hydra admin
-- Kratos admin and public
-- The MariaDB database connections
-
-These need to be available locally, because Kratos wants to run on the same
-domain as the front-end that serves the login interface.
-
-
-### 1. Setup hosts file
-
-The application will run on `http://stackspin_proxy`. Add the following line to
-`/etc/hosts` to be able to access that from your browser:
-
-```
-127.0.0.1	stackspin_proxy
-```
-
-### 2. Kubernetes access
-
-The script needs you to have access to the Kubernetes cluster that runs
-Stackspin. Point the `KUBECONFIG` environment variable to a kubectl config. That
-kubeconfig will be mounted inside docker containers, so also make sure your
-Docker user can read it.
-
-### 3. Run it all
-
-Now, run this script that sets a few environment variables based on what is in
-your cluster secrets, and starts `docker-compose` to start a reverse proxy as
-well as the flask application in this repository.
-
-```
-./run_app.sh
-```
-
-### 4. Front-end developmenet
-
-Start the [dashboard front-end app](https://open.greenhost.net/stackspin/dashboard/#yarn-start).