Commit 794d308f authored by Adam Parák's avatar Adam Parák 💬
Browse files

Merge branch 'add-tagger' into 'main'

Docker CI cleanup

Closes #269

See merge request inject/frontend!400
parents 4ae05e52 ab591a99
Loading
Loading
Loading
Loading
+75 −7
Original line number Diff line number Diff line
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/pipeline/#customization
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
# Container Scanning customization: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings
# Note that environment variables can be set in several places
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
image: node:20

stages:
- test
- buildimage
- createtag

variables:
  ID: "${CI_COMMIT_SHORT_SHA}"
  GIT_SUBMODULE_STRATEGY: recursive
@@ -19,25 +15,51 @@ variables:
  DOCKER_HOST: tcp://docker:2375
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ''
  TAGGER_OUTPUT: "false"

.disable-for-tagger:
  rules:
    - if: $TAGGER_OUTPUT == "false"
      when: on_success
    - when: never

.enable-for-tagger:
  rules:
    - if: $TAGGER_OUTPUT == "false"
      when: never
    - if: $CI_COMMIT_BRANCH == "main" && $CI_COMMIT_TAG
      when: on_success

default:
  tags:
  - inject

cache:
  key: yarn-cache
  paths:
  - ".yarn"


unit-test-job:
  stage: test
  script:
  - yarn test
  before_script:
  - yarn
  extends:
    - .disable-for-tagger


lint-test-job:
  stage: test
  script:
  - yarn lint
  before_script:
  - yarn
  extends:
    - .disable-for-tagger


tsc-test-job:
  stage: test
  script:
@@ -45,19 +67,31 @@ tsc-test-job:
  - yarn workspace @inject/frontend tsc
  before_script:
  - yarn
  extends:
    - .disable-for-tagger


sast:
  variables:
    SAST_EXCLUDED_PATHS: backend
  allow_failure: true
  extends:
    - .disable-for-tagger


dependency_scanning:
  variables:
    DS_EXCLUDED_PATHS: backend
  allow_failure: true
  extends:
    - .disable-for-tagger


secret_detection:
  allow_failure: false
  extends:
    - .disable-for-tagger


create-image:
  image: docker:20.10.16
@@ -82,6 +116,9 @@ create-image:
    -t $IMAGE_TAG -t $IMAGE_LATEST ${CI_PROJECT_DIR}
  - docker push $IMAGE_TAG
  - docker push $IMAGE_LATEST
  extends:
    - .enable-for-tagger


release_job:
  stage: buildimage
@@ -93,6 +130,37 @@ release_job:
  release:                               # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties
    tag_name: '$CI_COMMIT_TAG'
    description: 'Version ${CI_COMMIT_TAG}, for more info please check the changelog in the documentation.'
  extends:
    - .enable-for-tagger


create-tag:
  image: python:3.8-buster
  stage: createtag
  variables:
    VERSION_TYPE: minor
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual
  before_script:
    - git config user.email "$GITLAB_USER_EMAIL"
    - git config user.name "$GITLAB_USER_NAME"
  script:
    - old_version=$(sed -n "s/^export const version = '\(.*\)'/\1/p" frontend/src/constants.ts)
    - new_version=$(python tagging.py "$old_version" "$VERSION_TYPE")
    - >
      if [[ $? -ne 0 ]]; then
        exit 1
      fi
    - sed "s/^export const version = .*/export const version = '$new_version'/" frontend/src/constants.ts --in-place
    - git add frontend/src/constants.ts
    - git commit -m "update version and create new tag"
    - git tag -f "$new_version" -m "frontend version $new_version"
    - git push --tags https://tagger:$TAGGER_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH HEAD:$CI_COMMIT_REF_NAME -o ci.variable="TAGGER_OUTPUT=true"
  extends:
    - .disable-for-tagger



include:
  - template: Security/Dependency-Scanning.gitlab-ci.yml
+1 −3
Original line number Diff line number Diff line
@@ -22,9 +22,7 @@ COPY . .

RUN yarn workspace @inject/frontend prebuild

ARG BUILD_NUMBER

RUN VITE_BUILD_NUMBER=${BUILD_NUMBER} yarn workspace @inject/frontend build
RUN yarn workspace @inject/frontend build

FROM nginx:1-alpine

docker/nginx-deployment/.env

