How I made Docker linter for IntelliJ IDEA (and other JetBrains IDE)


This article originally published on my personal website, protsenko.dev.
TL;DR In this article, I’m sharing my experience creating an IDE plugin as a pet project. I developed the plugin to help find security and maintainability issues in Docker files and perfectly integrated it into JetBrains IDEs.
I’ve had an idea to create a powerful plugin for making Infrastructure as Code (IaC) files more secure and reliable. IaC files define infrastructure through code, such as Dockerfiles or Kubernetes configurations. I developed this idea because I’m passionate about Security, DevOps, and Development. Another reason was to create something I could promote, gaining experience managing and promoting an open-source project.
My challenge was creating a project independently from scratch and publishing it to the JetBrains marketplace. I act as an open-source developer and work on it in my free time, generally on vacations or weekends.
Kicking off the development
The IntelliJ platform is awesome. One of its features, PSI (Program Structure Interface), provides developers with a powerful tool to analyze code. Creating inspections is a great way to improve your coding skills and deepen your knowledge of specific technologies. For me, it was Docker (Dockerfile and docker-compose files).
I used the Docker plugin as a required dependency because it provides language support for Dockerfile. However, it would be better if basic support for standard formats were integrated into the platform rather than relying on a plugin that might not be installed in a user’s IDE.
Creating inspections can be challenging because you must:
Deeply understand what problem should be covered with the inspection.
How it could be analyzed and highlighted.
How to implement it properly.
Need to write tests to make sure it works as expected.
Overcoming these challenges provides valuable experience in writing high-quality software because it involves key areas such as researching, planning, developing, and testing.
Researching problems & planning
I researched the security of Dockerfile and docker-compose files to create effective inspections that could help developers and SRE engineers improve their files.
As a source for my research, I googled extensively and analyzed open-source software that already provides similar checks, such as Trivy and Hadolint. Additionally, one of the essential resources I bookmarked is the Docker documentation, which perfectly describes Dockerfile commands and their purposes.
To define the rulesets I should implement, I studied the previously mentioned tools, Trivy and Hadolint, diving deep into their rule definitions. I’ve implemented checks from Trivy and already covered a significant portion of Hadolint’s rules.
Learning about rules, problems, and file structures isn’t limited to a single research source. One of the most significant shifts in my implementation vision came from reading GitHub issues for Hadolint. That project seems abandoned and has several missing features or unresolved bugs.
Understanding users’ pain points through these issues provided valuable guidance. By following them, I identified many ways to improve my solution. For example, Hadolint couldn’t track an image version declared as a variable, but my solution resolves the variable to the correct version and verifies its content.
Knowing users’ pain points is crucial for creating good software. If someone spends time reporting an issue on GitHub, it indicates they’ve encountered a real problem. Therefore, you should consider user feedback and software improvement, especially when similar projects have unresolved issues.
After researching, you’ll have a list of problems your solution should address. It’s important to focus on multiple problems rather than just one. You should have a clear vision of your product: how it will be positioned, which pain points it should solve, and an overall understanding of its purpose.
The Python Security plugin genuinely inspired my vision and solution. I wanted to address problems and help developers similarly. With over 150k downloads, I saw an opportunity to create a security-focused plugin targeting a different technology stack.
Summary:
Before creating something, do careful research.
If you’re developing inspections, and be aware that many corner cases could arise.
If you have open-source competitors. Read their issues and user feedback to avoid repeating the same mistakes.
Develop a strong vision of your product, plan what needs to be implemented, and execute it better than competitors.
Find products that inspire you, understand how they solve problems, and use this knowledge to enhance your implementation.
Development & testing
After detailed work on your research and planning the features you want to implement, the obvious next step is development. Using IntelliJ Community Edition makes the process challenging because the Ultimate Edition offers many features that increase productivity. One of my favorite features is Full Line Code Completion, available only in the Ultimate Edition. I really enjoy how this feature generates code on the fly on my machine; without it, you have to write code the classical way.
The development stage was similar to others I’ve experienced during my past eight years as a developer. I’d select a task (a rule) and implement it. Step by step, my codebase grew, and complexity increased. I performed two or three major refactorings during this process to simplify and unify my solutions.
While working on inspections, I encountered new insights and technical issues that needed solving. Carefully reading the platform documentation solved about 70% of my problems, reading the source code resolved another 10%, and googling combined with AI handled the remaining 20%. The documentation is of high quality and greatly helped me throughout my journey.
One of my most important lessons was that unit tests are essential. I wrote many test cases to cover my inspections and ensure everything worked correctly. This significantly increased my development speed and protected me from technical debt.
However, tests did not catch some issues, such as compatibility problems with different IDE versions. Initially, I adapted my plugin for version 233 and newer.
I practiced TDD, developed inspections based on test feedback, and performed manual testing on the targeted IDE version (233). However, I was quite surprised when I installed the plugin on the latest IDE version and saw that my highlighting blinked or disappeared occasionally.
Newer versions of the IntelliJ Platform had changed their approach to visiting PSI elements, which caused my code to stop working correctly. As a result, I needed to adjust my solution to remain compatible with future updates.
One effective way to verify a solution is to record a video demo of how it works. When you record or present your solution, you clearly observe how the plugin behaves and notice any problems that occur during its usage.
For me, it was:
Blinking inspections while you create working on the supported files.
Invalid order of highlighted problems on one line that makes problem prioritization harder.
Errors that happen during using invalid threads.
Complex inspection descriptions.
While fixing issues and publishing new versions to the plugin marketplace, new problems emerged. For example, supporting a wide range of IDE versions is difficult, and the Plugin Verifier clearly points this out. The Plugin Verifier is a useful marketplace feature that helps you identify which IDE versions will be correctly supported and what issues might arise.
Some inspections are occasionally boring to implement because they require text analysis. Text analysis is one of the most boring tasks I’ve encountered, and I solved this by combining regular expressions with AI assistance.
I created an interface representing a validator with clear documentation to guide the AI in generating accurate and valid regular expressions. Additionally, AI was forced to write many unit tests to ensure the generated validators work correctly.
I used AI for several tasks, including creating validators, refining inspection messages, and partially for documentation. AI significantly boosts productivity, and I took advantage of this using the ChatGPT 1o model. Although IntelliJ offers an AI Assistant, I was limited by working in the Community Edition without a subscription to Assistant. I tried requesting a license for open-source projects but received no response.
Another interesting insight: running tests on my Windows gaming laptop took about 12 seconds. On the same machine under Manjaro Linux, it took around 8 seconds, and on my girlfriend’s MacBook Air M2, it took nearly 5 seconds. That’s a big difference in performance.
Summary:
Write extensive tests to ensure everything works as expected.
Always perform manual testing on your targeted IDE and the latest versions.
Supporting a wide range of IDE versions can be challenging.
Dogfood your product to discover areas for improvement.
If you encounter issues with your solution, revisit the platform documentation.
Don’t hesitate to use AI for routine tasks.
IntelliJ IDEA Ultimate offers effective tools to increase productivity.
At the end
Developing plugins was even more exciting and challenging than I initially thought. But that’s exactly what keeps me constantly working on my project. Creating inspections is a great way to explore a specific area of the IDE and improve your expertise in a particular technology. For me, that technology was Docker. Understanding why something is considered a problem and how it can lead to errors or vulnerabilities helped me start seeing things from different angles.
Since October 2024, the plugin has been downloaded over 1600 times. Month by month, the number of monthly downloads has been rising, especially since I often publish new versions of the plugins.
After first publishing the plugin to the marketplace, I got almost 40 downloads, which motivated me to continue working on newer versions. I documented all the highlighted problems carefully, optimized the plugin’s description, and improved its SEO. If you search the marketplace plugin with name security, it will be on the first page of the results, which means a lot to me.
It was a long way from an idea to a working product. I’ve gained much experience and strength in my tech skills and knowledge about different aspects of our platform. Also, I’ve got many insights into making products and how to maintain them properly.
I don’t know about the future of my pet project because to continue working on it — I need more users that share their feedback or contribute to the open-source project. A solid user base is crucial for open-source products because you shouldn’t do only for you; you should make products for users.
I’ve stopped actively working on it, sometimes fixing something I received from user feedback. It’s time to focus on different projects.
Thanks to everyone who is reading it; share your feedback, star the repository, and, of course, give it a try to plugin.
Subscribe to my newsletter
Read articles from Dmitry Protsenko directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
