如何在分离模式下将Bitbucket服务器作为容器启动?

时间:2019-04-26 08:27:41

标签: docker dockerfile bitbucket bitbucket-server

存在许多有关如何以分离模式运行容器的问题。

我的问题虽然有点特定于在分离模式容器中运行Atlassian Bitbucket服务器。

我尝试了以下操作作为dockerfile中的最后一层,当我使用-d运行容器时,进程未启动

运行/opt/atlassian-bitbucket/bin/start-bitbucket.sh

我尝试使用ENTRYPOINT,如下所示

ENTRYPOINT [“ /opt/atlassian-bitbucket/bin/start-bitbucket.sh”]

,但是启动脚本完成后容器总是退出。

不确定是否有人在容器中设置了Bitbucket数据中心,但我很好奇他们将如何运行多个具有相同映像的容器并使它们加入单个群集。

2 个答案:

答案 0 :(得分:1)

全面披露:我为Atlassian Premier Support工作,与我们的Bitbucket Server团队紧密合作,并且在过去的两年中一直是atlassian/bitbucket-server Docker映像的主要维护者。

短版

首先:使用我们的official image,多年来我们已经解决了许多问题,因此与其尝试从头开始,不如使用我们的基础。

第二:您确实可以在Docker中运行数据中心集群。我的个人测试环境由3个群集节点和几个Smart Mirror组成,它们全部使用官方映像,并且HAProxy充当负载平衡器,并使用外部Elasticsearch实例管理搜索。在上面的自述文件中查看常用配置选项的列表-您可能需要的选项可以通过传递环境变量来设置

长版

又称为“如何在测试环境中启动完整的DC群集?”

这是很久以前我为我们自己的内部支持团队整理的一个简单教程。它使用自定义的HAProxy Docker容器为您提供现成的负载平衡器。它旨在在单个主机上进行测试,因此,如果您想做一些不同的事情或与生产部署更接近,这将无法涵盖。

这里有很多内容,所以让我们从基础开始。

网络

有几种方法可以连接各个Docker容器,以便它们可以彼此找到对方并进行通信(例如--link参数),但是Docker Network到目前为止是最灵活的。通过专用网络,我们可以获得:

  • 容器间通信:同一网络上的容器可以相互通信,并可以从其他容器访问服务,而无需向主机发布特定端口。
  • 自动DNS:容器可以通过其容器名称(由--name参数定义)相互查找。但是,与真实DNS不同,当容器发生故障时,其DNS解析将不再存在。这可能会给诸如HAProxy之类的服务带来一些问题-但我们稍后会解决。另外值得注意的是,这不会设置计算机的主机名,如果需要,则需要单独设置。
  • 静态IP分配:在某些使用情况下,为Docker容器的网络内提供静态IP地址非常有用
  • 多播:默认情况下,Docker网络支持多播,这非常适合通过Hazelcast进行通信的数据中心节点

Docker网络不做的一件事是将主机连接到其网络,因此,用户(用户)无法按容器名称连接到容器,并且您仍然需要将端口发布到本地计算机。但是,在某些情况下,这样做既有用又必要。最简单的解决方法是将条目添加到您的主机文件中,这些条目指向您希望访问的每个容器名称的回送地址127.0.0.1

要创建Docker网络,请运行以下命令。在我的示例中,我们将网络命名为atlasNetwork。如果要使用其他名称,请记住在所有后续的docker命令中更改网络名称。

docker network create --driver bridge \
    --subnet=10.255.0.0/16 \
    atlasNetwork

在这里,我们正在使用网桥驱动程序创建网络-这是最简单的网络类型。更复杂的网络类型允许网络跨越多个主机。我们还手动指定子网-如果我们省略此子网,则Docker将随机选择一个子网,它可能与现有的网络子网冲突,因此最安全的选择我们自己的子网。我们还指定了/ 16掩码,以允许我们使用最后两个八位字节内的IP地址范围-稍后会出现!

存储

诸如$BITBUCKET_HOME之类的永久数据或您的数据库文件需要存储在容器本身之外的某个位置。对于我们的测试环境,我们可以直接将它们直接存储在本地操作系统的主机上。这意味着我们可以使用我们最喜欢的文本编辑器来编辑配置文件,这非常方便! 在下面的示例中,我们将数据文件存储在文件夹~/dockerdata中。无需创建此文件夹或任何子文件夹,因为Docker会自动执行此操作。如果要使用其他文件夹,请确保更新以下示例。

