How to Use Symlink in Tomcat to Preserve User Data During WAR File Deployment?

Introduction

At our company, we specialize in creating solutions that simplify complex processes and improve operational efficiency for our clients. By leveraging automation tools and modern practices, such as Symlink, we enable businesses to become more agile and scalable. Recently, we tackled a unique challenge faced by a client where their WAR file deployment process in Tomcat was accidentally deleting important user-uploaded data.

To fix this, we used a simple but effective method involving symlinks and Elastic File System (EFS). This ensured that user data was saved during deployments without needing to update the application’s code.

In this post, we’ll explain the problem, how we solved it using symlinks, and how this approach kept the data safe while making the deployment process smooth and reliable.

Problem Statement

In today’s fast-paced tech environment, companies need to deliver updates and features quickly while maintaining reliability. One of our clients faced unexpected issues during their application deployments in Tomcat. They were using a Lambda function to pull WAR files from S3 and deploy them to Tomcat. However, each time they deployed a new WAR file, the process deleted the user-uploaded data in the /opt/tomcat/webapps/<warfile_name>/upload/ directory.

This was a critical problem because the data in this directory was important for the application’s functionality, but the deployment process wiped it out every time. While the ideal solution was to store the data in a separate, persistent location, the client’s application code was hardcoded to use this specific path, making it difficult to modify.

The challenge was to find a way to keep the user data safe during deployments without requiring changes to the existing codebase, ensuring a seamless and reliable deployment process.

Our Solution

To solve this issue, we created a straightforward and effective solution that kept user-uploaded data safe during deployments without requiring any changes to the client’s application code.

Here’s what we did:

  1. Set Up Persistent Storage:
    We created an Amazon Elastic File System (EFS), which provides scalable and persistent storage. This was mounted on the Tomcat server at /var/upload.
  2. Used Symlinks to Bridge the Gap:
    Since the application code was already designed to use a specific path, we implemented a symlink to redirect this path to /var/upload. This ensured the data would be stored in the persistent location, without altering the application’s codebase.
  3. Configured Tomcat to Allow Symlinks:
    To allow Tomcat to follow the symlink, we updated the <Context> configuration in the Tomcat context.xml file.

    With this solution in place, the user data remained safe during each deployment, and the application continued using the same path as before. The symlink effectively redirected data storage to the persistent EFS, ensuring that user-uploaded data was retained even after new WAR files were deployed.

Implementation

To implement the solution of using Amazon EFS and symlinks, we followed these detailed steps:

Step 1: Create and Set Up Amazon EFS

  1. Create an EFS File System:
    • Go to the AWS Management Console.
    • Navigate to EFS and click Create File System.
    • Follow the prompts to create a file system and ensure it is accessible from the same VPC as your Tomcat server.
  2. Add Mount Targets:
    • Configure mount targets for the subnets where your EC2 instances (Tomcat server) are running.
  3. Install NFS Utilities on the Server:
    • Log in to the Tomcat server.
    • Install the necessary NFS tools to mount EFS:
      sudo yum install -y nfs-utils
  4. Mount the EFS File System:
    • Use the following command to mount EFS to the desired directory (/var/upload):
      sudo mount -t nfs4 -o defaults fs-.efs..amazonaws.com:/ /var/upload
  5. Add a Persistent Mount (Optional):
    To ensure EFS is remounted after a reboot, add an entry to the fstab file:
    echo "fs-<efs-id>.efs.<region>.amazonaws.com:/ /var/upload nfs4 defaults,_netdev 0 0" | sudo tee -a /etc/fstab
    Test the configuration with:
    sudo mount -a

Step 2: Update the Deployment Script

Once EFS is set up, update the Lambda function that deploys the WAR file by adding these commands to create the symlink:

cd /opt/tomcat/webapps/<warfile_name> && rm -rf upload && ln -s /var/upload upload  

Here’s what happens:

  1. rm -rf upload: Removes the old upload directory created during WAR extraction to avoid conflicts.
  2. ln -s /var/upload upload: Creates a symlink to redirect operations from /opt/tomcat/webapps/<warfile_name>/upload/ to /var/upload.

Step 3: Update Tomcat Configuration

To enable symlink usage in Tomcat:

  1. Open the context.xml file located in the conf directory of your Tomcat installation or the specific context.xml file for your application.
  2. Add the following configuration under the <Context> element:
    <Resources allowLinking="true" cachingAllowed="true" cacheMaxSize="100000" />
  3. Save the file and restart Tomcat for the changes to take effect:
    sudo systemctl restart tomcat

This configuration ensures that Tomcat recognizes and follows the symlink without any additional changes.

Benefits

By using Amazon EFS and symlinks, we created a solution that not only addressed the immediate problem but also added long-term value to the client’s deployment process. Here’s how this approach helped:

  1. Data Persistence Across Deployments:
    User-uploaded files are now safely stored in a centralized and persistent EFS directory. Even when a new WAR file is deployed, the data remains intact.
  2. Seamless Integration with Existing Code:
    The symlink ensures that the application can continue to use the original path (/opt/tomcat/webapps/<warfile_name>/upload/) without any changes to the code. This saved significant development time and avoided introducing potential bugs.
  3. Improved Scalability and Flexibility:
    With EFS, the storage scales automatically based on the amount of data, eliminating the need for manual adjustments or concerns about running out of space.
  4. Simplified Maintenance:
    The setup reduces the complexity of managing deployments. The Lambda function handles everything—removing old directories, creating symlinks, and ensuring user data is preserved.
  5. Future-Proof Solution:
    The use of EFS makes it easier to share data across multiple servers or applications in the future, enhancing the overall infrastructure’s flexibility.

Conclusion

In conclusion, the solution of using Amazon EFS, symlinks, and updates to the Tomcat configuration significantly improved the deployment process for the client, addressing the critical issue of user data being lost during WAR file deployments. By integrating EFS for persistent storage, using symlinks to bridge the gap with the existing application code, and enabling symlink support through the Tomcat configuration, we ensured that user-uploaded data remained intact across multiple deployments.

This comprehensive approach streamlined the deployment process, reducing manual intervention and the potential for errors, leading to more reliable and efficient deployments. The client no longer had to worry about losing important user data, and their deployment pipeline became more scalable and future-ready.

Overall, this combination of solutions didn’t just solve a short-term issue—it empowered the client with a more resilient, flexible, and scalable system, allowing them to confidently handle growing demands and focus on delivering value to their users.

Thank you for Reading !! 🙌🏻😁📃, see you in the next blog.🤘

I hope this article proves beneficial to you. If you have any doubts or suggestions, feel free to mention them in the comment section below or contact us.

The end ✌🏻

References