@@ The main branch contains the code for the regular version of CodeLabeller. @@
+ The code for the demo version is available in the demo branch.CodeLabeller is a web-based tool for labeling and annotating code snippets for research purposes.
If you use CodeLabeller in your research, please cite:
Nazar, N., Chen, N., & Chong, C. Y. (2023). "CodeLabeller: A Web-Based Code Annotation Tool for Java Design Patterns and Summaries." International Journal of Software Engineering and Knowledge Engineering, 33(07), 993-1009.
https://doi.org/10.1142/S0218194023500213
Note: This project has been updated to work with Node.js v16-24. The original version required Node.js 14.
Node.js (v16 or higher recommended):
# For Node.js 16 (LTS)
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejsWindows Users: The application can be run on Windows using PowerShell. Docker Desktop is required for database and Redis services.
Docker:
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo curl -L "https://github.com/docker/compose/releases/download/1.28.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker volume create --name=codelabellerdataSSL/HTTPS certificate (fill in domain name and contact email as appropriate):
DNS A Record for specified domain must point to IP address of host machine, and port 80 must be opened for obtaining the SSL certificate.
sudo apt-get install -y certbot
sudo certbot certonly --standalone --preferred-challenges http -d <DOMAIN_NAME> --non-interactive --agree-tos -m <CONTACT_EMAIL_ADDRESS>PM2 (Process manager)
npm install pm2 -g-
Install dependencies:
npm install
-
Configure environment variables:
- Copy
.env.exampleto.env(if available) or create.envfile - Set
API_DEPLOY_MODE="DEV"for development - Configure database and Redis passwords in both
.envanddocker-compose.yaml - See Environment Variables section for all required variables
- Copy
-
Start Docker containers:
docker-compose up -d
-
Create the database:
CREATE DATABASE codelabeller COLLATE 'utf8_bin';
-
Start the development server:
npm start
This will start three servers:
- Angular dev server:
http://localhost:4201(for development) - API server:
http://localhost:3333/api - Frontend server:
http://localhost:4200(for production builds)
- Angular dev server:
-
Access the application:
- For development: Open
http://localhost:4201in your browser
- For development: Open
-
The
package.jsonfile needs to be copied to the deployment server, andnpm installcommand needs to be run when starting the project for the first time or whenever new npm project dependencies are added. -
Environment variables need to be specified in the provided
.envfile. -
Create a Docker container for the database (MySQL) and Redis servers (if containers are not already running):
-
Copy the
docker-compose.yamlprovided file to the deployment server. In the same directory as this file. -
For the passwords to be used for the MySQL and Redis servers container instances, change
<ENTER PASSWORD>to your desired passwords. -
Then, run the command within the same working directory as the
docker-compose.yamlfile:
docker-compose up -d
- Storing persistent data on External Docker volumes is essential to avoid database data loss, as all data within a container is also destroyed when the container is destroyed.
-
-
Initialise the database (first run only):
- Make sure a database with the name as given in the DB_DATABASE_NAME environment variable has been created/exists. Case sensitive database collation must be created/used. For example:
CREATE DATABASE codelabeller COLLATE 'utf8_bin'; - Run the server with API_DEPLOY_MODE set to "DEV".
- Once the server is ready and listening, stop the server, change the API_DEPLOY_MODE environment variable to "PROD" and restart the server.
- Future runs should have API_DEPLOY_MODE set to "PROD".
- Make sure a database with the name as given in the DB_DATABASE_NAME environment variable has been created/exists. Case sensitive database collation must be created/used. For example:
-
Initialise a CodeLabeller administrator account (first run only - subsequent accounts can be done via the CodeLabeller administration panel):
- Once the Docker container for MySQL is running, grab its ID:
docker ps -a
docker exec -it <CONTAINER ID> /bin/bash # now within container mysql -p <DB_DATABASE_NAME> # enter database user password, should be the same value as the one specified for the DB_PASSWORD environment variable. # run the following SQL query. Replace the email and name values accordingly. INSERT INTO `user` (`id`, `timeCreated`, `lastSeen`, `isEnabled`, `isAdmin`, `email`, `givenName`, `familyName`, `currentFileId`) VALUES (uuid(), 'CURRENT_TIMESTAMP(6)', NULL, '1', '1', '<EMAIL ADDRESS>', '<GIVEN NAME>', '<FAMILY NAME>', NULL);
The commands below assume that the current working directory is the project's root directory.
# Install all project dependencies
npm install
# Start development servers (Angular dev server on port 4201, API on port 3333)
npm start
# Access the application
# - Development: http://localhost:4201
# - API: http://localhost:3333/apiNote for Modern Node.js: This project uses Angular 12 which requires the legacy OpenSSL provider flag. This is automatically set in the npm scripts via NODE_OPTIONS=--openssl-legacy-provider.
Production commands (on a remote server):
# Build application in production mode
npm run build
# run on server
pm2 start node dist/apps/api/main.js --exp-backoff-restart-delay=100 --name api
pm2 start node dist/apps/frontend-server/main.js --exp-backoff-restart-delay=100 --name proxy# to stop the server
pm2 delete api
pm2 delete proxyThis project has been updated to work with modern Node.js versions (v16-24). Key changes include:
- Updated NestJS dependencies to v7.6.18 for better compatibility
- Added legacy OpenSSL provider flag for Node.js 17+ compatibility
- Fixed import statements to support ES module interop
- Added
.npmrcwithlegacy-peer-deps=truefor dependency resolution - Changed Angular dev server port to 4201 to avoid conflicts with frontend server
- Works on Windows with PowerShell and Docker Desktop
- MySQL 5.7.32 and Redis (Alpine) in Docker containers
- Requires creating
corpusandtemp_uploadsdirectories in project root
- Some TypeScript warnings remain but don't affect functionality
- Google OAuth configuration required for user login (see Creating an OAuth Client ID)
- Frontend server (port 4200) requires production build to function properly
-
API_DEPLOY_MODE: "DEV" if dev mode, or "PROD" if prod mode. -
API_DOMAIN_NAME: The domain name where the API can be accessed. Do not include http://, https://, or a trailing slash in this value. -
API_GLOBAL_PREFIX: The URL path prefix for all API endpoints. Should include a leading slash. -
API_PORT: The port number for which the API server should be listening on. -
SSL_CERT_ABSOLUTE_PATH: The absolute path to the SSL certificate file. For certificates issued by Let's Encrypt, use the fullchain.pem file. -
SSL_PRIVATE_KEY_ABSOLUTE_PATH: The absolute path to the SSL private key file. For certificates issued by Let's Encrypt, use the privkey.pem file. -
SSL_CA_ABSOLUTE_PATH: The absolute path to the certificate authority file. For certificates issued by Let's Encrypt, use the chain.pem file. -
DB_CONN_NAME: The internal name/identifier string for the connection to the MySQL database. -
DB_HOST: The domain name or IP address of the server hosting the MySQL database. -
DB_PORT: The port number of the server on which the database is listening on. Usually "3306". -
DB_DATABASE_NAME: The name of the MySQL database to connect to. -
DB_USERNAME: The username of the user account that will be used to connect to the MySQL database. -
DB_PASSWORD: The password of the user account that will be used to connect to the MySQL database. -
REDIS_HOST: The domain name or IP address of the server running Redis. -
REDIS_PORT: The port number on which the Redis server is listening on. Usually "3789". -
REDIS_PASSWORD: The password that will be used to connect to the Redis server. -
CORPUS_ABSOLUTE_PATH: The absolute path to the directory where the corpus will be stored on disk. -
TEMP_UPLOADS_ABSOLUTE_PATH: The absolute path to the directory where project upload job files that were uploaded to the server will be temporarily stored on disk. -
GOOGLE_OAUTH_CLIENT_ID: The Google OAuth 2.0 Client ID required to enable OAuth login for users. Details on how to get one can be found here
-
DEPLOY_MODE: "DEV" if dev mode, or "PROD" if prod mode. -
DOMAIN_NAME: The domain name where the frontend app can be accessed. Do not include http://, https://, or a trailing slash in this value. -
PORT: The port number for which the frontend server should be listening on. -
API_GLOBAL_PREFIX: The URL path prefix for all API endpoints. Should include a leading slash. -
API_PORT: The port number for which the API server is listening on. -
SSL_CERT_ABSOLUTE_PATH: The absolute path to the SSL certificate file. For certificates issued by Let's Encrypt, use the fullchain.pem file. -
SSL_PRIVATE_KEY_ABSOLUTE_PATH: The absolute path to the SSL private key file. For certificates issued by Let's Encrypt, use the privkey.pem file. -
SSL_CA_ABSOLUTE_PATH: The absolute path to the certificate authority file. For certificates issued by Let's Encrypt, use the chain.pem file.
Steps:
-
Navigate to the Google API console
-
Create a new Google Cloud project or select an existing one.
-
Click on "OAuth consent screen", located in the navigation menu on the left of the screen
-
Go through the creation process and select the following:
- User Type - External
- Add authorised domain (use the same value as the
API_DOMAIN_NAMEenvironment variable) - Scopes: email, profile, openid
- No need to add test users
-
Once consent screen is created, go to "Credentials", which is just above the "OAuth consent screen" button from earlier.
- Click on: Create credentials > OAuth client ID
- Application type: Web application
- Add the following Authorised redirect URIs:
- http://localhost:4200/login
- https://localhost:4200/login
- http://
<API_DOMAIN_NAME>/login - https://
<API_DOMAIN_NAME>/login
-
You will now have a client ID to use as the value for the
GOOGLE_OAUTH_CLIENT_IDenvironment variable.
Enabling UFW with Docker:
https://stackoverflow.com/a/58098930
sudo ufw enable
shutdown -r now
# Add UFW rules to allow ports 22, 80, 443, and allow/deny other ports to your liking, e.g:
# ufw allow from <IP address> to any port <port number>
# Ports not specified in any rule are blocked by default.
sudo ufw allow proto tcp from any to any port 80,443
sudo ufw allow http
sudo ufw allow https
sudo ufw allow ssh