Commit 89603887 authored by Marek Veselý's avatar Marek Veselý
Browse files

Merge branch 'deduplicate-installation-with-docker-deployment' into 'dux'

Deduplicate installation with docker deployment

See merge request inject/inject-docs!118
parents 2fab3b36 89a9020a
Loading
Loading
Loading
Loading
+118 −16
Original line number Diff line number Diff line
For version 3.0.0 of IXP, download the compose preset folder for HTTPS deployment using Let's
Encrypt [here](https://gitlab.fi.muni.cz/inject/docker-deployment/-/package_files/229/download),
unzip it, set it as your working directory, and follow the instructions below.
<!-- Note: This file is primarily defined to be used in the IXP documentation. However, it is also provided in the docker-deployment repository for reference. If you accessed this file from the docker-deployment repository, please be aware that the links used in this file may not work as expected. -->

## HTTPS Deployment

For HTTPS deployment, you need to generate HTTPS certificates. In this configuration, the
certificates are generated via [Certbot](https://certbot.eff.org/) using Lets Encrypt.
<!-- TODO: update package file for Dux -->

This can be done via the `./cert_script.sh` script, which automatically generates the certificate in
the current directory. Invoke the script like so, substituting the placeholders for their respective
values:
For deployment of the IXP with SSL certificates generated via
[Certbot](https://certbot.eff.org/) by Let's Encrypt, download the latest
compose preset folder
[here](https://gitlab.fi.muni.cz/inject/docker-deployment/-/package_files/229/download).

After downloading the preset, unzip it, set the unzipped folder as your working
directory, and follow the instructions below.

### Certificate Generation

The certificates can be generated using the `cert_script.sh` script, which
automates the process. The script will:

1. generate or renew the SSL certificates for the specified domain
2. and reload the Nginx configuration to apply the new certificates (if
    running).

#### Usage

1. Ensure the script is executable:

    ```bash
./cert_script.sh <email-address> <domain>
    chmod +x ./cert_script.sh
    ```

After the certificate has been generated, an email will be sent to the provided address with
additional information about the certificate.
2. Invoke the script as follows, substituting the placeholders for their
    respective values:

The same script can be used to renew the certificates.
    ```bash
    ./cert_script.sh <email-address> <domain>
    ```

Example usage:
    Example:

    ```bash
    ./cert_script.sh admin@inject.fi.muni.cz inject.fi.muni.cz
    ```

Please note that by executing this script, you're agreeing to Certbot's TOS and Privacy Policy, and
your email will be used for essential communication about expiration notices.
#### Notes:

- By executing this script, you agree to Certbot's Terms of Service and Privacy
    Policy. Your email will be used for essential communication, such as
    expiration notices.

### (Optional) Automatic Certificate Renewal

To ensure that your certificates are renewed automatically before they expire,
you can set up a cron job to run the `cert_script.sh` script periodically.

#### Setting Up the Cron Job

1. Open the crontab editor:

    ```bash
    crontab -e
    ```

2. Add the following line to schedule the script to run on the 1st day of every
    month at midnight. Don't forget to substitute the placeholders for their
    respective values:

    ```bash
    0 0 1 * * cd <project-root> && ./cert_script.sh <email-address> <domain> >> ./cert_renewal.log 2>&1
    ```

    Example:

    ```bash
    0 0 1 * * cd /home/inject/https && ./cert_script.sh admin@inject.fi.muni.cz inject.fi.muni.cz >> ./cert_renewal.log 2>&1
    ```

    **If you want to be notified via email when the renewal process fails, you
    can modify the cronjob using a temporary log file:**

    1. Make sure you have a working Postfix Service set up.

    2. Use the following cronjob, and add a `MAILTO` variable at the top of the
        crontab file to specify the recipient email address. The cron job will
        then send an email with the output of the script if it fails:

        ```bash
        MAILTO=<your-email-address>
        0 0 1 * * cd <project-root> && ./cert_script.sh <email-address> <domain> > ./cert_renewal_tmp.log 2>&1 && cat ./cert_renewal_tmp.log >> ./cert_renewal.log || cat ./cert_renewal_tmp.log
        ```

        Example:

        ```bash
        MAILTO=admin@inject.fi.muni.cz
        0 0 1 * * cd /home/inject/https && ./cert_script.sh admin@inject.fi.muni.cz inject.fi.muni.cz > ./cert_renewal_tmp.log 2>&1 && cat ./cert_renewal_tmp.log >> ./cert_renewal.log || cat ./cert_renewal_tmp.log
        ```

3. Save and exit the crontab editor.

4. Check the logs to verify the cron job is running as expected:

    ```bash
    cat ./cert_renewal.log
    ```

#### Rootless Docker

If you are using _Rootless Docker_, you'll have to pass the `DOCKER_HOST`
variable to the script in the cron job. First, find the value of `DOCKER_HOST`
by running the following command:

```bash
echo $DOCKER_HOST
```

Then, modify the cron job to include the `DOCKER_HOST` variable.

Without the email notification, the cron job would look like this:

```bash
0 0 1 * * cd <project-root> && DOCKER_HOST="<docker-host>" ./cert_script.sh <email-address> <domain> >> ./cert_renewal.log 2>&1
```

With the email notification, it would look like this:

```bash
MAILTO=<your-email-address>
0 0 1 * * cd <project-root> && DOCKER_HOST="<docker-host>" ./cert_script.sh <email-address> <domain> > ./cert_renewal_tmp.log 2>&1 && cat ./cert_renewal_tmp.log >> ./cert_renewal.log || cat ./cert_renewal_tmp.log
```

### Next Steps

After adding the certificates, proceed with the installation as described in the
[installation guide](../overview.md).
+32 −10
Original line number Diff line number Diff line
For version 3.0.0 of IXP, download the compose preset folder for HTTPS Deployment with your own
certificates
[here](https://gitlab.fi.muni.cz/inject/docker-deployment/-/package_files/230/download), unzip it,
set it as your working directory, and follow the instructions below.
<!-- Note: This file is primarily defined to be used in the IXP documentation. However, it is also provided in the docker-deployment repository for reference. If you accessed this file from the docker-deployment repository, please be aware that the links used in this file may not work as expected. -->

## HTTPS Deployment with your own certificates (advanced)
## HTTPS Deployment with your own certificates

For HTTPS deployment with your own certificates, add `fullchain.pem` and `privkey.pem` into the
`./certificates` directory. If the format of the keys or selection of keys does not suffice, modify
the `nginx.conf.template` file and change the related configuration on line `:32-33`.
<!-- TODO: update package file for Dux -->

Docker compose mounts the `./certificates` folder as `/etc/nginx/certificates/` in the Nginx
container.
For deployment of the IXP with your own SSL certificates, download the latest
compose preset folder
[here](https://gitlab.fi.muni.cz/inject/docker-deployment/-/package_files/230/download).

After downloading the preset, unzip it, set the unzipped folder as your working
directory, and follow the instructions below.

### Adding Your Own Certificates

Add `fullchain.pem` and `privkey.pem` into the `./certificates` directory. If
the format of the keys or selection of keys does not suffice, modify the
`nginx.conf.template` file and change the related configuration on the line
`:32-33`.

### Notes:

- Docker compose mounts the `./certificates` folder as
    `/etc/nginx/certificates/` in the Nginx container.

- For development purposes, you might want to use self-signed certificates. You
    can generate them using the following command:

    ```bash
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
        -keyout privkey.pem -out fullchain.pem \
        -subj "/C=US/ST=State/L=City/O=Organization/OU=Unit/CN=localhost"
    ```

### Next Steps

After adding the certificates, proceed with the installation as described in the
[installation guide](../overview.md).
+86 −60
Original line number Diff line number Diff line
<!-- Note: This file is primarily defined to be used in the IXP documentation. However, it is also provided in the docker-deployment repository for reference. If you accessed this file from the docker-deployment repository, please be aware that the links used in this file may not work as expected. -->

# Installation

The INJECT Exercise Platform (IXP) comprises two main components: the frontend and the backend. This
separation allows for modular development, easier maintenance, and scalability of the platform.
Below, we'll walk you through the unified process of installation for frontend as well as for
backend.
The INJECT Exercise Platform (IXP) comprises two main components: the frontend
and the backend. This separation allows for modular development, easier
maintenance, and scalability of the platform. Below, we'll walk you through the
unified installation process for the frontend and backend.

For a deeper understanding of the overall architecture of the IXP, you can refer to the
[architecture overview](../architecture/overview.md) in the documentation.
For a deeper understanding of the overall architecture of the IXP, you can refer
to the [architecture overview](../architecture/overview.md) in the
documentation.

## Prerequisites

@@ -14,16 +17,19 @@ For a deeper understanding of the overall architecture of the IXP, you can refer

Before you begin, ensure that you have the following:

- A server with at least 2 core CPU and 8 GB RAM
- A 64-bit x86 architecture
- Root or sudo access to the server
- At least 4 GB of disk space, although more is necessary for long-term storage of exercise data
- a server with at least a 2-core CPU and 8 GB RAM,
- a 64-bit x86 architecture,
- root or sudo access to the server,
- and at least 4 GB of disk space, although more is necessary for long-term
    storage of exercise data.

These requirements ensure that the backend server can handle data processing efficiently while
serving the frontend interface smoothly for the most basic needs.
These requirements ensure that the backend server can handle data processing
efficiently while serving the frontend interface smoothly for the most basic
needs.

The performance mainly depends on one factor, which is _the number of teams in all currently running
exercises_. Please refer to the table below for our recommended hardware setups based on this value.
The performance mainly depends on one factor, which is _the number of teams in
all currently running exercises_. Please refer to the table below for our
recommended hardware setups based on this value.

| Number of teams | CPU Cores (Worker Count) | RAM  |
| --------------- | ------------------------ | ---- |
@@ -31,25 +37,18 @@ exercises_. Please refer to the table below for our recommended hardware setups
| 21 - 50         | 4 (8)                    | 16GB |
| 51 - 100        | 8 (16)                   | 16GB |

We cannot give a good recommendation for disk space, as that only depends on the number of exercises
and definitions stored at the same time.
We cannot give a good recommendation for disk space, as that only depends on the
number of exercises and definitions stored at the same time.

### Software Requirements

!!! Disclaimer

    If you are upgrading an existing installation, please note that all stored data will likely be lost
    during the upgrade process, as we cannot guarantee compatibility between different versions of the
    platform. To avoid problems during the upgrade process, please make sure to stop the running
    containers first by executing `docker compose down` and remove the volumes by executing
    `docker volume rm inject-data inject-pgdata`. Also make sure to rebuild the containers by executing
    `docker compose build` before running `docker compose up` again.

- Linux operating system: Debian 11 or 12 is recommended
- [Docker Engine](https://docs.docker.com/engine/install/).
- [Docker Compose](https://docs.docker.com/compose/install/linux/) with recommended version v2.27.0
- [Docker Engine](https://docs.docker.com/engine/install/)
- [Docker Compose](https://docs.docker.com/compose/install/linux/) with
    recommended version v2.27.0

Make sure to install Docker and Docker Compose before proceeding with the installation.
Make sure to install Docker and Docker Compose before proceeding with the
installation.

## Installation

@@ -61,26 +60,29 @@ Make sure to install Docker and Docker Compose before proceeding with the instal
### 2. Download the source code of the frontend and the backend:

The frontend and backend releases follow a modified version of
[Semantic Versioning](https://semver.org/). Each release is tagged with a version number in the
format `vX.Y.Z`, where:
[Semantic Versioning](https://semver.org/). Each release is tagged with a
version number in the format `vX.Y.Z`, where:

- `X` is the major version,
- `Y` is the minor version,
- `Z` is the patch version.

The major version is incremented for significant changes to the whole platform. Such releases are
deployed together with a new version of the documentation and exercise definitions.
The major version is incremented for significant changes to the whole platform.
Such releases are deployed together with a new version of the documentation and
exercise definitions.

The minor version is incremented for changes to the API. Because of this, **only the frontend and
backend with the same major and minor version are compatible with each other**. For example,
`v3.0.0` of the frontend is compatible with `v3.0.0` of the backend but not with `v2.0.0` of the
backend. Similarly, `v3.1.0` of the frontend is compatible with `v3.1.0` of the backend, but not
The minor version is incremented for changes to the API. Because of this, **only
the frontend and backend with the same major and minor version are compatible
with each other**. For example, `v3.0.0` of the frontend is compatible with
`v3.0.0` of the backend but not with `v2.0.0` of the backend. Similarly,
`v3.1.0` of the frontend is compatible with `v3.1.0` of the backend, but not
with `v3.0.0` of the backend.

The patch version is incremented for bug fixes and minor improvements. Such releases are created for
the frontend and backend separately. **The patch version of the frontend and backend does not have
to match.** For example, `v3.0.1` of the frontend is compatible with `v3.0.0` of the backend, but
not with `v2.0.0` of the backend.
The patch version is incremented for bug fixes and minor improvements. Such
releases are created for the frontend and backend separately. **The patch
versions of the frontend and backend do not have to match.** For example,
`v3.0.1` of the frontend is compatible with `v3.0.0` of the backend, but not
with `v2.0.0` of the backend.

The releases can be downloaded from the following links:

@@ -89,43 +91,67 @@ The releases can be downloaded from the following links:

### 3. Unzip the downloaded archives, move them inside the compose preset folder (`https` or `https-owncert`, depending on which one you chose for generating TLS certificates), and rename the unzipped folders to `frontend` and `backend` respectively.

Having the source code available in folders named `frontend` and `backend` is crucial for the
deployment script to work.
The deployment script expects the source code in folders named `frontend` and
`backend`.

### 4. Set up the `.env` file in the root directory (`https` or `https-owncert`).

Follow the setup guide [here](./setup.md#environment-variables). Especially make sure that:
Follow the setup guide [here](./setup.md#environment-variables). Especially make
sure that:

- `INJECT_DOMAIN` is set to your desired hostname (the same one you generated the certificate for),
- and `INJECT_SECRET_KEY` is changed to a truly random string of characters of at least 50
    characters.
- `INJECT_DOMAIN` is set to your desired hostname (the same one you generated
    the certificate for)
- and `INJECT_SECRET_KEY` is changed to a truly random string of characters of
    at least 50 characters.

### 5. Make sure the prepared scripts are executable.

The following scripts are used to set up the environment. Make sure they are executable:
The following scripts are used to set up the environment. Make sure they are
executable:

- `./01-substitute-env.sh`: you can grant the executable permission via
    `chmod +x 01-substitute-env.sh`.
- `./frontend/frontend/substituteEnv.sh`: you can grant the executable permission via
    `chmod +x frontend/frontend/substituteEnv.sh`.
    `chmod +x 01-substitute-env.sh`,
- `./frontend/frontend/substituteEnv.sh`: you can grant the executable
    permission via `chmod +x frontend/frontend/substituteEnv.sh`.

### 6. Run `docker compose up`, or `docker compose up -d` to run the containers in the background.

If any errors occur, please refer to the [troubleshooting guides](./troubleshooting.md).
If any errors occur, please refer to the
[troubleshooting guides](./troubleshooting.md).

!!! Disclaimer

### 7. Add an admin (superuser) account by following [these instructions](./users.md).
    If you are upgrading an existing installation, please note that all stored data
    will be lost during the upgrade process, as we cannot guarantee compatibility
    between different versions of the platform.

    To avoid problems during the upgrade process, please stop the running containers
    and remove the volumes by executing `docker compose down -v`. Also, make sure to
    rebuild the containers by executing `docker compose up --build` when starting
    them again.

### 7. Add an admin account by following [these instructions](./users.md).

## Conclusion

By following the installation guide, you'll be able to successfully set up and deploy the IXP. After
completing the installation, you may download this
By following the installation guide, you'll be able to set up and deploy the
IXP. After completing the installation, you may download the
[Intro Definition](https://gitlab.fi.muni.cz/inject/inject-docs/-/raw/dux/files-from-repos/intro-definition.zip?ref_type=heads&inline=false)
and try to upload it to test the platform's functionality.

If you encounter any bugs, please refer to the [Known Issues and Fixes](../../known-issues.md) page
for troubleshooting steps and solutions. If you require further assistance, don't hesitate to report
them to us. The [Report issue](../../report-issue.md) page includes instructions on how to report
bugs.
If you encounter any bugs, please refer to the
[Known Issues and Fixes](../../known-issues.md) page for troubleshooting steps
and solutions. If you encounter any other issues, don't hesitate to report them
to us through the [Report Issue](../../report-issue.md) page.

## Backup

If you want to back up your IXP installation, it's advised to back up:

- data located in the `inject-data` and the `inject-pgdata` docker volume,
- and the `INJECT_SECRET_KEY` variable. This key is critical to ensure proper
    functioning of AAI: if the same database is used with a different key, users
    will not be able to log in.

<div class="navigation" markdown>
 [&larr; Home](../../index.md){ .md-button }
+148 −95

File changed.

Preview size limit exceeded, changes collapsed.

+28 −17
Original line number Diff line number Diff line
<!-- Note: This file is primarily defined to be used in the IXP documentation. However, it is also provided in the docker-deployment repository for reference. If you accessed this file from the docker-deployment repository, please be aware that the links used in this file may not work as expected. -->

## Troubleshooting

If you encounter issues during deployment, consider the following steps:

- **Executable Permissions**: Ensure that the deployment scripts have executable permissions. Run
    the following command to set the appropriate permissions:
- **Executable Permissions**: Ensure that the deployment scripts have executable
    permissions. Run the following command to set the appropriate permissions:

    ```
    chmod +x deploy.sh 01-substitute-env.sh
    chmod +x deploy-with-https.sh generate-cert.sh  # If using HTTPS deployment
    ```

- **INJECT_DOMAIN Setting**: Verify that the INJECT_DOMAIN environment variable is set to a domain
    name and not a static IP address. The platform requires a domain name to function correctly. For
    local test deployments please use reserved TLD `.localhost` (example: `inject.localhost`)

- **Backend is not returning any valid response**: Verify that the `INJECT_DOMAIN` and
    `INJECT_HOST_ADDRESSES` is setup correctly. The platform requires that the addresses are setup
    to hostnames where the platform is expected to be accessed from.

- **Frontend's error log in Developer Console is reporting mixed-origin connection issues**: Verify
    that connection settings in the environment varibles are setup correctely. If using HTTP
    deployment, that they use `http://` and `ws://` protocol, and when using HTTPS, then `https://`
    and `wss://`.

- **Application is connecting to an incorrect backend instance**: Clean up your cookies and session
    storage to enforce rebinding of the Frontend client.
- **INJECT_DOMAIN Setting**: Verify that the INJECT_DOMAIN environment variable
    is set to a domain name and not a static IP address. The platform requires a
    domain name to function correctly. For local test deployments please use
    reserved TLD `.localhost` (example: `inject.localhost`)

- **Backend is not returning any valid response**: Verify that the
    `INJECT_DOMAIN` and `INJECT_HOST_ADDRESSES` is setup correctly. The platform
    requires that the addresses are setup to hostnames where the platform is
    expected to be accessed from.

- **Frontend's error log in Developer Console is reporting mixed-origin
    connection issues**: Verify that connection settings in the environment
    varibles are setup correctely. If using HTTP deployment, that they use
    `http://` and `ws://` protocol, and when using HTTPS, then `https://` and
    `wss://`.

- **Application is connecting to an incorrect backend instance**: Clean up your
    browser local storage to enforce rebinding of the Frontend client.

- **The application shows an error about frontend and backend versions not being
    compatible**: This usually happens after upgrading to a new version of the
    platform. To resolve this, clear your browser's cache to ensure that the
    frontend loads the latest version and can properly communicate with the
    backend.

<div class="navigation" markdown>
  [&larr; Installation overview](./overview.md){ .md-button }
Loading