How to migrate Bitbucket Server and Data Center to Docker container
Platform Notice: Data Center - This article applies to Atlassian products on the Data Center platform.
Note that this knowledge base article was created for the Data Center version of the product. Data Center knowledge base articles for non-Data Center-specific features may also work for Server versions of the product, however they have not been tested. Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Except Fisheye and Crucible
Summary
When migrating the Bitbucket Server and Data Center to the Docker containers, there are specific distinctive steps to take. Sometimes, the idea is not only to migrate Bitbucket to a containerized environment but also to upgrade it and add more nodes - converting a single-node setup to a multi-node containerized DC setup.
This article gives general recommendations and explains migrating from a stand-alone Bitbucket setup to a dockerized one.
Environment
7.21.10, but applies to other versions.
Solution
The General recommendations section below covers organizational aspects of migration, whereas the Procedure section explains technical aspects of the migration.
General recommendations
When planning a complex migration that involves many changes, like moving to Docker containers, upgrading it, and adding more nodes, it is crucial to go with a "one step at a time" principle. That means introducing only one change, testing it, and going to the next step if all is well. For example, when moving Bitbucket to containers, upgrading it, and adding more DC nodes, our recommendation is:
- Introduce a containerized Bitbucket while staying on the same version as before.
- Test it, and if all is well, go with an upgrade.
- Test the upgraded, containerized Bitbucket. Start planning and carrying out a multi-node setup if all is well again.
Using this principle, we would limit the number of changes to a strict minimum and avoid tangling many of them together. If we don't follow this principle, if anything goes wrong, we will not be sure what change caused the problem. For example, if we move to Docker containers and upgrade the version and the new server fails to start, it would be hard to tell if containerization made a problem or an upgrade went bad.
Of course, this can be even more complicated: imagine changing the SQL database, upgrading the search engine, and moving the setup to a different collocation facility. The more changes we introduce, the more it is important not to make more than one at a time!
Before any change, please ensure you have an up-to-date, complete, and consistent backup of your Bitbucket home directory, shared directory, and SQL database.
Backups of your Git repositories and SQL database must be in sync (consistent).
The procedure of migrating Bitbucket to a Docker container
The Official Bitbucket Docker Images page explains how to set up Bitbucket using Docker containers.
- You must convert the settings from the
bitbucket.properties
file to environment variables.
Please take a look at the page Binding From Environment Variables for detailed information on how to convert them. - To access existing data, you have to:
- Use JDBC_... Docker environment variables to point dockerized Bitbucket to use existing SQL database.
- Bind-mount existing
$BITBUCKET_HOME/shared
directory into/var/atlassian/application-data/bitbucket/shared
inside the Docker container.
- Don't share existing
$BITBUCKET_HOME
directory with dockerized Bitbucket. Technically, it can work, but it also can cause many problems if not done properly. - Ensure you have enough free disk space on the volume where Docker containers are installed. This volume will be used for
$BITBUCKET_HOME
and will also contain SCM caches that can be as large as your repositories. - Before further activity, make sure you have an up-to-date and consistent backup of your SQL and file-system data!
- Atlassian Bitbucket Docker containers are self-sufficient; they don't require installing Java or creating system users.
Directories and mounts
- The best practice for the
$BITBUCKET_HOME
location, according to the "Quick Start" section of the Official Atlassian Bitbucket Docker is to mount it from a host directory. As the same section states, when using a multi-node Bitbucket Data Center on Dockers, we must ensure that$BITBUCKET_HOME/shared
is properly mounted. With that in mind, it would be best to:- Allocate a new, empty directory for
$BITBUCKET_HOME
for dockerized Bitbucket on a host server, then mount it to a Docker container.It must be mounted to
/var/atlassian/application-data/bitbucket
inside the Docker container. - The shared data directory
$BITBUCKET_HOME/shared
should be mounted to the Docker container separately.It must be mounted to
/var/atlassian/application-data/bitbucket/shared
inside the Docker container. - If you later add more Bitbucket Data Center nodes, every one of them must have its own
$BITBUCKET_HOME
, but all of them must share the same$BITBUCKET_HOME/shared
directory.
- Allocate a new, empty directory for
- Bitbucket application inside the Docker container runs as
UID=2003
,GID=2003
, so we have to change ownership of all files inside$BITBUCKET_HOME/shared
to that UID-GID combination - use "chown -R 2003:2003"
command (without the quotes) over the directory on the host server.
If your old, standalone, and new, dockerized Bitbucket instances don't run on the same host server, you have had to copy the contents of the $BITBUCKET_HOME/shared
directory from the old server to the new one. You may even have to execute rsync
several times to bring the new copy up-to-date with the old one. When using rsync to copy the $BITBUCKET_HOME/shared
directory contents, always use the --delete
parameter to avoid Missing commits in Bitbucket after a filesystem migration.
The table below will give a better understanding of the Docker container directory mounts. It provides examples of paths when you have used rsync to copy data from an old, non-dockerized server to a new host server for dockerized Bitbucket installation.
Mind that directory paths are given only as examples.
- "Directory on old, non-dockerized server" is the directory from where you
rsync
-ed files to "Directory on the new host server for dockerized setup". - You can choose any directory path under "Directory on the new host server for dockerized setup".
- "Directory inside Docker container" is defined by the Bitbucket container itself and you can't change these.
Description | Directory on old, non-dockerized server | Directory on the new host server | Directory inside Docker container | Note |
---|---|---|---|---|
Bitbucket home | – | /var/dockerdata/bitbucket/node-1 | /var/atlassian/application-data/bitbucket | Bitbucket node 1 home directory. We are not re-using the home directory from the old setup. |
Shared data | /some/path/to/bitbucket/shared | /var/dockerdata/bitbucket/shared | /var/atlassian/application-data/bitbucket/shared | Data rsync -ed from the old server. |
With plain Docker command line utility, these mounts would be like this:
docker run -d \
--name bitbucket-1 \
...
...
-v /var/dockerdata/bitbucket/node-1:/var/atlassian/application-data/bitbucket \
-v /var/dockerdata/bitbucket/shared:/var/atlassian/application-data/bitbucket/shared \
...
...
In case you add one more Bitbucket node to the same host server, this is how the directory mounts for the second node would look like:
- "Shared data" would be the same for both nodes.
- "Bitbucket home" directories must be different.
Description | Directory on old, non-dockerized server | Directory on the new host server for dockerized setup | Directory inside Docker container | Note |
---|---|---|---|---|
Bitbucket home | – | /var/dockerdata/bitbucket/node-2 | /var/atlassian/application-data/bitbucket | Bitbucket node 2 home directory. We are not re-using the home directory from the old setup. |
Shared data | /some/path/to/bitbucket/shared | /var/dockerdata/bitbucket/shared | /var/atlassian/application-data/bitbucket/shared | Data rsync -ed from the old server. |
Environment variables for connection to the database server
To specify database connection when starting dockerized Bitbucket, what was earlier written to bitbucket.properties
in a non-docker case, must be converted to environment variables.
The variables you must define are these:
bitbucket.properties variable | Environment variable | Note |
---|---|---|
jdbc.driver | JDBC_DRIVER | Database driver to use |
jdbc.url | JDBC_URL | Database connection URL |
jdbc.user | JDBC_USER | Username to connect to the database |
jdbc.password | JDBC_PASSWORD | Password to connect to database |
With plain docker command line utility, setting environment variables would be like this - please note that this is only an example and you will have to provide proper values for environment variables:
docker run -d \
--name bitbucket-1 \
...
...
-e JDBC_DRIVER="org.postgresql.Driver" \
-e JDBC_URL="jdbc:postgresql://10.0.2.100:5432/bitbucket_1?targetServerType=master" \
-e JDBC_USER="bitbucketdbuser" \
-e JDBC_PASSWORD="mysecretpassword" \
...
...
Other variables
Similarly to JDBC_...
environment variables, other settings from the bitbucket.properties
file has to be converted to environment variables. Check the page Binding From Environment Variables for information on how to convert them.
Special characters in the command line and escaping them
Sometimes values of environment variables contain characters that have special meanings in the Unix shell - like "#", single or double quotes, "$", "\", and so on.
- To be able to set those values, you can put single quotes around the value like
'some value'
. - Single quotes don't apply any special processing to the characters inside them, so there is a great chance for success.
- The exception would be if the value itself (password, for example) contains a single-quote character.
- If that is your case, we will have to find another solution, like using the https://onlinelinuxtools.com/escape-shell-characters tool to "convert" the value and apply it as given in the "output" window, without additional quotes.
As a very quick-and-dirty test, you can add "echo
" before your "docker run ...
" command to inspect if what is written out looks correct - it should be as if you would type those values manually.
So, to test it, add a prefix to the command, something like
echo docker run ....
If what you see looks fine, remove the "echo
" part and execute the command.