Installing JIRA from scratch, Part 1, Database Install and Setup

When I was leaving VMware, I discovered something interesting. My junior admin – who, in two weeks, would be the senior admin – had never done an install of JIRA from scratch.

Obviously, this would not do. Over the next two weeks, we did several intensive training sessions, where I’d do an install why he took notes. Eventually we tested the new docs by having him do the install solo while I watched. He passed -with some tweaks to the documents.

Looking online, there just isn’t to many details on how to do an install from front to back. Yeah, all the pieces are there, but it’s up to a new admin to put them together – which if you’ve never done it before, can be daunting. But I intend to fix that, starting here.

My original idea for this article was to do it from the ground up. That is, setting up the VM, installing the OS, installing the prereqs, configuring the DB, installing JIRA and then the proxy. Upon reflection, I think it’s safe to assume a few things. First, you know how to setup a VM and install an OS…or at least, you know who to ask. Second, you don’t need 100% hand holding. So I will be scaling this article back some. If you are interested in how I go about setting up my VM’s and linux installs, let me know in the comments and I’ll write up that article.

OS Selection

Though I’m assuming you know how to install an OS, there is a myth that I see often: that you must run JIRA on Linux. Let me squash this right now.


My advice is to use what you know. You don’t know linux but you can run a windows server? Use that! You want to run it on a Mac in the corner? Well…that might actually be an issue. It will run, but your support from Atlassian may not be there.

I’m not saying you can ignore the supported platforms document. You should double check with your choices here. But I am saying when your choices are as varied as they are in the doc, you have options.

To me, it is much more important you be familiar and comfortable with the operating system than following the crowd. Java, by it’s design, will take care of making sure it can run on your system. I started out as a Linux Admin, and can configure and tune Linux in my sleep. So I use what I know. But you don’t have to.

That being said, with only a few considerations, you can migrate an instance from one OS to another with minimal headaches. It’s not the easiest operation ever, but can be done well enough in a change window. Just something to keep in mind.

System Setup

Okay, now that we have that out of the way, I’m going to put down a few details about how the system is setup and what assumptions I am making.

JIRA System Specs

  • OS: CentOS 7 Linux
  • Database: Latest Supported MySQL (5.7 as of the writing of this article)
  • RAM: 4 GB
  • Processors: 2
  • Root Hard drive of 30 GB
  • Extra Hard drive of 50 GB to house the database and JIRA’s home directory

So a few things I want to note here. First off, I chose four gigabytes of ram for a reason. The way I like to break down a new system is like this: 2 GB (ish) for JIRA’s Heap memory, 1 GB of Ram for MySQL, and 1 for system resources. This usually gives you enough room to grow for a bit before it gets to be a problem.

Second, I like to keep a 2:1 ratio between GB of Ram and Processors. This isn’t listed anywhere as a best practice for VM’s, just something I’ve always done, and I’ve never had a cause for change the practice. When it does cause something to happen, I may re-evaluate the practice then.

Lastly, I like to keep the JIRA Home and Database on a separate drive from the system resources. This makes monitoring easier, as these will be the two directories that will grow the most as your JIRA instance matures. It’s strictly speaking not required, but I like to think it helps in the long run, even if it is more work up-front. For my system, I’ll have it mounted to /archive.

MySQL Database Setup

JIRA, at it’s heart, is a web based front end for the Database. This makes your database choice pretty important. As of this writing, JIRA supports the following database systems:

  • PostgreSQL 9.4, 9.5, and 9.6
  • MySQL 5.6 and 5.7
  • Oracle 12cR1
  • Microsoft SQL Server 2012, 2014, and 2016
  • Azure SQL

As with the OS Selection, it’s important to use what you know. I’ve used PostgreSQL and Microsoft SQL Server in systems before, but I’ve developed queries and databases for – as well as ran and tuned as a system – MySQL. Therefore, outside of concerns for performance, I’ll use what I know best.

Slow down there!

Take a moment and think not only about the system as you currently envision it, but as you will use it years down the road. Unlike OS Selection, JIRA is very much a pain to migrate from one Database to another, requiring you to do an XML export and import on an entirely new instance on the new DB system. It may get to the point before you realize it that it becomes wholly impractical to do so.

