diff --git a/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst
deleted file mode 100644
index 9618c5f7d4285f366f05a5f8b2fd4cef43cf829b..0000000000000000000000000000000000000000
--- a/CODE_OF_CONDUCT.rst
+++ /dev/null
@@ -1,144 +0,0 @@
-Contributor Covenant Code of Conduct
-====================================
-
-Our Pledge
-----------
-
-We as members, contributors, and leaders pledge to make participation in
-our community a harassment-free experience for everyone, regardless of
-age, body size, visible or invisible disability, ethnicity, sex
-characteristics, gender identity and expression, level of experience,
-education, socio-economic status, nationality, personal appearance,
-race, religion, or sexual identity and orientation.
-
-We pledge to act and interact in ways that contribute to an open,
-welcoming, diverse, inclusive, and healthy community.
-
-Our Standards
--------------
-
-Examples of behavior that contributes to a positive environment for our
-community include:
-
--  Demonstrating empathy and kindness toward other people
--  Being respectful of differing opinions, viewpoints, and experiences
--  Giving and gracefully accepting constructive feedback
--  Accepting responsibility and apologizing to those affected by our
-   mistakes, and learning from the experience
--  Focusing on what is best not just for us as individuals, but for the
-   overall community
-
-Examples of unacceptable behavior include:
-
--  The use of sexualized language or imagery, and sexual attention or
-   advances of any kind
--  Trolling, insulting or derogatory comments, and personal or political
-   attacks
--  Public or private harassment
--  Publishing others’ private information, such as a physical or email
-   address, without their explicit permission
--  Other conduct which could reasonably be considered inappropriate in a
-   professional setting
-
-Enforcement Responsibilities
-----------------------------
-
-Community leaders are responsible for clarifying and enforcing our
-standards of acceptable behavior and will take appropriate and fair
-corrective action in response to any behavior that they deem
-inappropriate, threatening, offensive, or harmful.
-
-Community leaders have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other
-contributions that are not aligned to this Code of Conduct, and will
-communicate reasons for moderation decisions when appropriate.
-
-Scope
------
-
-This Code of Conduct applies within all community spaces, and also
-applies when an individual is officially representing the community in
-public spaces. Examples of representing our community include using an
-official e-mail address, posting via an official social media account,
-or acting as an appointed representative at an online or offline event.
-
-Enforcement
------------
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may
-be reported to the community leaders responsible for enforcement at
-foss@teckids.org. All complaints will be reviewed and investigated
-promptly and fairly.
-
-All community leaders are obligated to respect the privacy and security
-of the reporter of any incident.
-
-Enforcement Guidelines
-----------------------
-
-Community leaders will follow these Community Impact Guidelines in
-determining the consequences for any action they deem in violation of
-this Code of Conduct:
-
-1. Correction
-~~~~~~~~~~~~~
-
-**Community Impact**: Use of inappropriate language or other behavior
-deemed unprofessional or unwelcome in the community.
-
-**Consequence**: A private, written warning from community leaders,
-providing clarity around the nature of the violation and an explanation
-of why the behavior was inappropriate. A public apology may be
-requested.
-
-2. Warning
-~~~~~~~~~~
-
-**Community Impact**: A violation through a single incident or series of
-actions.
-
-**Consequence**: A warning with consequences for continued behavior. No
-interaction with the people involved, including unsolicited interaction
-with those enforcing the Code of Conduct, for a specified period of
-time. This includes avoiding interactions in community spaces as well as
-external channels like social media. Violating these terms may lead to a
-temporary or permanent ban.
-
-3. Temporary Ban
-~~~~~~~~~~~~~~~~
-
-**Community Impact**: A serious violation of community standards,
-including sustained inappropriate behavior.
-
-**Consequence**: A temporary ban from any sort of interaction or public
-communication with the community for a specified period of time. No
-public or private interaction with the people involved, including
-unsolicited interaction with those enforcing the Code of Conduct, is
-allowed during this period. Violating these terms may lead to a
-permanent ban.
-
-4. Permanent Ban
-~~~~~~~~~~~~~~~~
-
-**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior, harassment of an
-individual, or aggression toward or disparagement of classes of
-individuals.
-
-**Consequence**: A permanent ban from any sort of public interaction
-within the project community.
-
-Attribution
------------
-
-This Code of Conduct is adapted from the `Contributor
-Covenant <https://www.contributor-covenant.org>`__, version 2.0,
-available at
-https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
-
-Community Impact Guidelines were inspired by `Mozilla’s code of conduct
-enforcement ladder <https://github.com/mozilla/diversity>`__.
-
-For answers to common questions about this code of conduct, see the FAQ
-at https://www.contributor-covenant.org/faq. Translations are available
-at https://www.contributor-covenant.org/translations.
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
deleted file mode 100644
index be12afc1552dc2b6d6cb398bc2a456392ef21b9d..0000000000000000000000000000000000000000
--- a/CONTRIBUTING.rst
+++ /dev/null
@@ -1,232 +0,0 @@
-Development principles and contribution guidelines
-==================================================
-
-In order to create a high-quality software product, the AlekSIS developers
-have agreed upon fundamental principles governing the code layout, coding
-style and repository management for AlekSIS and all official apps.
-
-
-Coding layout and style
------------------------
-
-The coding style is defined in `PEP 8`_, with the following differences and
-decisions:
-
-- The defaults of the `black`_ code formatter are used
-  - This implies all string literals usin double-quotes, if it does not lead
-    to more escaping. As proposed by `black`: "My recommendation here is to
-    keep using whatever is faster to type and let Black handle the transformation."
-- The maximum line length is 100 characters
-- Imports are structured in five blocks, each of them sorted as defined in
-  PEP 8 and the Django style guide:
-
-  1. Standard library imports
-  2. Django imports
-  3. Third-party imports
-  4. Imports from AlekSIS core and other apps (absolute imports)
-  5. Imports from the same AlekSIS app (realtive imports)
-
-  Use `isort` to take care of this
-
-For the layout of source trees and style recommendations specific to Django,
-the `Django coding style`_ is a good source of information, together with
-the `Django Best Practices`_ collection.
-
-To ensure code is styled correctly, before commiting, run::
-
-  tox -e reformat
-
-Text documents
-~~~~~~~~~~~~~~
-
-If there is no objective reason against it, all text documents accompanying
-the source use `reStructuredText`_.
-
-
-Working with the Git repository
--------------------------------
-
-The Git repository shall be used as a historic documentation of development
-and as change management. It is important that the Git commit history
-describes what was changed, by whom and why.
-
-Help and information on Git for beginners are available in the `Git guide`_
-
-Feature and issue branches
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-All features and bug fixes should be developed in their own branch and later
-merged into the master branch as a whole. Of course, sometimes, it is
-sensible to not do that, e.g. for fixing mere typos and the like.
-
-Within the feature branch, every logical step should be commited separately.
-It is neither required nor desired to do micro-commits about every
-development step. The commit history should describe the trains of thought
-the design and implementation is based on.
-
-If you work on multiple issues at the same time, you have to change between
-branches. Never work on unrelated issues in the same branch.
-
-Branches should either contain the number and title of the related issue (as
-generated by GitLab), or follow the naming convention type/name, where type
-is one of bugfix, feature, or refactor.
-
-All changes on the code should be commited and pushed before stopping work on
-in order to prevent data loss. If a logical step is continued later, you
-should amend and force-push the commit.
-
-Issue branches should be rebased onto the current master regularly to avoid
-merge conflicts.
-
-Commit messages
-~~~~~~~~~~~~~~~
-
-Commit messages should be written as described in `How to Write a Git Commit
-Message`_.
-
-Commit messages should mention or even close any related issues. For merely
-mentioning progress on an issue, use the keyword `advances`; for closing an
-issue, use `closes`; for referring to a related issue for informational
-purposes, use `cf.`. This should be done in the body of the commit message.
-
-The subject of a commit message can (and should) be prepended with a tag in
-square brackets if it relates to a certain part of the repository, e.g. [CI]
-when changing CI/CD configuration or support code, [Dev] when changing
-something in the development utilities, etc.
-
-Example::
-
-  Solve LDAP connection problems
-
-  - Add the ldap-with-unicorn-dust dependency
-  - Configure settings.py to accept the correct groups from LDAP
-
-  Closes #10.
-
-Merge Requests
-~~~~~~~~~~~~~~
-
-If you think that the work on your feature branch is finished, you have to
-create a merge request on EduGit in order to let other developers and the
-maintainers take a look at it.
-
-See below on how to submit patches if you cannot use the development
-platform.
-
-Manifestos governing development
---------------------------------
-
-The FOSS community has created some manifestos describing several aspects of
-software development, to agree upon a baseline for these aspects. The
-AlekSIS developers have agreed to adhere to the following manifestos:
-
-- The `Sane software manifesto`_
-- The `Accessibility Manifesto`_
-- The `User Data Manifesto`_
-
-Not all theses from these manifestos are applicable. For example, most data
-about persons in a school information system are dictated by the school and
-probably governed by laws defining what and when to store. In that case,
-giving the user control over these decisions is not possible. Developers
-need to decide what should resonably be followed.
-
-The case on supporting non-free services
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Defined by the `Free Software Definition`_, it is an essential freedom to
-be allowed to use free software for any purpose, without limitation. Thus,
-interoperability with non-free services shall not be ruled out, and the
-AlekSIS project explicitly welcomes implementing support for
-interoperability with non-free services.
-
-However, to purposefully foster free software and services, if
-interoperability for a certain kind of non-free service is implemented, this
-must be done in a generalised manner (i.e.  using open protocols and
-interfaces).  For example, if implementing interoperability with some
-cloud-hosted calendar provider can be implemented either through a
-proprietary API, or through a standard iCalendar/Webcal interfaces, the
-latter is to be preferred.  Lacking such support, if a proprietary service
-is connected through a proprietary, single-purpose interface, measures shall
-be taken to also support alternative free services.
-
-
-Documentation
--------------
-
-The documentation in the AlekSIS project shall consist of three layers.
-
-Source code comments
-~~~~~~~~~~~~~~~~~~~~
-
-The parts of your code that are not self-explaining have to be commented.
-Ideally, source code is self-explaining, in the sense that its logical
-structure, naming of variables, and the like makes it easy to read and
-understand, for a reasonably talented programmer, to follow what it does.
-
-Docstrings
-~~~~~~~~~~
-
-All functions, methods, classes and modules that are newly added (or changed
-extensively) must contain a docstring for other developers to understand
-what it does. Docstrings of public elements will be included in the
-developer documentation.
-
-Sphinx documentation
-~~~~~~~~~~~~~~~~~~~~
-
-In addition to that you should document the function or the way the app
-works in the project documentation (`docs/` directory). Use that especially
-for functionality which is shared by your app for other apps (public APIs).
-
-Your Sphinx documentation should contain what the API can and shall be sued
-for, and how other apps can benefit from it.
-
-When creating a new app, also include documentation about it targeted at
-administrators and users.  At least you have to document what new developers
-and users have to do in order to get a working instance of the app.
-
-Sphinx documentation for all official apps will be published together.
-
-
-Contributing to upstream
-------------------------
-
-If possible and reasonable, code that can be of use to others in the general
-Django ecosystem shall be contributed to any upstream dependency, or a new
-generalised upstream dependency be created, under the most permissive
-licence possible.
-
-
-How to contact the team
------------------------
-
-Development platform
-~~~~~~~~~~~~~~~~~~~~
-
-Main development of AlekSIS is done on the `EduGit`_ platform in the
-`AlekSIS group`_ and discussions are held on the linked `Mattermost team`_.
-
-All platforms and tools mandated for development are free software and
-freely usable. EduGit accepts a variety of sources for login, so
-contributors are free to decide where they want to register in order to
-participate.
-
-If any contributor cannot use the platforms for whatever reasons, patches and
-questions directed at the developers can also be e-mailed to
-<aleksis-dev@lists.teckids.org>.
-
-
-.. _PEP 8: https://pep8.org/
-.. _Django coding style: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/
-.. _black: https://black.readthedocs.io/en/stable/
-.. _Django Best Practices: https://django-best-practices.readthedocs.io/en/latest/index.html
-.. _Git guide: https://rogerdudler.github.io/git-guide/
-.. _How to Write a Git Commit Message: https://chris.beams.io/posts/git-commit/
-.. _Sane software manifesto: https://sane-software.globalcode.info/
-.. _Accessibility Manifesto: http://accessibilitymanifesto.com/
-.. _User Data Manifesto: https://userdatamanifesto.org/
-.. _Free Software Definition: https://www.gnu.org/philosophy/free-sw.en.html
-.. _reStructuredText: http://docutils.sourceforge.net/rst.html
-.. _EduGit: https://edugit.org/
-.. _AlekSIS group: https://edugit.org/AlekSIS/
-.. _Mattermost team: https://mattermost.edugit.org/biscuit/
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 0c4f3b52ededb87de3ea36f7814d155aaa20026d..0000000000000000000000000000000000000000
--- a/Dockerfile
+++ /dev/null
@@ -1,97 +0,0 @@
-FROM python:3.8-buster AS core
-
-# Configure Python to be nice inside Docker and pip to stfu
-ENV PYTHONUNBUFFERED 1
-ENV PYTHONDONTWRITEBYTECODE 1
-ENV PIP_DEFAULT_TIMEOUT 100
-ENV PIP_DISABLE_PIP_VERSION_CHECK 1
-ENV PIP_NO_CACHE_DIR 1
-
-# Configure app settings for build and runtime
-ENV ALEKSIS_static__root /usr/share/aleksis/static
-ENV ALEKSIS_media__root /var/lib/aleksis/media
-ENV ALEKSIS_backup__location /var/lib/aleksis/backups
-
-# Install necessary Debian packages for build and runtime
-RUN apt-get -y update && \
-    apt-get -y install eatmydata && \
-    eatmydata apt-get -y upgrade && \
-    eatmydata apt-get install -y --no-install-recommends \
-        build-essential \
-	gettext \
-	libpq5 \
-	libpq-dev \
-	libssl-dev \
-	netcat-openbsd \
-	yarnpkg
-
-# Install core
-WORKDIR /usr/src/app
-COPY LICENCE.rst README.rst manage.py poetry.lock pyproject.toml ./
-COPY aleksis ./aleksis/
-RUN set -e; \
-    mkdir -p /var/lib/aleksis/media /usr/share/aleksis/static /var/lib/aleksis/backups; \
-    eatmydata pip install poetry; \
-    poetry config virtualenvs.create false; \
-    eatmydata poetry install; \
-    eatmydata pip install gunicorn django-compressor
-
-# Declare a persistent volume for all data
-VOLUME /var/lib/aleksis
-
-# Define entrypoint and gunicorn running on port 8000
-EXPOSE 8000
-COPY docker/entrypoint.sh /usr/local/bin/
-ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
-
-# Install core extras
-FROM core AS core-extras
-ARG EXTRA_LDAP=1
-ARG EXTRA_CELERY=1
-WORKDIR /usr/src/app
-
-# LDAP
-RUN   if [ $EXTRA_LDAP = 1 ] ; then \
-        eatmydata apt-get install -y --no-install-recommends \
-        libldap2-dev \
-        libsasl2-dev \
-        ldap-utils; \
-        eatmydata poetry install -E ldap; \
-        fi;
-
-# Celery
-RUN   if [ $EXTRA_CELERY = 1 ] ; then \
-        eatmydata poetry install -E celery; \
-        fi;
-
-# Install official apps
-FROM core-extras AS apps
-COPY apps ./apps/
-RUN set -e; \
-    for d in apps/official/*; do \
-        cd $d; \
-        rm -rf .git; \
-        poetry install; \
-        cd ../../..; \
-    done
-
-# Build messages and assets
-FROM apps as assets
-RUN eatmydata python manage.py compilemessages && \
-    eatmydata python manage.py yarn install && \
-    eatmydata python manage.py collectstatic --no-input --clear
-
-# Clean up build dependencies
-FROM assets AS clean
-RUN set -e; \
-    eatmydata apt-get remove --purge -y \
-        build-essential \
-        gettext \
-        libpq-dev \
-        libssl-dev \
-        yarnpkg; \
-    eatmydata apt-get autoremove --purge -y; \
-    apt-get clean -y; \
-    eatmydata pip uninstall -y poetry; \
-    rm -f /var/lib/apt/lists/*_*; \
-    rm -rf /root/.cache
diff --git a/ci/build_dist.yml b/ci/build_dist.yml
deleted file mode 100644
index b0c1bcc43f612d6f32760e73cbd91e8b214b9f73..0000000000000000000000000000000000000000
--- a/ci/build_dist.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-build_dist:
-  stage: build
-  script:
-    - if ! [ x$CI_COMMIT_REF_NAME = x$CI_COMMIT_TAG ]; then
-        poetry version $(poetry version | cut -d" " -f2)+$(date --date=${CI_COMMIT_TIMESTAMP} +%Y%m%d%H%M%S).${CI_COMMIT_SHORT_SHA} ;
-      fi
-    - tox -e build
-  artifacts:
-    paths:
-      - dist/
diff --git a/ci/build_docker.yml b/ci/build_docker.yml
deleted file mode 100644
index 92a1572c6ac4d1878110500f458262a6a7c5bdf4..0000000000000000000000000000000000000000
--- a/ci/build_docker.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-build_docker:
-  stage: build
-  image:
-    name: gcr.io/kaniko-project/executor:debug
-    entrypoint: [""]
-  script:
-    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" >/kaniko/.docker/config.json
-    - /kaniko/executor
-       --context $CI_PROJECT_DIR
-       --dockerfile $CI_PROJECT_DIR/Dockerfile
-       --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
-       --cache=true
-       --cleanup
-    - /kaniko/executor
-       --context $CI_PROJECT_DIR/docker/nginx
-       --dockerfile $CI_PROJECT_DIR/docker/nginx/Dockerfile
-       --destination $CI_REGISTRY_IMAGE/nginx:$CI_COMMIT_REF_NAME
-       --cache=true
-       --cleanup
-  only:
-    - master
-    - tags
diff --git a/ci/deploy.yml b/ci/deploy.yml
deleted file mode 100644
index 249e4c3333cf7c8800600a7801727110305a487e..0000000000000000000000000000000000000000
--- a/ci/deploy.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-deploy_demo-master:
-  stage: deploy
-  environment:
-    name: demo/master
-    url: http://demo-master.aleksis.org
-  before_script:
-    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
-    - eval $(ssh-agent -s)
-    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
-    - mkdir -p ~/.ssh
-    - chmod 700 ~/.ssh
-    - echo "$SSH_KNOWN_HOSTS" >~/.ssh/known_hosts
-    - chmod 644 ~/.ssh/known_hosts
-  script:
-    - grep -v "build:" docker-compose.yml | ssh root@demo-master.aleksis.org
-       env ALEKSIS_IMAGE_TAG=${CI_COMMIT_REF_NAME}
-       docker-compose
-        -p aleksis-${CI_ENVIRONMENT_SLUG}
-        -f /dev/stdin
-        pull
-    - grep -v "build:" docker-compose.yml | ssh root@demo-master.aleksis.org
-       env ALEKSIS_IMAGE_TAG=${CI_COMMIT_REF_NAME}
-           NGINX_HTTP_PORT=80
-           ALEKSIS_maintenance__debug=true
-       docker-compose
-        -p aleksis-${CI_ENVIRONMENT_SLUG}
-        -f /dev/stdin
-        up -d
-  only:
-    - master
diff --git a/ci/deploy_pypi.yml b/ci/deploy_pypi.yml
deleted file mode 100644
index 1d388e3564bdb57fd7b0e4fff2408c53fd919692..0000000000000000000000000000000000000000
--- a/ci/deploy_pypi.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-deploy_pypi:
-  stage: deploy
-  script:
-    - if [ $CI_COMMIT_REF_NAME = master ]; then
-       poetry version $(poetry version | cut -d" " -f2)+$(date --date=${CI_COMMIT_TIMESTAMP} +%Y%m%d%H%M%S).${CI_COMMIT_SHORT_SHA} ;
-      elif [ x$CI_COMMIT_REF_NAME = x$CI_COMMIT_TAG ]; then
-       if ! [ "$(poetry version | cut -d" " -f2)" = $CI_COMMIT_REF_NAME ]; then
-        echo "Package version does not match tag. Aborting build of tag!" >/dev/fd/2 ;
-        exit 1 ;
-       fi ;
-      fi
-    - if [ $CI_COMMIT_REF_NAME = master ]; then
-       poetry publish -r gitlab ;
-      elif [ x$CI_COMMIT_REF_NAME = x$CI_COMMIT_TAG ]; then
-       poetry publish ;
-      fi
-  only:
-    - master
-    - tags
diff --git a/ci/general.yml b/ci/general.yml
deleted file mode 100644
index 216fb757c7b984c5910c40c8a2395b7447fbac2f..0000000000000000000000000000000000000000
--- a/ci/general.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-image: registry.edugit.org/teckids/team-sysadmin/docker-images/python-pimped:latest
-
-stages:
-  - test
-  - build
-  - deploy
-
-variables:
-  GIT_SUBMODULE_STRATEGY: recursive
-  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
-  FF_NETWORK_PER_BUILD: "true"
-  POETRY_REPOSITORIES_GITLAB_URL: "$CI_API_V4_URL/projects/461/packages/pypi"
-  POETRY_HTTP_BASIC_GITLAB_USERNAME: aleksis
-  POETRY_HTTP_BASIC_GITLAB_PASSWORD: "$GITLAB_PUBLISH_TOKEN"
-  POETRY_PYPI_TOKEN_PYPI: "$GITLAB_PUBLISH_TOKEN"
-
-cache:
-  key:
-    files:
-      - poetry.lock
-      - pyproject.toml
-  paths:
-    - .cache/pip
-    - .tox
diff --git a/ci/pages.yml b/ci/pages.yml
deleted file mode 100644
index 31d8866e1d1c1b665d12ce15da9a7c918440aa7a..0000000000000000000000000000000000000000
--- a/ci/pages.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-pages:
-  stage: deploy
-  before_script:
-    - cp -r .tox/screenshots/firefox docs/screenshots
-  script:
-    - export LC_ALL=en_GB.utf8
-    - tox -e docs -- BUILDDIR=../public/docs
-  artifacts:
-    paths:
-    - public/
-  only:
-    - master
diff --git a/ci/test.yml b/ci/test.yml
deleted file mode 100644
index 2ab64bc324536c8716c5cb8641d09d9c43dbf844..0000000000000000000000000000000000000000
--- a/ci/test.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-test:
-  stage: test
-  services:
-    - name: selenium/standalone-firefox
-      alias: selenium
-  before_script:
-    - adduser --disabled-password --gecos "Test User" testuser
-    - chown -R testuser .
-  script:
-    - sudo apt update
-    - sudo apt install python3-ldap libldap2-dev libssl-dev libsasl2-dev python3.7-dev -y
-    - sudo -u testuser
-      env TEST_SELENIUM_HUB=http://selenium:4444/wd/hub
-          TEST_SELENIUM_BROWSERS=firefox
-          TEST_HOST=build
-      tox -e selenium -- --junitxml=.tox/junit.xml
-  artifacts:
-    paths:
-      - .tox/screenshots
-    reports:
-      junit: .tox/junit.xml
-
-lint:
-  stage: test
-  script:
-    - tox -e lint,security
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index 56d9d1edb57546360eaf73a18d2a95097b950288..0000000000000000000000000000000000000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,74 +0,0 @@
-version: '3'
-
-services:
-  db:
-    image: postgres:12
-    volumes:
-      - postgres_data:/var/lib/postgresql/data/
-    environment:
-      - POSTGRES_USER=aleksis
-      - POSTGRES_DB=aleksis
-  memcached:
-    image: memcached:latest
-  app:
-    build: .
-    image: registry.edugit.org/aleksis/official/aleksis:${ALEKSIS_IMAGE_TAG:-latest}
-    volumes:
-      - aleksis_data:/var/lib/aleksis/
-      - aleksis_static:/usr/share/aleksis/static/
-    environment:
-      - ALEKSIS_http__allowed_hosts="['*']"
-      - ALEKSIS_caching__memcached__address=memcached:11211
-      - ALEKSIS_caching__memcached__enabled=true
-      - ALEKSIS_database__host=db
-      - ALEKSIS_maintenance__debug=${ALEKSIS_maintenance__debug:-false}
-      - ALEKSIS_backup__location=/var/lib/aleksis/backups
-    depends_on:
-      - db
-      - memcached
-  worker:
-    build: .
-    image: registry.edugit.org/aleksis/official/aleksis:${ALEKSIS_IMAGE_TAG:-latest}
-    volumes:
-      - aleksis_data:/var/lib/aleksis/
-      - aleksis_static:/usr/share/aleksis/static/
-    command: celery_worker
-    environment:
-      - ALEKSIS_http__allowed_hosts="['*']"
-      - ALEKSIS_caching__memcached__address=memcached:11211
-      - ALEKSIS_caching__memcached__enabled=true
-      - ALEKSIS_database__host=db
-      - ALEKSIS_maintenance__debug=${ALEKSIS_maintenance__debug:-false}
-      - ALEKSIS_backup__location=/var/lib/aleksis/backups
-    depends_on:
-      - app
-  scheduler:
-    build: .
-    image: registry.edugit.org/aleksis/official/aleksis:${ALEKSIS_IMAGE_TAG:-latest}
-    volumes:
-      - aleksis_data:/var/lib/aleksis/
-      - aleksis_static:/usr/share/aleksis/static/
-    command: celery_beat
-    environment:
-      - ALEKSIS_http__allowed_hosts="['*']"
-      - ALEKSIS_caching__memcached__address=memcached:11211
-      - ALEKSIS_caching__memcached__enabled=true
-      - ALEKSIS_database__host=db
-      - ALEKSIS_maintenance__debug=${ALEKSIS_maintenance__debug:-false}
-    depends_on:
-      - worker
-  web:
-    build: ./docker/nginx
-    image: registry.edugit.org/aleksis/official/aleksis/nginx:${ALEKSIS_IMAGE_TAG:-latest}
-    volumes:
-      - aleksis_data:/var/lib/aleksis/
-      - aleksis_static:/usr/share/aleksis/static/:ro
-    ports:
-      - ${NGINX_HTTP_PORT:-8080}:80
-    depends_on:
-      - app
-
-volumes:
-  postgres_data:
-  aleksis_data:
-  aleksis_static:
diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh
deleted file mode 100755
index 4b68fa884420b1a40ed34d4bd4410aabd2ac1e3f..0000000000000000000000000000000000000000
--- a/docker/entrypoint.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-
-GUNICORN_BIND=${GUNICORN_BIND:-0.0.0.0:8000}
-
-export ALEKSIS_database__host=${ALEKSIS_database__host:-127.0.0.1}
-export ALEKSIS_database__port=${ALEKSIS_database__port:-5432}
-
-if [[ -z $ALEKSIS_secret_key ]]; then
-    if [[ ! -e /var/lib/aleksis/secret_key ]]; then
-	touch /var/lib/aleksis/secret_key; chmod 600 /var/lib/aleksis/secret_key
-	LC_ALL=C tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' </dev/urandom | head -c 64 >/var/lib/aleksis/secret_key
-    fi
-    ALEKSIS_secret_key=$(</var/lib/aleksis/secret_key)
-fi
-
-while ! nc -z $ALEKSIS_database__host $ALEKSIS_database__port; do
-    sleep 0.1
-done
-
-python manage.py compilescss
-python manage.py collectstatic --no-input --clear
-python manage.py migrate
-python manage.py createinitialrevisions
-
-ARG=${$1:-"gunicorn"}
-
-if [ $ARG = "celery_worker" ]; then
-    exec celery -A aleksis.core worker -l info
-elif [ $ARG = "celery_beat" ]; then
-    exec celery -A aleksis.core beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
-else
-    exec gunicorn aleksis.core.wsgi --bind ${GUNICORN_BIND}
-fi
diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile
deleted file mode 100644
index 18b91b5f17398ee5b2dc6e95bdedc225eb934821..0000000000000000000000000000000000000000
--- a/docker/nginx/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM nginx
-
-RUN rm /etc/nginx/conf.d/default.conf
-COPY nginx.conf /etc/nginx/conf.d/default.conf
-
-RUN mkdir /var/lib/aleksis
diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf
deleted file mode 100644
index 759f385041ce7bd7dc06b487ff2dfb2c43635482..0000000000000000000000000000000000000000
--- a/docker/nginx/nginx.conf
+++ /dev/null
@@ -1,23 +0,0 @@
-upstream aleksis {
-    server app:8000;
-}
-
-server {
-    listen 80;
-
-    location /media/ {
-        alias /var/lib/aleksis/media/;
-    }
-
-    location /static/ {
-        alias /usr/share/aleksis/static/;
-    }
-
-    location / {
-        proxy_pass http://aleksis;
-        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-        proxy_set_header Host $host;
-        proxy_redirect off;
-    }
-
-}