您可能想知道为什么我们不使用Docker的命名卷而不是在主机上装载文件夹。命名卷更易于管理抽象,通常建议使用;但是,出于测试环境的目的(尤其是在Mac上的Docker上,您无法直接访问虚拟文件系统),能够直接检查每个容器的持久性数据具有巨大的实际好处。您可能需要在Bitbucket,Postgres或HAProxy中编辑许多配置文件,这在使用命名卷时可能很困难,因为它需要您在容器中打开外壳程序-而且许多容器都不包含基本的文本编辑器实用程序(甚至都不是vi!)。但是,如果您更喜欢使用卷,则只需在以下所有示例中将主机文件夹替换为命名的卷即可。

数据库

我们网络上需要的第一项服务是数据库。让我们创建一个Postgres实例:

docker run -d \
    --name postgres \
    --restart=unless-stopped \
    -e POSTGRES_PASSWORD=mysecretpassword \
    -e PGDATA=/var/lib/postgresql/data/pgdata \
    -v ~/dockerdata/postgres:/var/lib/postgresql/data/pgdata \
    --network=atlasNetwork \
    -p 5432:5432 \
    postgres:latest

让我们检查一下我们在做什么:

  • -d
    • 运行容器并从中分离(返回提示)。如果没有此选项,则在容器启动时,我们将直接附加到其标准输出,而取消该操作将停止容器。
  • --name postgres
    • 将容器的名称设置为postgres,这也将作为其在我们网络上的DNS记录。
  • --restart=unless-stopped
    • 将容器设置为在Docker启动时自动启动,除非您已明确停止容器。这样,当您重新启动计算机时,Postgres会自动恢复
  • -e POSTGRES_PASSWORD=mysecretpassword
    • 将默认postgres用户的密码设置为mysecretpassword
  • -e PGDATA=/var/lib/postgresql/data/pgdata
    • Postgres官方docker映像建议在将数据文件夹安装到外部卷时指定此自定义位置
  • -v ~/dockerdata/postgres:/var/lib/postgresql/data/pgdata
    • 将容器内的文件夹/var/lib/postgresql/data/pgdata安装到位于主机~/dockerdata/postgres上的外部卷。此文件夹将自动创建
  • --network=atlasNetwork
    • 将容器加入我们的自定义Docker网络
  • -p 5432:5432
    • 将Postgres端口发布到主机,以便我们可以在localhost:5432上访问Postgres。对于其他容器来说,访问该服务不是必需的,但对我们而言,这是必需的
  • postgres:latest
    • Postgres官方docker镜像的最新版本

运行命令,嘿,您现在可以访问功能全面的Postgres实例。为了保持一致,您可能要在这里添加您的第一个主机条目:

127.0.0.1   postgres

现在,您和任何运行中的容器都可以访问postgres:5432上的实例 在继续之前,您应该使用所选的数据库管理工具连接到数据库。使用用户名postgres,默认数据库postgres和密码mysecretpassword连接到主机名postgres,并创建一个准备就绪的Bitbucket数据库:

CREATE USER bitbucket WITH PASSWORD 'bitbucket';
CREATE DATABASE bitbucket WITH OWNER bitbucket ENCODING 'UTF8';

如果您没有方便的数据库管理工具,则可以使用docker exec在容器中直接运行psql来创建数据库:

# We need to run two commands because psql won't let
# you run CREATE DATABASE from a multi-command string

docker exec -it postgres psql -U postgres -c \
    "CREATE USER bitbucket WITH PASSWORD 'bitbucket';"
docker exec -it postgres psql -U postgres -c \
    "CREATE DATABASE bitbucket WITH OWNER bitbucket ENCODING 'UTF8';"

Elasticsearch

我们将设置的下一个服务是Elasticsearch。我们需要一个专用实例,所有我们的数据中心节点都可以访问。关于如何安装兼容版本,如何将其配置为与Bitbucket一起使用以及安装Atlassian的扣环安全性插件,我们有很多说明:安装和配置远程Elasticsearch实例 那么我们如何在Docker中进行设置呢?好吧,这很简单:

docker pull dchevell/bitbucket-elasticsearch:latest