As such, consider where you see this instance in 3 years. If you plan for this to be used by a lot of people simultaneously, PostgreSQL might be the way to go. There are use cases for Oracle, MS SQL Server, and Azure as well, all depending on how you want to use it. Now is the time to just take a second and think about it. Your future self will thank you.


While we are slowing down, there are a few documents we will need to check out.

The first document we’ll need is from MySQL. CentOS ships with MariaDB in it’s repos. Normally that’d be fine, and in some cases even preferred, but JIRA expressly doesn’t support MariaDB. As such, we’ll need to add the Yum repos for MySQL to our soon-to-be JIRA server.

Next, there’s Atlassian’s guide to setting up a MySQL database for use with JIRA. This will tell us what accounts to create, settings to set, and things to do to get MySQL running smoothly with JIRA.

These are mostly compatible with the settings you need for Confluence, Bitbucket, and Bamboo, so you can centralize the database if you so wish. However, that also introduces a huge single point of failure for your whole system, so I don’t really recommend it.

Yeah, but your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should

Dr. Ian Malcolm, Jurassic Park, 1993

Getting Started

To start with, we’ll need a way to manage yum repositories, so the first step should be to install yum-utils. This will come in handy in a few later steps, so might as well take care of it now. I will be running this as root via the esxi interface (I disable root from remote connections), but use sudo where you need to.

yum install yum-utils -y

As stated in the MySQL Document, we need to do is get the RPM for the MySQL Yum Repo onto the server. You can do this by downloading it to your local system and transferring it via scp/sftp/ftp/séance with the dead. But why. I prefer to get the link to the actual RPM (may take a couple of menus!), then use a utility called wget to retrieve it directly to the machine.


You are free to use the above command, but I can’t guarantee it will work forever, so I always suggest you double check that link against MySQL’s website and renew it as needed.

Now that we have it downloaded, we do a yum localinstall against it. This will setup Yum to have the MySQL repo.

yum localinstall ./mysql80-community-release-el7-3.noarch.rpm

So now we have the Yum Repository for MySQL installed, but we still have a problem. MySQL will default to the latest available (MySQL 8) unless we tell it otherwise. As such, we first need to see what is enabled and not. To do so, we’ll use the following command:

yum repolist all | grep mysql

We should see the following output:

Here we see three repos enabled.

  • mysql-connectors-community/x86_64
  • mysql-tools-community/x86_64
  • mysql80-community/x86/64

To disable this and enable mysql57-community, we run the following two commands, in order

yum-config-manager --disable mysql80-community
yum-config-manager --enable mysql57-community

After you run these, re-run the yum repolist command to confirm the correct repo is enabled:

Main Event Time

Install the mysql-community-server and all it’s prerequisites with the following command:

yum install mysql-community-server -y

I know this seems anticlimactic considering how much you have to do to just get here. But that is one of the beautiful things here – it’s mostly automated. The install will take a second, but not terribly long in the grand scheme of things. Once done, start the MySQL server with the command below.

systemctl start mysqld

Wait a few seconds, then query the log for the temporary password. You’ll need it here in just a second, so might as well grab it.

grep 'temporary password' /var/log/mysqld.log

Take this password and run the command:


This is a script that will guide you through locking down your MySQL instance. You will need the temporary password we just got, but you will get a chance to setup a proper root password. Please be sure to set your MySQL root password to something unique and complex. You don’t want to be the one to be hacked because your DB root password was the same as your user password.

For the rest of the questions on this script, select Yes. This is just a fast way to do all the good hygiene stuff you should do when you make a new MySQL DB.

From here, we can run one more command to make sure MySQL comes up as part of the system’s boot sequence, and we are ready to start configuring the Database for JIRA.

systemctl enable mysqld.

JIRA’fying this DB

Here’s where we’ll start following the Atlassian Document I referenced earlier. Log into the machine, either via a console or ssh, and connect to MySQL using the following:

mysql -u root -p

Here you will use the Database Root password you just set within the Secure Install script. Here we’ll run a number of queries to setup the database and user JIRA will connect through.