deleted100644 → 0
+0 −29
Original line number Diff line number Diff line
# sets up appropriate hostname for the Nginx server
INJECT_DOMAIN=inject.localhost

# Secret key for cryptographic signing
INJECT_SECRET_KEY=your-at-least-fifty-or-more-characters-long-secret-key

# enable AAI, uncomment the next line to disable it
# INJECT_NOAUTH=true

# host parametres that should be setup for client and server to interact correctly,
# do not touch unless you know what you are doing
INJECT_HOST_ADDRESSES=$INJECT_DOMAIN
VITE_HTTP_HOST=$INJECT_DOMAIN
CORS_ALLOWED_ORIGINS=http://$INJECT_DOMAIN

# for certbot generation, use with certbot-generator.yml
CERTBOT_EMAIL=noemail@inject.localhost

# for email sending of AAI mails
INJECT_EMAIL_HOST=
INJECT_EMAIL_PORT=
INJECT_EMAIL_HOST_USER=
INJECT_EMAIL_HOST_PASSWORD=
INJECT_EMAIL_SENDER_ADDRESS=
INJECT_EMAIL_PROTOCOL=

# enable logging to a specific file
# INJECT_LOGS=data/
+0 −4
Original line number Diff line number Diff line
#!/usr/bin/env sh

echo 'Substituting environment variables in nginx.conf.template'
envsubst '${INJECT_DOMAIN}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
 No newline at end of file

docker/nginx-deployment/README.md

deleted100644 → 0
+0 −163
Original line number Diff line number Diff line
---
tags: used_in_docs
---
## Deployment using Nginx

INJECT Exercise Platform provides a simplified deployment method via Docker Compose. 
This method simplifies the deployment by creating necessary settings and pairings between the frontend and backend and also creating a singular endpoint for accessing INJECT Exercise Platform.