docker run -d \
    --name elasticsearch \
    -e AUTH_BASIC_USERNAME=bitbucket \
    -e AUTH_BASIC_PASSWORD=mysecretpassword \
    -v ~/dockerdata/elastic:/usr/share/elasticsearch/data \
    --network=atlasNetwork \
    -p 9200:9200 \
    dchevell/bitbucket-elasticsearch:latest

简而言之,dchevell/bitbucket-elasticsearch是预先配置的Docker映像,它是根据Atlassian的Install and configure a remote Elasticsearch instance KB文章中的说明进行设置的。已为您安装了Atlassian的Buckler安全插件,您可以使用上述环境变量配置用户名和密码。再次,我们将数据卷安装到主机上,将其连接到Docker网络,并发布端口,以便我们可以直接访问它。这只是出于故障排除的目的,因此,如果您想在本地Elasticsearch实例中四处闲逛而无需通过Bitbucket,则可以。

现在我们完成了,您可以添加第二个主机条目:

127.0.0.1   elasticsearch

HAProxy

接下来,我们将设置HAProxy。安装Bitbucket Data Center提供了一些示例配置,同样,我们有一个预先配置的Docker映像,它为我们完成了所有艰苦的工作。但是首先,我们需要首先解决一些问题。 HAProxy在Docker网络的DNS系统中不能很好地发挥作用。在现实世界中,如果系统出现故障,DNS记录仍然存在,并且连接只会超时。 HAProxy可以很好地处理这种情况。但是在Docker网络中,当容器停止时,其DNS记录将不复存在,并且与它的连接将失败,并显示“未知主机”错误。发生这种情况时,HAProxy不会启动,这意味着我们无法将其配置为通过容器名称代理与节点的连接。相反,我们需要为每个节点提供一个静态IP地址,并将HAProxy配置为使用该IP地址。

即使我们尚未创建节点,我们现在也可以为其确定IP地址。我们的Docker网络的子网为10.255.0.0/16,Docker将在最后一个八位位组上动态分配容器地址(例如10.255.0.110.255.0.2等)。既然知道这一点,我们就可以使用倒数第二个八位字节安全地为Bitbucket节点分配静态IP地址:

10.255.1.1
10.255.1.2
10.255.1.3

有了这一点,还有一件事。 HAProxy将成为我们实例的外观,因此其容器名称将代表我们用来访问该实例的URL。在此示例中,我们将其称为bitbucketdc。我们还将将机器的主机名设置为相同。

docker run -d \
    --name bitbucketdc \
    --hostname bitbucketdc \
    -v ~/dockerdata/haproxy:/usr/local/etc/haproxy \
    --network=atlasNetwork \
    -e HTTP_NODES="10.255.1.1:7990,10.255.1.2:7990,10.255.1.3:7990" \
    -e SSH_NODES="10.255.1.1:7999,10.255.1.2:7999,10.255.1.3:7999" \
    -p 80:80 \
    -p 443:443 \
    -p 7999:7999 \
    -p 8001:8001 \
    dchevell/bitbucket-haproxy:latest

在上面的示例中,我们将未来的Bitbucket节点的HTTP端点以及SSH端点指定为逗号分隔的列表。容器会将其转换为有效的HAProxy配置。代理服务将在端口80和端口443上可用,因此我们将同时发布它们。将该容器配置为根据计算机的主机名自动生成自签名SSL证书,因此我们现成可用的HTTPS访问权限。

由于我们也在代理SSH,因此我们还将发布端口7999,这是Bitbucket Server的默认SSH端口。您会注意到我们还发布了端口8001。这是用于访问HAProxy的Admin界面,因此我们可以监视在任何给定时间检测到哪些节点处于打开或关闭状态。

最后,我们正在将HAProxy的config文件夹安装到数据卷上。确实不是必需的,但是它可以让您直接访问 haproxy.cfg ,以便您可以在那里了解配置选项。

现在是时候进入我们的第三任主机。之所以这样,是因为它会影响诸如访问基本URL之类的事情,因此绝对必需

127.0.0.1   bitbucketdc

Bitbucket节点

最后,我们准备创建Bitbucket节点。由于所有这些都将通过负载平衡器进行访问,因此我们不必发布任何端口。但是,出于故障排除和测试目的,有时您会希望直接命中特定节点,因此我们将每个节点发布到不同的本地端口,以便我们在需要时可以直接访问它。