Yes, you do need to set it up as utf8mb4 with a collation of utf8mb4_bin. Not using these will cause JIRA to throw errors, and in some cases fail altogether. This will setup the Database with MySQL. Note that there is no requirement to call the DB “jiradb”. You are free to use any name here, though I’d recommend you use one that is readily identifiable.

Next, we’ll setup the user using this next two queries.

flush privileges;

In the GRANT statement above, we’ll replace the following as such:

  • <JIRADB> is whatever you named the database above
  • <USERNAME> is the username JIRA will use to connect to the DB
  • <JIRA_SERVER_HOSTNAME> to the name of the JIRA server (localhost in our case)
  • <PASSWORD> to the password JIRA will connect with

It’s important to security that the JIRA password be different from the root password. Don’t be that guy. Please do not be that guy.

After this, we are safe to exit MySQL (run the query ‘exit;’), and make some changes to the MySQL configuration file. This one…is very poorly named, considering history, but you can find it at /etc/my.cnf.

Yes, poorly named….

Anyways, it will ask you to make a number of changes. For the sake of brevity, I will include a copy of the config file that shall not be said aloud:




#<---- Start JIRA Specific Settings ---->
#<---- End JIRA Specific Settings ---->

Note that I’ve changed the datadir to the /archive mount I mentioned before. Not necessary, but I still feel it will be beneficial long-term. Just a note, if you also intend to move the datadir in your MySQL install, and you are running on CentOS or REHL, you will need to adjust a few Selinux policies. Just run the following commands:

yum install policycoreutils-python -y
semanage fcontext -a -t mysqld_db_t "<new_datadir>(/.*)?"
restorecon -R <new_datadir>

Edit: Future Rodney stepping in here. It seems I missed recording a few steps, so I wanted to add them.

First, if you are moving the datadir in the mysql config file, you will also need to move the physical files as well. You can do so with the following command:

rsync -av /var/lib/mysql <new_datadir>

Second, after making any changes to the MySQL config file, be sure to restart MySQL with the following. Be sure you do the file move first, as well as the Selinux policy step if you are on RHEL/CentOS.

systemctl restart mysqld

Now returning you to your regularly scheduled blog post.

And there we are!

We’ve now setup a database and configured it for Linux. I think we are going to call it here (wow this one is long) and move on to installing JIRA next week. I also have a crazy plan to see if I can install this on a Raspberry Pi 4…while not supported, I do think it *might* be possible! Of course if I do achieve that, I’ll write up a how-to on that one as well! Until then, I’m Rodney, asking “Have you updated your JIRA issues today?”

Advanced Monitoring of JIRA

Note from the future: I’ve actually written a much better article on this you can find here: Monitoring JIRA for Health and Fun. You will find much better information there. I’m leaving this up as a testament to the past, but figured I’d save you the work.

So, confession time. I am a sucker for data. I love seeing real time graphs of system stats, performance, events, etc.

And this is just Minecraft….

So when I saw the following blog post being shared on reddit, it was a no brainer.

Jira active monitoring 24/7 with Prometheus + Grafana

It was a great read and a great guide. I chose to set up Prometheus in a docker container as all my other monitoring tools are there, but aside from that his guide was spot on, and I encourage everyone to read it.


It didn’t quiet go far enough, in my mind. I could get a ton of stats that I couldn’t get before: licensed user count, logged in user count, attachments storage size. But without being able to tie it to what the underlying system was doing it just felt…incomplete. I mean it’s great you can tell you have 250 users logged in, but is that what’s really causing the lag in the system?

Luckily I had another tool in my toolbelt. I had previously setup Grafana and InfluxDB/Telegraf for use on other systems. It was merely a matter of setting up telegraf on the JIRA server, and start pumping in the required data that way.

To see how to install InfluxDB and Grafana via docker, I’d first suggest following this guide from a fellow homelabber:

My JIRA system runs on CentOS, so my first step in getting JIRA’s server info was to get the InfluxDB added to yum. To do so, I executed the following command:

cat <<EOF | sudo tee /etc/yum.repos.d/influxdb.repo
name = InfluxDB Repository - RHEL 
baseurl =
enabled = 1
gpgcheck = 1
gpgkey =