This solution consists of 3+1 containers: frontend, backend, Nginx Proxy (as a front-facing router) and [Certbot](https://certbot.eff.org/).

Frontend and Backend are setup to communicate under a single endpoint handled by Nginx Proxy. The Proxy forwards appropriate requests either to Frontend or Backend. 
Certbot handles the generation of HTTPS certificates if needed. 
Currently it only simplifies the creation of new certificates, but it is not automated.

Deployment is setup with persistent storage under a Docker Compose volume called `backend-data`. This volume contains any data generated by INJECT. At current state it's adviced if there is any manipulation to be done on said containers (ex. restarting, shutting them down, updating, etc.) to ensure that no exercises are running at given point of time.

## Environment variables

For environment variables, please refer to the `.env` file. 
The example file contains an ideal set of environment variables to set up the platform. 
Below, the variables are categorized and described for better understanding.

### General Configuration
```
# sets up an appropriate hostname for the Nginx server
INJECT_DOMAIN=inject.localhost

# Secret key for cryptographic signing
INJECT_SECRET_KEY=your-at-least-fifty-or-more-characters-long-secret-key
```


- INJECT_DOMAIN: Defines the hostname for the Nginx server. This should be set to the **domain name** that points to your server's IP address.
- INJECT_SECRET_KEY: Used to provide cryptographic signing. Must be at least 50 characters long. Can be anything.


### Authentication, Authorization and Identification (AAI)

AAI enables user authentication and sending user credentials via email. 
The emails are sent out using an external SMTP server.

The settings for sending emails is configured the following environment variables in `.env` file. 

```
# for email sending of AAI mails
INJECT_EMAIL_HOST=
INJECT_EMAIL_PORT=
INJECT_EMAIL_HOST_USER=
INJECT_EMAIL_HOST_PASSWORD=
INJECT_EMAIL_SENDER_ADDRESS=
INJECT_EMAIL_PROTOCOL=
```

- INJECT_NOAUTH: Comment this out to to enable AAI (enabled by default).

#### Email Configuration for AAI

- INJECT_EMAIL_HOST: SMTP server address for sending emails.
- INJECT_EMAIL_PORT: Port for the SMTP server.
- INJECT_EMAIL_HOST_USER: Username for the SMTP server.
- INJECT_EMAIL_HOST_PASSWORD: Password for the SMTP server.
- INJECT_EMAIL_SENDER_ADDRESS: Email address used as the sender for outgoing emails.
- INJECT_EMAIL_PROTOCOL: Preferred protocol for communication with SMTP server. The choices (values) can be _ssl_ or _tls_ (case insensitive). This variable can also be left undefined - no encryption will be used.

## HTTPS Deployment

For HTTPS deployment, you need to generate HTTPS certificates.

Use the `generate-cert.sh` script, which calls [Certbot](https://certbot.eff.org/) and outputs certificates in the `./certbot` directory of the Compose script for the given `INJECT_DOMAIN` setup in the `.env` file.  Before full deployment ensure that `.env` file has correctly set protocols for HTTP communication. That is - `https` and `wss`, failing to do so may lead to connection issues. This applies for `CORS_ALLOWED_ORIGINS` and `VITE_HTTP_WS`
For more information on configuration of this script, please refer to [CertBot Configuration](#certbot-configuration)

When the certificates are generated, execute `deploy-with-https.sh` which will run INJECT Exercise Platform. 
This script launches three Docker Compose layers that form a complete script.
The first one is the basal binding compose file (`docker-compose.yml`), which establishes the basic bindings between frontend, backend, and Nginx Proxy.
The second one (`compose-from-registry.yml`) sets up appropriate import paths for frontend and backend images.
The last one (`compose-with-nginx-https.yml`) sets up Nginx Proxy to run in HTTPS mode under ports `80` and `443` and generates the necessary nginx configuration from `nginx-https.conf.template`.

## HTTP Deployment

Although HTTPS is the recommended and default deployment method, you can still deploy the platform using HTTP. Before full deployment ensure that `.env` file has correctly set protocols for HTTP communication. That is - `http` and `ws`, failing to do so may lead to connection issues. This applies for `CORS_ALLOWED_ORIGINS` and `VITE_HTTP_WS`

For HTTP deployment, please refer to the `deploy.sh` script in the root of the folder.
The script is similar to `deploy-with-https.sh` with one caveat, and that's the usage of `compose-with-nginx.yml` instead of `compose-with-nginx-https.yml` which by essence does the same but uses a different NGINX template (`nginx.conf.template`) and runs on port `80`.

## Creating an Admin

After deployment, you might need to create a admin to manage the platform. Follow these steps in order to create a admin:


 - List the running Docker containers to find the **NAME** of the backend container:
    ```
    docker ps
    ```
 - Execute a shell session in the backend container. Replace `CONTAINERNAME` with the actual container **NAME** of the backend service:
    ```
    docker exec -it CONTAINERNAME python manage.py shell
    ```

- Create a admin using the Django shell. Replace `email@test.com` and `password` with your desired admin credentials.:

    ``` python
    from user.models import User
    User.objects.create_superuser(username="email@test.com", password="password")
    ```

## Optional and additional settings

### Disabling AAI

To disable AAI, modify the `.env` file and uncomment the `INJECT_NOAUTH` variable. Doing so disables the AAI.

### CertBot Configuration

If you want to use HTTPS, you can generate certificates using CertBot. Configure the following environment variable in your `.env` file:

```
# for certbot generation, use with certbot-generator.yml
CERTBOT_EMAIL=noemail@inject.localhost
```

- CERTBOT_EMAIL: Email address used for generating HTTPS certificates with CertBot.

### Logging and Debugging

If you need to enable logging or debugging for the backend, configure the following environment variables in your .env file:

```
# enable logging to a specific file
# INJECT_LOGS=data/

# enable debug mode for the backend
INJECT_DEBUG=
```

- INJECT_LOGS: Path to the log file. Uncomment and set this variable to enable logging.
- INJECT_DEBUG: If set, enables debug mode for the backend.

### Host and Connection Settings
```
# host parameters that should be set up for the client and server to interact correctly,
# do not touch unless you know what you are doing
INJECT_HOST_ADDRESSES=$INJECT_DOMAIN
VITE_HTTP_HOST=$INJECT_DOMAIN
CORS_ALLOWED_ORIGINS=http://$INJECT_DOMAIN
```

- INJECT_HOST_ADDRESSES: Specifies the address where the backend can be reached.
- VITE_HTTP_HOST: Defines the HTTPS host for the frontend.
- CORS_ALLOWED_ORIGINS: Lists the origins allowed for Cross-Origin Resource Sharing (CORS). Implicitly set-up values by backend include: `http://localhost:5173`, `http://127.0.0.1:5173`, `http://localhost:8000`, `http://127.0.0.1:8000`.

## 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:
    ```
    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`)

- **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://`. After fixing the issues please reset your cookies and local storage.
Loading