This is a simple Next.JS todo app using React and TypeScript, demonstrating how to deploy a simple single-sign-on (SSO) application to Imperial’s ImPaaS platform, with a MySQL database and file volumes.
If you haven’t already, read the React Quick Start tutorial so that you understand the key concepts of React, which you’ll need to develop on this app.
Read more about Next.js here as well.
Read more about TypeScript here.
Once you understand these things, you can make a start on deploying the app.
For ease of use, we recommend developing on Linux, macOS or Windows Subsystem for Linux (WSL).
Install Node.js from the Node.js website.
Run this command to install all the necessary packages:
npm install
For development, the template app uses a MySQL database, which you will need to create an instance of. The easiest way to do so is with Docker.
First, install Docker. We recommend installing Docker Desktop.
Then, start an instance of a MySQL database using a Docker image as follows, replacing mysql
with the name of the database (this can be anything) and pass
with a chosen password. Make sure to note both of these down for later. This command will pull the MySQL Docker image and start the container.
Note: —-publish
exposes port 3306 locally (the default MySQL port) as port 3306 on the container.
docker run --name some-mysql \
--env MYSQL_ROOT_PASSWORD=pass \
--env MYSQL_DATABASE=mysql \
--env MYSQL_USER=user \
--env MYSQL_PASSWORD=pass \
--publish 3306:3306 \
--detach mysql:latest
Make a copy of .env.template
as .env
and fill in these variables, where pass
and mysql
are the password and name chosen above.
...
MYSQL_DATABASE_NAME=mysql
MYSQL_HOST=localhost
MYSQL_PASSWORD=pass
MYSQL_PORT=3306
MYSQL_USER=user
...
A volume is used for persistent file storage in your deployed app. A volume must be mounted at a certain directory. We suggest ./uploads
in development. Make this folder:
mkdir uploads
Update the .env.local
file accordingly:
...
UPLOAD_DIR=./uploads
...
Refer to this page for more info.
Login to the Entra Admin Center.
In the Entra Admin Center, head to the App Registrations page (Applications > App registrations in the sidebar). In the toolbar at the top, select “New registration”.
Fill in the name of your app and select your desired supported account types. If in doubt, select “Accounts in this organizational directory only”.
For the redirect URI, select the “Web” platform, and enter http://localhost:3000/api/auth/callback/microsoft-entra-id
as the address.
Confirm the details and you will be redirected to your app’s Entra ID App Registration page which contains some IDs.
In your project’s .env
file, set:
MS_ENTRA_CLIENT_ID
to the “Application (client) ID”MS_ENTRA_TENANT_ID
to the “Directory (tenant) ID”
From the app’s Entra ID App Registration, navigate to “Certificates & secrets”, then click on “New client secret”. Enter any description and leave the expiration as 6 months (Note: this means you will have to generate a new client secret in 6 months’ time). Click “Add”.
Copy the value from the secret into the MS_ENTRA_CLIENT_SECRET
row in the .env
file.
Assuming you’ve make a copy of .env.template
as .env
and filled it in as required (read the comments), you can start the app as follows:
npm run dev
If all goes well, the app should now be available at http://localhost:3000
Install ImPaaS as described here:
curl -fsSL "https://tsuru.io/get" | bash
echo "alias impaas='tsuru'" >> ~/.bashrc
source ~/.bashrc
Login to ImPaas:
impaas login
Create a new team:
impaas team create <TEAM_NAME>
Add members to the team as required:
impaas role-assign team-member <EMAIL_ADDRESS> <TEAM_NAME>
Create a new app:
impaas app create <APP_NAME> --team <TEAM_NAME>
Note
See information about your app by running impaas app info -a <APP_NAME>
to confirm that it was successfully created
As described above, a volume is used for persistent file storage in your deployed app. A volume must be mounted at a certain directory. To create a volume:
impaas volume create <VOLUME_NAME> azurefile \
--team <TEAM_NAME> \
--opt capacity=512Mi \
--opt access-modes=ReadWriteMany \
--pool local
Now bind your volume to the app, specifying the MOUNT_POINT_NAME
(directory to store files - we recommend using uploads
)
impaas volume bind <VOLUME_NAME> /<MOUNT_POINT_NAME> --app <APP_NAME>
Finally, set the UPLOAD_DIR
environment variable to the mount point:
impaas env set UPLOAD_DIR=/<MOUNT_POINT_NAME> --app <APP_NAME>
Create a MySQL instance for your team, specifying DB_NAME
(the name of the MySQL instance):
impaas service instance add mysql <DB_NAME> --team <TEAM_NAME>
Note
To check the instance was made: impaas service instance info mysql <DB_NAME>
Bind the MySQL instance to the app.
impaas service instance bind mysql <DB_NAME> --app <APP_NAME>
The environment variables relating to MySQL do not have to be changed as this is handled by ImPaaS automatically.
Follow the instructions in the development guide above to add SSO Authentication. However, instead of setting the environment variables in the .env
file, set them in the ImPaaS environment:
impaas env set \
MS_ENTRA_CLIENT_ID=<CLIENT_ID> \
MS_ENTRA_CLIENT_SECRET=<CLIENT_SECRET> \
MS_ENTRA_TENANT_ID=<TENANT_ID> \
--app <APP_NAME>
Add an additional redirectURI in the Entra ID portal with platform “Web” and address https://<APP_NAME>.impaas.uk/api/auth/callback/microsoft-entra-id
.
Deploy the app on ImPaaS using:
impaas app deploy \
--app <APP_NAME> \
--dockerfile Dockerfile
If you encounter a Request Entity Too Large
error when deploying the app, ensure the .tsuruignore
includes your development volumes directory (/<MOUNT_POINT_NAME>
) as this should not be included in deployment.
To view logs for the deployed app, run the following:
Note
See logs for your deployed app: impaas app log -a <APP_NAME> -l 100 --follow
To format all TypeScript source code files in the repo using prettier, run:
npm run format
app/
- Next.js app router (different from the older page router) - see https://nextjs.org/docs/app. Put layouts, pages & API routes herecomponents/
- components used by pages & layoutslib/
- Other TypeScript logic code e.g. next.js server actions, types, database logicpublic/
- Next.js directory for static files
Dockerfile
- docker file to build a container image for deployment to ImPaaS.env.template
- copy to.env.local
to specify environment variables for the app in development.gitignore
- stop large files being committed to the git repo such asnode_modules
orUPLOAD_DIR
.tsuruignore
- stop large files being uploaded to ImPaaS due to file size restrictions.prettierrc
- config for code formatter