After this, it was a simple thing to do a yum install, and boom, I had telegraf on the system. As a matter of disclosure, I did look that up here, it’s not like I just knew it.

After installing it, I did need to configure it so that it would gather and send the stats I was interested in to InfluxDB. To do so, I took a backup of the default config file (found at /etc/telegraf/telegraf.conf), then replaced the original with my own generic config file for Linux systems:

  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "10s"
  flush_jitter = "0s"
  precision = ""
  debug = false
  quiet = false
  logfile = "/var/log/telegraf/telegraf.log"
  hostname = "<<system host name, optional>>"
  omit_hostname = false
  urls = ["<<url to your influxdb server>>"]
  username = "<<influxdb user>>"
  password = "<<influxdb password>>"
  percpu = true
  totalcpu = true
  collect_cpu_time = false
  report_active = false
  ignore_fs = ["tmpfs", "devtmpfs", "devfs", "overlay", "aufs", "squashfs"]

Then it was a matter of starting Telegraf, confirm in the logs that it was sending, and then start work in Grafana. After working the data a bit, I got the following dashboard:

::wipes up drool::

Now, this is still very much a work in progress. For one thing, the orange line is supposed to be the max java heap, and unless I stop JIRA and change it – I don’t think it’s supposed to change. And those gaps aren’t me restarting JIRA, so it should have been constant. (proxy problems, ammirite?)

The particularly tricky one to do is the CPU Graph and guage. Telegraf will breakdown CPU usage into io_wait, user, system, etc. To be fair, this is how it’s recorded to Linux internally, but to get a unified number, I had to take the idle time on the CPU, multiply it by -1, then subtract it from 100.

The second gotcha is under to options tab of the single stat block. It will always default to give you an average – which at times you will want. But in most cases will give you weird readings, like 0.4 users are currently logged in instead of one. To fix this, simply change it to read “Current”, as shown below.

So, you may be asking yourselves, why?

My first answer would be “Have you seen it! It’s just cool a.f.!”

But my second, more practical answer is incident detection and response. Just like in JIRA, Dashboards here give you and idea of whats going on now, as well as what’s been going on previously. You can even expand on this to tell if you are using swap, which could severely slow down a system. Or if you are out of memory for the JVM setting you have. Or you don’t have enough CPU power to process all the requests. And you can tell all this at a glance. You can even have this posted on a monitor on the wall so everyone can see it in real time.

My Brain at the moment….

So this post is a bit short…

I just got back home yesterday from a last minute trip I had to take. I knew I’d want to update the blog, but honestly couldn’t think of what to do it on. Luckily while I was gone I had worked on this as a distraction, so here we are. But this is a tool I wish I had one some of my previous engagements, and figured some of you might be able to use it as well. So, until next week, when I can hopefully complete part one of the Installing JIRA from scratch, this is Rodney, asking “Have you updated your JIRA issues today?”

My Favorite 3rd Party Plugins

Hey guys. I know it’s been a couple of weeks. I have been working on a large piece on installing JIRA front-to-back. Or pieces, as it were. That one is becoming a bit bigger than I thought It would be. I have most of the first piece done, but honestly I’m considering breaking it up even further.

So I’d figure I’d put up a quick article here in the meantime. It basically came to me like this: As I’m on an interview, there is one question that will let me know immediately whether a company is new to JIRA or seasoned. That question, simply put, is “What plugins (or Apps) do you like?”

I’ve given interviews to those applying to be a JIRA Admin, and honestly, I didn’t think of this as a question. It’s on my list now, though. (Be warned, suckers!)

Now, I should mention caution here. You should never, *ever*, use a plugin to replace something JIRA can do by default. Yes, they do exist. Also, you should be weary about overloading a JIRA instance with plugins. The more you have, the more memory the JVM will need, and the more system resources you need. And you can (and will) get to a critical point where the system becomes unusable because of too many plugins.

As such, I always recommend testing all plugins for a few weeks in a pre-production environment with as real a data set as your policies will let you have. Also have the requesting party test it to make sure it actually meets their needs. This will usually catch a good bit of problems before they cause production downtime.