docker run -d \
    --name=bitbucket_1 \
    -e ELASTICSEARCH_ENABLED=false \
    -e HAZELCAST_NETWORK_MULTICAST=true \
    -e HAZELCAST_GROUP_NAME=bitbucket-docker \
    -e HAZELCAST_GROUP_PASSWORD=bitbucket-docker \
    -e SERVER_PROXY_NAME=bitbucketdc \
    -e SERVER_PROXY_PORT=443 \
    -e SERVER_SCHEME=https \
    -e SERVER_SECURE=true \
    -v ~/dockerdata/bitbucket-shared:/var/atlassian/application-data/bitbucket/shared \
    --network=atlasNetwork \
    --ip=10.255.1.1 \
    -p 7001:7990 \
    -p 7991:7999 \
    atlassian/bitbucket-server:latest

docker run -d \
    --name=bitbucket_2 \
    -e ELASTICSEARCH_ENABLED=false \
    -e HAZELCAST_NETWORK_MULTICAST=true \
    -e HAZELCAST_GROUP_NAME=bitbucket-docker \
    -e HAZELCAST_GROUP_PASSWORD=bitbucket-docker \
    -e SERVER_PROXY_NAME=bitbucketdc \
    -e SERVER_PROXY_PORT=443 \
    -e SERVER_SCHEME=https \
    -e SERVER_SECURE=true \
    -v ~/dockerdata/bitbucket-shared:/var/atlassian/application-data/bitbucket/shared \
    --network=atlasNetwork \
    --ip=10.255.1.2 \
    -p 7002:7990 \
    -p 7992:7999 \
    atlassian/bitbucket-server:latest

docker run -d \
    --name=bitbucket_3 \
    -e ELASTICSEARCH_ENABLED=false \
    -e HAZELCAST_NETWORK_MULTICAST=true \
    -e HAZELCAST_GROUP_NAME=bitbucket-docker \
    -e HAZELCAST_GROUP_PASSWORD=bitbucket-docker \
    -e SERVER_PROXY_NAME=bitbucketdc \
    -e SERVER_PROXY_PORT=443 \
    -e SERVER_SCHEME=https \
    -e SERVER_SECURE=true \
    -v ~/dockerdata/bitbucket-shared:/var/atlassian/application-data/bitbucket/shared \
    --network=atlasNetwork \
    --ip=10.255.1.3 \
    -p 7003:7990 \
    -p 7993:7999 \
    atlassian/bitbucket-server:latest

您可以看到,我们正在指定设置HAProxy时确定的静态IP地址。是否为这些节点添加主机条目,还是仅通过本地主机访问其端口,取决于您。由于没有其他容器需要通过主机名访问我们的节点,因此这不是必须的,而且我个人也没有打扰。

正式的Docker映像增加了设置仅Docker变量ELASTICSEARCH_ENABLED=false的功能,以防止Elasticsearch在容器中启动。官方docker镜像本身支持其余的Hazelcast属性,因为Bitbucket 5基于Springboot,可以为我们自动将环境变量转换为其等效的点属性。

全部打开

现在我们准备出发了!

https://bitbucketdc(或您选择的任何名称)上访问您的实例。添加数据中心评估许可证(您可以在https://my.atlassian.com上生成30天的试用许可证)并将其连接到Postgres数据库。登录,然后转到Server Admin并连接您的Elasticsearch实例(请记住,它运行在端口9200上,因此将Elasticsearch URL设置为http://elasticsearch:9200并使用我们在创建Elasticsearch容器时配置的用户名和密码。

访问Server Admin中的Clustering(群集)部分,您应该在那里看到所有节点,这表明Multicast正在工作并且节点之间已经找到对方。

就是这样!您的数据中心实例完全可以运行。您可以通过关闭除一个节点之外的所有节点并将其用作日常实例,而将其用作单个节点测试实例,然后将其用作日常实例,然后在需要时打开其他节点。

答案 1 :(得分:0)

请参阅正式的docker图片:https://hub.docker.com/r/atlassian/bitbucket-server/

运行:

docker run -v /data/bitbucket:/var/atlassian/application-data/bitbucket --name="bitbucket" -d -p 7990:7990 -p 7999:7999 atlassian/bitbucket-server

您还可以查看官方dockerfile:https://hub.docker.com/r/atlassian/bitbucket-server/dockerfile