Skip to content
Right to Education Digital Public Good by Indus Action
  • Home
  • Docs
Github
Right to Education Digital Public Good by Indus Action

User Manual

10
  • Introduction
  • User Roles and Permissions
  • Process Flow
  • What is RTE Section 12 (1) (c)?
  • Home Page
  • State Admin
  • District Admin
  • Block Admin
  • School Admin
  • Students – Public Page

Functional Documentation

8
  • Introduction
  • Features
  • Multiple user levels and role permissions
  • State Admin Login
  • District Admin Login
  • Block Admin Login
  • School User’s Public and Private (login) Interface
  • Parents access to RTE admission application

Technical Documentation

6
  • Installation Guide
  • App Administration
  • School Management
  • Student Management
  • Lottery Management
  • Student Tracking Management
  • Home
  • Docs
  • Technical Documentation
View Categories

Installation Guide

14 min read

RTE MIS (DPG) Installation

System Requirements

  • Operating system: Ubuntu 24.04
  • RAM: Minimum 16 GB (for actual prod env deployed by govts)
  • Processor: Any modern multicore processor
  • Disk space: As per application requirements

Software Versions

  • PHP: 8.2
  • MySQL: 8.0.35
  • Nginx: Latest version

Platforms Involved

  • AWS (EC2, load balancer

Step-By-Step Installation Guide

1. Set up an EC2 instance

  • Operating system: Ubuntu 24.04 OS
  • Instance type: t3a.medium (minimum)
  • Volume: EBS (minimum of 30 GB storage)

2. Set up a target group

  • Target type: Instances
  • Target group name: *-tg
  • Protocol: HTTP
  • Port: 80
  • On the next page: register the EC2 instance created above
  •  associated load balancer and listener rule.

3. Set up the domain name record pointing to the load balancer URL.

4. Update the package list and upgrade existing packages:

sudo apt update && sudo apt upgrade -y

2. Add the repository for PHP

sudo add-apt-repository ppa:ondrej/php sudo apt update

3. Install PHP 8.2 and required extensions:

sudo apt install php8.2 php8.2-fpm php8.2-mysql php8.2-intl php8.2-curl php8.2-mbstring php8.2-xml php8.2-zip php8.2-ldap php8.2-gd php8.2-bz2 php8.2-sqlite3 php8.2-redis

4. Open php.ini to increase the PHP memory limit:

sudo nano /etc/php/8.2/fpm/php.ini

5. Change the memory_limit value to 512M:

memory_limit = 512M

6. Restart PHP-FPM service to apply the changes:

sudo systemctl restart php8.2-fpm

7. Install MySQL server:

sudo apt install mysql-server

8. Secure the MySQL installation:

sudo mysql_secure_installation

9. Answer the prompts that follow the above command according to the statements below:

  • Type and submit “Y” (for yes) to the question, “Would you like to set up VALIDATE PASSWORD component?”
  • Type and submit “0” (Low) or “1” (Medium) or “2” (High) for password strength.
  • Password for the root user is not set and skipped as authentication with auth_socket is used by default.
  • Type and submit “Y” to the question “Remove anonymous users?”
  • Type and submit “Y” to the question “Disallow root login remotely?”
  • Type and submit “Y” to the question “Remove test database and access to it?”
  • Type and submit “Y” to the question “Reload privilege tables now?”

10. Log into MySQL as root (since the password is not set; simply press “Enter” for the password prompt):

sudo mysql -u root -p

11. Set password for the root user:

ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘new_password’;

12. Flush privileges for change to take effect:

FLUSH PRIVILEGES;

13. Create a new MySQL user and set a password:

CREATE USER ‘newuser’@’localhost’ IDENTIFIED BY ‘password’;

14. Create a new database:

CREATE DATABASE example;

15. Grant all privileges on the new database to the new user:

GRANT ALL PRIVILEGES ON example.* TO ‘newuser’@’localhost’;

16. Flush privileges to ensure that they take effect:

FLUSH PRIVILEGES;

17. Exit MySQL:

EXIT;

18. Add the repository for Nginx:

sudo add-apt-repository ppa:ondrej/nginx && sudo apt update

19. Install Nginx

sudo apt install nginx

20. Install Composer

sudo apt install composer

21. Set Up the RTE-MIS project directory

cd /var/www/

22. Create the project using Composer (will download rte-mis-project from Composer’s registry)

sudo composer create-project indus-action-initiatives/rte-mis-project:^1.0 <project-name>

23. Project Permission (add sudo if required)

sudo chown ${USER}:www-data <project-name>

24. Navigate to the project directory

cd <project-name>

25. Install dependencies

composer install

26. Fix Permissions (add sudo if required)

cd ~
wget https://gist.githubusercontent.com/kunal-sin/1ba9eeaa26237ef8fe3f70ea63d77763/raw/ec699ee673f139a4812f93b3a80dd3f49938f883/fix-permissions.sh
chmod +x fix-permissions.sh

sudo bash ./fix-permissions.sh –drupal_path=/var/www/rte-mis-project/docroot –drupal_user=${USER} –httpd_group=www-data

27. Configure file permissions

cd docroot
mkdir sites/default/files
chmod a+w sites/default/files/
cp sites/default/default.settings.php sites/default/settings.php
chmod 777 sites/default/settings.php

28. Create a new Nginx configuration file:

sudo nano /etc/nginx/sites-available/rte-mis-[prod | dev | staging]

29. Nginx configuration sample (modify appropriate values)

server {    listen 80;    server_name example.com;    root /var/www/<project_path>/docroot; ## <– Your only path reference.        location = /favicon.ico {        log_not_found off;        access_log off;    }
    location = /robots.txt {        allow all;        log_not_found off;        access_log off;    }
    # Very rarely should these ever be accessed outside of your lan    location ~* \.(txt|log)$ {        allow 192.168.0.0/16;        deny all;    }
    location ~ \..*/.*\.php$ {        return 403;    }
    location ~ ^/sites/.*/private/ {        return 403;    }
    # Block access to scripts in site files directory    location ~ ^/sites/[^/]+/files/.*\.php$ {        deny all;    }
    # Allow “Well-Known URIs” as per RFC 5785    location ~* ^/.well-known/ {        allow all;    }
    # Block access to “hidden” files and directories whose names begin with a    # period. This includes directories used by version control systems such    # as Subversion or Git to store control files.    location ~ (^|/)\. {        return 403;    }
    location / {        # try_files $uri @rewrite; # For Drupal <= 6        try_files $uri /index.php?$query_string; # For Drupal >= 7    }
    location @rewrite {        #rewrite ^/(.*)$ /index.php?q=$1; # For Drupal <= 6        rewrite ^ /index.php; # For Drupal >= 7    }
    # Don’t allow direct access to PHP files in the vendor directory.    location ~ /vendor/.*\.php$ {        deny all;        return 404;    }
    # Protect files and directories from prying eyes.    location ~* \.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|/(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config)$|/#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$ {        deny all;        return 404;    }
    # In Drupal 8, we must also match new paths where the ‘.php’ appears in    # the middle, such as update.php/selection. The rule we use is strict,    # and only allows this pattern with the update.php front controller.    # This allows legacy path aliases in the form of    # blog/index.php/legacy-path to continue to route to Drupal nodes. If    # you do not have any paths like that, then you might prefer to use a    # laxer rule, such as:    #   location ~ \.php(/|$) {    # The laxer rule will continue to work if Drupal uses this new URL    # pattern with front controllers other than update.php in a future    # release.    location ~ ‘\.php$|^/update.php’ {        fastcgi_split_path_info ^(.+?\.php)(|/.*)$;        # Ensure the php file exists. Mitigates CVE-2019-11043        try_files $fastcgi_script_name =404;        # Security note: If you’re running a version of PHP older than the        # latest 5.3, you should have “cgi.fix_pathinfo = 0;” in php.ini.        # See http://serverfault.com/q/627903/94922 for details.        include fastcgi_params;        # Block httpoxy attacks. See https://httpoxy.org/.        fastcgi_param HTTP_PROXY “”;        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;        fastcgi_param PATH_INFO $fastcgi_path_info;        fastcgi_param QUERY_STRING $query_string;        fastcgi_intercept_errors on;        fastcgi_buffers 16 16k;         fastcgi_buffer_size 32k;        # PHP 5 socket location.        #fastcgi_pass unix:/var/run/php5-fpm.sock;        # PHP 7 socket location.        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;#        fastcgi_param PHP_VALUE “appoptics.service_key=eTAlz2fpDiXu7rinnA4fkfOhLzY-J4F13nb9oiEx1LLenqjM4B6B24g7kER1mz9vQ24DYyo:rte-dev”;    }
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {        try_files $uri @rewrite;        expires max;        log_not_found off;    }
    # Fighting with Styles? This little gem is amazing.    # location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6    location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7        try_files $uri @rewrite;    }
    # Handle private files through Drupal. Private file’s path can come    # with a language prefix.    location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7        try_files $uri /index.php?$query_string;    }
    # Enforce clean URLs    # Removes index.php from urls like www.example.com/index.php/my-page –> www.example.com/my-page    # Could be done with 301 for permanent or other redirect codes.    if ($request_uri ~* “^(.*/)index\.php/(.*)”) {        return 307 $1$2;    }}

30. Sym link the website config in to sites-enabled

# For sym-linking, use absolute paths$ sudo ln -s /etc/nginx/sites-available/rte-mis /etc/nginx/sites-enabled/$ sudo nginx -t
$ sudo systemctl restart nginx.service

31. Visit the site and complete the initial setup

  • uncheckedSelect language and click the “Save and continue” button.
  • uncheckedEnter the database username and password set earlier.

32. Secure the file permissions after importing content:

chmod go-w sites/default/settings.php
chmod go-w sites/default/
  • uncheckedThe site will start installing automatically and update translations.
  • uncheckedFill out the site information form and click “Save and continue”.

33. Import the content assets:

cd ..
cp -r docroot/profiles/contrib/rte-mis/config/content/assets/* docroot/sites/default/files/

34. Import the content using Drush

vendor/bin/drush cr
vendor/bin/drush content:import profiles/contrib/rte-mis/config/content/media/content-bulk-export-18_06_2024-16_40.zip
vendor/bin/drush content:import profiles/contrib/rte-mis/config/content/node/content-bulk-export-18_06_2024-16_37.zip
vendor/bin/drush content:import profiles/contrib/rte-mis/config/content/menu_link_content/content-bulk-export-18_06_2024-16_35.zip

35. Turning off the aggregation

vendor/bin/drush -y config-set system.performance css.preprocess 0vendor/bin/drush -y config-set system.performance js.preprocess 0

36. Start and enable cron (for lottery):

sudo systemctl start cronsudo systemctl enable cron

37. Add executable permission for script files:

cd docroot/profiles/contrib/rte-mis
chmod +x scripts/lottery/process_lottery_data.shchmod +x scripts/lottery/process_allocation_student_queue.sh

38. Open the crontab:

crontab -e

Add the below jobs:

#Process lottery(student_data_lottery_queue_cron) queue. */3 * * * * bash -c  ‘/var/www/<project-path>/scripts/lottery/./process_lottery_data.sh /var/www/<project-path>/docroot rtemis.indusaction.org 120 > /dev/null 2>&1’  # Process student allocation(student_allocation) queue. */3 * * * * bash -c  ‘/var/www/<project-path>/scripts/lottery/./process_allocation_student_queue.sh /var/www/<project-path>/docroot  rtemis.indusaction.org 120 > /dev/null 2>&1’

Verify the job:

crontab -l

7. Amazon SES Mail Setup and configuration Guide.

1. Remove the AWS Account from Sandbox Mode

When you first create an Amazon SES account, it is in sandbox mode. In this mode, you can only send emails to verified email addresses, and there are sending limits. To use SES in production mode, you must request a removal from the sandbox.

Limitations in Sandbox Mode:
  • Email Sending Restrictions: You can only send email to verified email addresses and domains.
  • Sending Quotas: There are lower sending limits compared to production mode.
  • No Bulk Emailing: Bulk emailing is not allowed in sandbox mode.

2. Verify a Domain in Amazon SES

To send emails from your domain using Amazon SES, you need to verify your domain.

Steps to Verify a Domain:
  1. Choose Verified Identities from the left navigation pane in the Amazon SES console.
  2. Click Create Identity.
  3. Select Domain and enter your domain name.
  4. Choose Verify This Domain.
  5. Amazon SES will provide a set of DNS records that you need to add to your domain’s DNS settings:
    • DKIM (Domain Keys Identified Mail): This improves email deliverability and prevents spoofing.
    • Verification Record: This is typically a TXT record that proves domain ownership.
  6. Add the provided DNS records to your domain’s DNS settings. The method to add DNS records varies depending on your DNS provider.
  7. Once added, go back to the Amazon SES console and choose Verify. The verification process may take some time.
Create Credentials for Amazon SES in IAM

You need to create IAM credentials to send emails programmatically using Amazon SES.

Steps to Create IAM Credentials:

  • Sign in to the AWS Management Console and open the IAM (Identity and Access Management) console.
  • In the navigation pane, click on Policies, then click Create Policy.
  • Choose the JSON tab and paste the following policy:

{

    “Version”: “2012-10-17”,

    “Statement”: [

        {

            “Effect”: “Allow”,

            “Action”: “ses:SendRawEmail”,

            “Resource”: “*”

        }

    ]

}

  • Click Next: Tags (optional) if you want to add metadata tags to the policy, and then click Next: Review.
  • Provide a Name for the policy, such as SESSendRawEmailOnlyPolicy, and an optional Description.
  • Click Create Policy.

Steps to Attach the Policy to an IAM User

  1. Still in the IAM console, click Add User in the Users section.
  2. Enter a User name and select Programmatic access under Select AWS credential type to create access keys for API, CLI, SDK, and other development tools.
  3. Click Next: Permissions.
  4. Choose Attach policies directly, then find and select the newly created policy (SESSendRawEmailOnlyPolicy).
  5. Click Next: Tags to add optional metadata tags, and then Next: Review.
  6. Review your selections and click Create User.
  7. On the Success page, you will see the access key ID and Secret access key. Download the .csv file or copy the keys and store them securely. You will use these credentials to configure Postfix or any other application that needs to send emails using Amazon SES.

3. Install Postfix

Postfix is a popular mail transfer agent (MTA) for sending emails. You need to install and configure Postfix to work with Amazon SES.

Update the package lists:

sudo apt update


Install the package:

sudo apt install postfix

After postfix is installed and the domain is verified in Amazon SES, Open the postfix configuration file:

sudo nano /etc/postfix/main.cf

Remove the empty relay host line and add the following lines at the end of the file:

  1. Open the postfix configuration file:

sudo nano /etc/postfix/main.cf

  1. Remove the empty relay host line and add the following lines at the end of the file:

relayhost = [email-smtp.eu-west-2.amazonaws.com]:587

smtp_sasl_auth_enable = yes

smtp_sasl_security_options = noanonymous

smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

smtp_use_tls = yes

smtp_tls_security_level = encrypt

smtp_tls_note_starttls_offer = yes

Change eu-west-2 to the region where the SES domain is verified.

  1. Create the authentication file:

sudo nano /etc/postfix/sasl_passwd

And add the SMTP Credentials in the following format:

[$SMTP_HOST]:587 $SMTP_USERNAME:$SMTP_PASSWORD

  1. Hash the authentication file:

sudo postmap hash:/etc/postfix/sasl_passwd

  1. Set the owner and file permissions:

sudo chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db

sudo chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db

sudo chown -R root:root /etc/postfix/

sudo chmod -R 655 /etc/postfix/ 

  1. Restart the Postfix service to apply changes:

sudo systemctl restart postfix

Testing from the command line

In the first test, we send an email from the command line; we need to log in via SSH check and install the mail utils package first.

  1. We update the package sources and install the mail utils package.

sudo apt update && sudo apt -f install mailutils

  1. We open a second terminal to tail the mail log file:

sudo tail -f /var/log/mail.log -n1000

  1. We send a test email from the command line:

echo “Test Message” | mail -s “Test Subject” -a “From:$FROM_EMAIL” $RECEPIENT

$FROM_EMAIL is the email ID from which emails will reach your end user, and $RECEPIENT is the email ID.

If you see, status=sent, then the email has been successfully delivered.

Updated on April 24, 2025
App Administration

ADDRESS

Indus Action Initiatives
G-7, 2nd Floor, Lajpat Nagar III
New Delhi – 110024
📧 tech@indusaction.org

QUICK LINKS

  • RTE MIS
  • About Us

CONNECT

  • Facebook
  • Instagram
  • LinkedIn
  • X
  • YouTube

© 2025 Right to Education Digital Public Good by Indus Action

  • Home
  • Docs