However, I figured I’d go through some of my favorite plugins, some of the absolute worst I’ve dealt with, and a few honorable mentions. These are in no particular order, just a list for your consideration

My Favorite Plugins

Automation for JIRA

So, I’m sure everyone is familiar with Scriptrunner, the groovy powered everything plugin. You either love it or you hate it. Well meet it’s easier to use younger brother: Automation for JIRA. This is a tool that uses a code-less, drag and drop style editor to build a script that runs on a specified event. It very much has a “IFTTT” feel to it. It has become my new favorite way to automate subtask creation. And get this, you can set this up per project. I mean, if you trust your project admins enough, you can even train them to use it to create their own use cases. I did say “if”, though.


  • Code-less
  • Configurations can be set up at a per project basis
  • can be set up to allow Project Admins to create automations that impact only their projects
  • Plenty of ability to use information from the triggering issue


  • Not as flexible or powerful as Scriptrunner
  • It is possible to create automations that bog down the entire instance
  • Can be blind to field changes that happen during a transition

Link: Automation for JIRA

Timetracker – Time Tracking and Reporting

So I discovered this one fairly recently. The problem I was trying to solve was this:

We had some customers we were billing per hour. The SoP was to have users enter their time in JIRA. However, we really did lack a good way to report and utilize that data once it was in JIRA. Thus comes in the hero of the Hero of the Hour: Timetracker.

Simply put, this changes how time is entered against tickets, and allows project leads and managers to then pull reports on this data. It even has some dashboard gadgets to have near real-time reporting on time tracking data.


  • Makes entering time against a ticket or issue really easy.
  • Allows reporting on the time data already stored within JIRA


  • You are going to have to deal with “Police State” claims…
  • If you have any change inertia in your org, it may be hard to get people to adopt because “it changes how I do things”.

Link: Timetracker


I mentioned it’s little brother before, so now it’s time for the big guy himself. The self-described “Everything” Plugin. Scriptrunner. If you know groovy, and you have an idea, this can do it. I think my favorite use case I’ve seen to date was using this to copy contents from one field to another, per issue, so that we could change a field type within the UI.

Now my Groovy skills….yeah, it’s not my strongest language. I really struggle writing groovy scripts for Scriptrunner. However, even a newb such as myself can find use in the built-in scripts. As an example, we setup a project configured exactly as we wanted it. Default groups assigned, permission, field, and screen schemes all the way we wanted them, etc. Then we’d use the “Copy Project” function within Scriptrunner to copy this “Gold Standard” when we had a request for a new project. Afterwords, we’d have to just take care of any customization related to other 3rd party plugins, and we’d be good to go. Turned a half-day affair into a button press.


  • If you can code it, it can literally do anything….
  • Built-in functionality for those of us who are groovy-impaired
  • can schedule tasks to run regularly if needed.


  • Does allow fairly low level access
  • An admin that has no clue what they are doing can do a lot of damage
  • Can be tricky to learn.

Link: Scriptrunner

Project Configurator

This is my secret weapon as an Admin. Not only does it allow me to play around with a configuration in test, and only move it to production when it’s ready, but it also allows me to move a project, group of projects, or in some cases even an entire JIRA instance, into another one. And I mean both Issues and Configurations.

I’ve used this one many many times in the past. It is absolutely one of my all time favorite add-ons to JIRA. Now, to be fair, if you are moving a large project, it can take a while. My personal record is a project with 60K issues, which took around 12 hours in total. And that was on top-of-the-line hardware you aren’t likely to find at just any company. But it worked, and that is what really matters.


  • Move configurations from instance to instance, great for testing changes before installing them in production
  • Can move issues with projects, making this invaluable for merging and migrating instances


  • Migrating issues can be SSSLLLLOOOOOWWWWW…..
  • Can be finicky at the best of times, even more so if the JIRA versions don’t match. However, so long as the major variables and settings don’t change, success is repeatable.

Link: Project Configurator

Honorable Mentions

Now, these are still great plugins, but I’ve moved away from them for one of two reasons: Either JIRA has taken up the functionality they served natively, or I found a better plugin for it. They are still great plugins, and I still wholly recommend them.

