Deploying Jira and Confluence on Docker with an External Database
This guide shows how to run Jira Software and Confluence in Docker with persistent storage and a production-ready external database. Use an official evaluation or purchased license from Atlassian during setup; this article does not cover bypassing licensing.
Prerequisites
- Docker and Docker Compose installed
- Outbound internet access to pull images
- MySQL 8.0+/MariaDB 10.5+ or PostgreSQL 12+ available (examples below use MySQL)
- Jira and Confluence evaluation or commercial licenses from Atlassian
Preparing the Database (MySQL/MariaDB)
Create databases and users with UTF-8 MB4 settings and the correct transaction isolation level.
-- Jira database and user
CREATE DATABASE jiradb CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE USER 'jiraapp'@'%' IDENTIFIED BY 'Str0ngP@ss_jira';
GRANT ALL PRIVILEGES ON jiradb.* TO 'jiraapp'@'%';
-- Confluence database and user
CREATE DATABASE confdb CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE USER 'confapp'@'%' IDENTIFIED BY 'Str0ngP@ss_conf';
GRANT ALL PRIVILEGES ON confdb.* TO 'confapp'@'%';
-- Ensure transaction isolation is READ-COMMITTED
-- MySQL 8+ uses `transaction_isolation`; older versions may use `tx_isolation`
SET GLOBAL transaction_isolation='READ-COMMITTED';
If you use MySQL as a container, you can enforce charset and isolation at startup:
# docker-compose fragment for MySQL
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
command:
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_bin"
- "--transaction-isolation=READ-COMMITTED"
- "--default-time-zone=+08:00"
ports:
- "3306:3306"
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
PostgreSQL alternative (optional):
-- Jira
CREATE ROLE jiraapp WITH LOGIN PASSWORD 'Str0ngP@ss_jira';
CREATE DATABASE jiradb OWNER jiraapp ENCODING 'UTF8';
-- Confluence
CREATE ROLE confapp WITH LOGIN PASSWORD 'Str0ngP@ss_conf';
CREATE DATABASE confdb OWNER confapp ENCODING 'UTF8';
Running Jira in Docker
Below is a Compose setup that runs Jira Software and persists its home directory. If you use MySQL, download MySQL Connector/J (e.g., 8.3.x) and mount it into the container so Jira can connect to MySQL.
version: "3.9"
services:
jira:
image: atlassian/jira-software:9.12.2
container_name: jira
ports:
- "18009:8080" # host:container
environment:
- TZ=Asia/Shanghai
volumes:
- ./jira-home:/var/atlassian/jira
# Optional: MySQL JDBC driver mount (adjust filename to your driver)
- ./drivers/mysql-connector-j-8.3.0.jar:/opt/atlassian/jira/lib/mysql-connector-j-8.3.0.jar:ro
restart: unless-stopped
Start Jira:
docker compose up -d jira
Open http://:18009 and follow the setup wizard:
- Choose "Set it up for me" or "I’ll set it up myself"
- Select the external database option and pick MySQL (or PostgreSQL)
- Use these JDBC URL patterns:
- MySQL: jdbc:mysql://:3306/jiradb?useUnicode=true&characterEncoding=utf8mb4
- PostgreSQL: jdbc:postgresql://:5432/jiradb
- Anter the DB user/password created earlier
- Provide your valid Atlassian license key when prompted
Running Confluence in Docker
Similar to Jira, Confluence persists its home directory and may need a JDBC driver for MySQL. You can run it alongside Jira.
version: "3.9"
services:
confluence:
image: atlassian/confluence-server:7.19.17
container_name: confluence
ports:
- "18010:8090"
environment:
- TZ=Asia/Shanghai
volumes:
- ./confluence-home:/var/atlassian/confluence
# Optional: MySQL JDBC driver mount (adjust filename to your driver)
- ./drivers/mysql-connector-j-8.3.0.jar:/opt/atlassian/confluence/confluence/WEB-INF/lib/mysql-connector-j-8.3.0.jar:ro
restart: unless-stopped
Start Confluence:
docker compose up -d confluence
Open http://:18010 and complete the setup wizard:
- Select "Production Installation"
- Database connection settings:
- MySQL: jdbc:mysql://:3306/confdb?useUnicode=true&characterEncoding=utf8mb4
- PostgreSQL: jdbc:postgresql://:5432/confdb
- Enter DB credentials created earlier
- Apply a valid Confluence license key
Optional integration with Jira for user management:
- In Confluence, go to User Management and add an external directory
- Chooose "Atlassian Jira" and supply the Jira base URL and application link credentials
Single-Node Docker Run Alternatives
If you prefer plain docker run:
# Jira
docker run -d \
--name jira \
-p 18009:8080 \
-e TZ=Asia/Shanghai \
-v $(pwd)/jira-home:/var/atlassian/jira \
-v $(pwd)/drivers/mysql-connector-j-8.3.0.jar:/opt/atlassian/jira/lib/mysql-connector-j-8.3.0.jar:ro \
--restart unless-stopped \
atlassian/jira-software:9.12.2
# Confluence
docker run -d \
--name confluence \
-p 18010:8090 \
-e TZ=Asia/Shanghai \
-v $(pwd)/confluence-home:/var/atlassian/confluence \
-v $(pwd)/drivers/mysql-connector-j-8.3.0.jar:/opt/atlassian/confluence/confluence/WEB-INF/lib/mysql-connector-j-8.3.0.jar:ro \
--restart unless-stopped \
atlassian/confluence-server:7.19.17
Fixing Garbled Characters (Chinese and Other Unicode)
If you see mojibake in Confluence, ensure both the DB and JDBC connection string use UTF-8 MB4. For MySQL:
- Database should be utf8mb4/utf8mb4_bin
- JDBC URL should include both useUnicode=true and characterEncoding=utf8mb4
In Confluance’s confluence.cfg.xml, the URL must escape ampersands for XML:
<property name="hibernate.connection.url">
jdbc:mysql://db.example.internal:3306/confdb?useUnicode=true&characterEncoding=utf8mb4
</property>
If Jira requires manual edits, the database URL is typically stored in dbconfig.xml inside the Jira home directory with a similar JDBC URL. Restart the container after making changes.
Notes on Database Drivers and Compatibility
- When using MySQL, ensure MySQL Connector/J 8.0+ is available to the application. Place the JAR in:
- Jira: /opt/atlassian/jira/lib/
- Confluence: /opt/atlassian/confluence/confluence/WEB-INF/lib/
- For PostgreSQL, the driver is usuallly bundled; verify compatibility with your product version
- Always consult the supported platforms matrix for your Jira/Confluence version and DB engine
Optional: Nginx Reverse Proxy
To serve clean hostnames with TLS, place Nginx in front of the containers:
server {
listen 80;
server_name jira.example.com;
location / {
proxy_pass http://127.0.0.1:18009;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name confluence.example.com;
location / {
proxy_pass http://127.0.0.1:18010;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}