JIRA Misc Workflow Extentions

Misc Workflow Extensions, as the name implies, allows you to extend what you can do within a workflow. It adds a number of Conditions, Validators, and post functions that let you manipulate the issue in-transition.

My main use-case for it was reassigning an issue on the fly. I’m aware you can now do this with vanilla JIRA. If I’m being honest, I missed that mention in the release notes, but it’s a welcome addition to the built-in functionality. But it did make my use of this plugin…what’s the word? Redundant.

Link: JIRA Misc Workflow Extensions

JSU Automation Suite for JIRA Workflows (Formally Jira Suite Utilities)

Aside from that, my use case was auto-generating sub tasks on issue creation. That being said, it was a bit clunky, with you having to format the creation string *just* right to get it to work. I can now do the same thing with Automation for JIRA with a lot less fussing around. For that reason, that is why this is only an honorable mention

This is another one that can do many things, but I was using it for one feature in particular. I know, maybe not the best practice, but here we are anyways.

Link: JSU Automation Suite for JIRA Workflows

How bad can it be?

These plugins here are ones that when possible, I want to immediately uninstall. This is for a number of reasons, to performance issue in JIRA, to plain violating what a Plugin should be. As with my recommendations, I’ll list what’s great and not-so-great about each of these.

Field Security Plugin for JIRA

On the surface, this one provides a pretty valuable functionality. It gives you the ability to define a scheme, in which you can specify who can see or edit a given field. You can even hide the content in the field from a specific group. No joke, this is among my top asks from Atlassian. So why is it on the naughty list?

Well, to be frank, to do this it has to do more than a mere plugin can do. As such, you are provided a zip file that you install in the JIRA installation directory to replace key files with their own version.

Yes, they modify files in JIRA to do what they need. Now I’ve used this for a number of years (against my will), and only had one issue – when I learned you had to replace those files on an upgrade. The issue, oddly enough, was the Pie Chart gadget stopped working. O_o Yeah, that doesn’t make much sense to me, but there we were, Monday after a weekend upgrade, with a line at my desk.


  • Can help you control sensitive information in JIRA.
  • Gives options on a per user or per group basis
  • Relatively easy in-service configuration after install.


  • Hiding information doesn’t really lend itself to an “open” culture…
  • Settings do not copy with project configs if you are using Scriptrunner to copy projects.
  • Because you are modifying JIRA files, this is not available for JIRA Cloud.
  • Modifying files within the install directory can invalidate your support agreement with Atlassian, meaning when you need help the most you may not have it. Did I forget to mention that? Well now you know.

To be fair, on that last point, I’ve never been called out and denied support from Atlassian for running this plugin. That being said, I have been warned about it several times, so figured I’d pass that warning along.

Link: Field Security for JIRA

WBS Gantt-Chart for JIRA

If I am being honest, this plugin is passible. I like the idea of the Work Breakdown System. My gripe with this is just how many fields it creates for you. I know, they need these fields to work, but they don’t check if the fields already exist. This means if you have to uninstall it and reinstall it for some reason, it will create duplicates of these fields, again *for you*…

That being said, it does do what it does well, so that may be an okay trade-off for some.

My recommendation is usually to go with Portfolio for this functionality. It uses the data already in JIRA to create charts for you, without needing to many extra fields. It will even help you with scheduling work and finding the critical path. But to each, their own, so if this is your thing, go for it.


  • It does what it does well.
  • Is a lot more intuitive for end users that Portfolio for JIRA


  • So many fields…
  • Can be slow to load for a large number of issues.
  • Did I mention the fields…yeah, this one might just be down to personal preference….But I’m willing to admit that.

Link: WBS Gantt-Chart for JIRA

In reflection…

These, ultimately come down to my own preferences and experiences as an Admin. You may disagree and love some plugins I hate. That’s fine. You may loath some plugins that I absolutely love. That’s also fine. However, I do want this to be a conversation. What plugins do you like? What are your plugin horror stories? Anything humorous happen around a plugin install? Definitely leave your stories down below, I’d love to hear them. So, Until next time, have you updated your JIRA issues today?