diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..ca252ede7a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,249 @@ +name: build + +on: + push: + # Sequence of patterns matched against refs/heads + branches: + # Provide the release branch + +env: + PKG_NAME: consul + +jobs: + get-product-version: + runs-on: ubuntu-latest + outputs: + product-version: ${{ steps.get-product-version.outputs.product-version }} + pre-version: ${{ steps.get-product-version.outputs.pre-version }} + pkg-version: ${{ steps.get-product-version.outputs.pkg-version }} + shared-ldflags: ${{ steps.shared-ldflags.outputs.shared-ldflags }} + steps: + - uses: actions/checkout@v2 + - name: get product version + id: get-product-version + run: | + IFS="-"; OUTPUT=$(build-support/scripts/version.sh -r); + read -a V <<< "$OUTPUT"; unset IFS; + + VERSION=${V[0]} + PREREL_VERSION=${V[1]} + + echo "::set-output name=product-version::${VERSION}-${PREREL_VERSION}" + echo "::set-output name=pre-version::${PREREL_VERSION}" + echo "::set-output name=pkg-version::${VERSION}" + + - name: Set shared -ldflags + id: shared-ldflags + run: echo "::set-output name=shared-ldflags::-X github.com/hashicorp/consul/version.GitCommit=${GITHUB_SHA::8} -X github.com/hashicorp/consul/version.GitDescribe=${{ steps.get-product-version.outputs.product-version }}" + + generate-metadata-file: + needs: get-product-version + runs-on: ubuntu-latest + outputs: + filepath: ${{ steps.generate-metadata-file.outputs.filepath }} + steps: + - name: 'Checkout directory' + uses: actions/checkout@v2 + - name: Generate metadata file + id: generate-metadata-file + uses: hashicorp/actions-generate-metadata@main + with: + version: ${{ needs.get-product-version.outputs.product-version }} + product: ${{ env.PKG_NAME }} + + - uses: actions/upload-artifact@v2 + with: + name: metadata.json + path: ${{ steps.generate-metadata-file.outputs.filepath }} + + build: + needs: get-product-version + runs-on: ubuntu-latest + strategy: + matrix: + include: + - {go: "1.17", goos: "linux", goarch: "386"} + - {go: "1.17", goos: "linux", goarch: "amd64"} + - {go: "1.17", goos: "linux", goarch: "arm"} + - {go: "1.17", goos: "linux", goarch: "arm64"} + - {go: "1.17", goos: "freebsd", goarch: "386"} + - {go: "1.17", goos: "freebsd", goarch: "amd64"} + - {go: "1.17", goos: "windows", goarch: "386"} + - {go: "1.17", goos: "windows", goarch: "amd64"} + - {go: "1.17", goos: "solaris", goarch: "amd64"} + fail-fast: true + + name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build + steps: + - uses: actions/checkout@v2 + + - name: Setup go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + + - name: Install project dependencies + run: | + go install github.com/elazarl/go-bindata-assetfs/go-bindata-assetfs@38087fe + go install github.com/hashicorp/go-bindata/go-bindata@bf7910a + + - name: Setup with node and yarn + uses: actions/setup-node@v2 + with: + node-version: '14' + cache: 'yarn' + cache-dependency-path: 'ui/yarn.lock' + + - name: Build UI + run: | + CONSUL_VERSION=${{ needs.get-product-version.outputs.product-version }} + CONSUL_BINARY_TYPE=${CONSUL_BINARY_TYPE} + CONSUL_COPYRIGHT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD) + echo "consul_version is ${CONSUL_VERSION}" + echo "consul binary type is ${CONSUL_BINARY_TYPE}" + echo "consul copyright year is ${CONSUL_COPYRIGHT_YEAR}" + cd ui && make && cd .. + mkdir pkg + mv ui/packages/consul-ui/dist pkg/web_ui + + - name: Build static-assets + run: make static-assets + + - name: Build + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: 0 + GOLDFLAGS: "${{needs.get-product-version.outputs.shared-ldflags}}" + run: | + mkdir dist out + go build -ldflags="$GOLDFLAGS" -o dist/ . + zip -r -j out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip dist/ + + - uses: actions/upload-artifact@v2 + with: + name: ${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + path: out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + + - name: Package + if: ${{ matrix.goos == 'linux' }} + uses: hashicorp/actions-packaging-linux@v1 + with: + name: ${{ github.event.repository.name }} + description: "Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure. " + arch: ${{ matrix.goarch }} + version: ${{ needs.get-product-version.outputs.product-version }} + maintainer: "HashiCorp" + homepage: "https://github.com/hashicorp/consul" + license: "MPL-2.0" + binary: "dist/${{ env.PKG_NAME }}" + deb_depends: "openssl" + rpm_depends: "openssl" + config_dir: ".release/linux/package" + preinstall: ".release/linux/preinstall" + postinstall: ".release/linux/postinstall" + postremove: ".release/linux/postremove" + + - name: Set Package Names + if: ${{ matrix.goos == 'linux' }} + run: | + echo "RPM_PACKAGE=$(basename out/*.rpm)" >> $GITHUB_ENV + echo "DEB_PACKAGE=$(basename out/*.deb)" >> $GITHUB_ENV + + - uses: actions/upload-artifact@v2 + if: ${{ matrix.goos == 'linux' }} + with: + name: ${{ env.RPM_PACKAGE }} + path: out/${{ env.RPM_PACKAGE }} + + - uses: actions/upload-artifact@v2 + if: ${{ matrix.goos == 'linux' }} + with: + name: ${{ env.DEB_PACKAGE }} + path: out/${{ env.DEB_PACKAGE }} + + build-darwin: + needs: get-product-version + runs-on: macos-latest + strategy: + matrix: + goos: [ darwin ] + goarch: [ "amd64" ] + go: [ "1.17" ] + fail-fast: true + + name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build + steps: + - uses: actions/checkout@v2 + + - name: Setup go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + + - name: Install project dependencies + run: | + go install github.com/elazarl/go-bindata-assetfs/go-bindata-assetfs@38087fe + go install github.com/hashicorp/go-bindata/go-bindata@bf7910a + + - name: Setup with node and yarn + uses: actions/setup-node@v2 + with: + node-version: '14' + cache: 'yarn' + cache-dependency-path: 'ui/yarn.lock' + + - name: Build UI + run: | + CONSUL_VERSION=${{ needs.get-product-version.outputs.product-version }} + CONSUL_BINARY_TYPE=${CONSUL_BINARY_TYPE} + CONSUL_COPYRIGHT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD) + echo "consul_version is ${CONSUL_VERSION}" + echo "consul binary type is ${CONSUL_BINARY_TYPE}" + echo "consul copyright year is ${CONSUL_COPYRIGHT_YEAR}" + cd ui && make && cd .. + mkdir pkg + mv ui/packages/consul-ui/dist pkg/web_ui + + - name: Build static-assets + run: make static-assets + + - name: Build + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + GOLDFLAGS: "${{ needs.get-product-version.outputs.shared-ldflags }}" + run: | + mkdir dist out + go build -ldflags="$GOLDFLAGS" -o dist/ . + zip -r -j out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip dist/ + + - uses: actions/upload-artifact@v2 + with: + name: ${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + path: out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + + build-docker: + name: Docker ${{ matrix.arch }} build + needs: + - get-product-version + - build + runs-on: ubuntu-latest + strategy: + matrix: + arch: ["arm", "arm64", "386", "amd64"] + env: + repo: ${{github.event.repository.name}} + version: ${{needs.get-product-version.outputs.product-version}} + + steps: + - uses: actions/checkout@v2 + - name: Docker Build (Action) + uses: hashicorp/actions-docker-build@v1 + with: + version: ${{env.version}} + target: default + arch: ${{matrix.arch}} + tags: | + docker.io/hashicorp/${{env.repo}}:${{env.version}} + ecr.public.aws/hashicorp/${{env.repo}}:${{env.version}} diff --git a/.release/ci.hcl b/.release/ci.hcl new file mode 100644 index 0000000000..b182421046 --- /dev/null +++ b/.release/ci.hcl @@ -0,0 +1,111 @@ +schema = "1" + +project "consul" { + team = "consul core" + slack { + # feed-consul-ci + notification_channel = "C9KPKPKRN" + } + github { + organization = "hashicorp" + repository = "consul" + release_branches = [ + "main", + "release/1.8.x", + "release/1.9.x", + "release/1.10.x", + "release/1.11.x" + ] + } +} + +event "build" { + depends = ["merge"] + action "build" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "build" + } +} + +event "upload-dev" { + depends = ["build"] + action "upload-dev" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "upload-dev" + depends = ["build"] + } + + notification { + on = "fail" + } +} + +event "notarize-darwin-amd64" { + depends = ["upload-dev"] + action "notarize-darwin-amd64" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "notarize-darwin-amd64" + + } + + notification { + on = "fail" + } +} + +event "notarize-windows-386" { + depends = ["notarize-darwin-amd64"] + action "notarize-windows-386" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "notarize-windows-386" + + } + + notification { + on = "fail" + } +} + +event "notarize-windows-amd64" { + depends = ["notarize-windows-386"] + action "notarize-windows-amd64" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "notarize-windows-amd64" + } + + notification { + on = "fail" + } +} + +event "sign" { + depends = ["notarize-windows-amd64"] + action "sign" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "sign" + + } + + notification { + on = "fail" + } +} + +event "verify" { + depends = ["sign"] + action "verify" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "verify" + } + + notification { + on = "fail" + } +} diff --git a/.release/docker/docker-entrypoint.sh b/.release/docker/docker-entrypoint.sh new file mode 100644 index 0000000000..fe91711c6e --- /dev/null +++ b/.release/docker/docker-entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/dumb-init /bin/sh +set -e + +# Note above that we run dumb-init as PID 1 in order to reap zombie processes +# as well as forward signals to all processes in its session. Normally, sh +# wouldn't do either of these functions so we'd leak zombies as well as do +# unclean termination of all our sub-processes. +# As of docker 1.13, using docker run --init achieves the same outcome. + +# You can set CONSUL_BIND_INTERFACE to the name of the interface you'd like to +# bind to and this will look up the IP and pass the proper -bind= option along +# to Consul. +if [ -z "$CONSUL_BIND" ]; then + if [ -n "$CONSUL_BIND_INTERFACE" ]; then + CONSUL_BIND_ADDRESS=$(ip -o -4 addr list $CONSUL_BIND_INTERFACE | head -n1 | awk '{print $4}' | cut -d/ -f1) + if [ -z "$CONSUL_BIND_ADDRESS" ]; then + echo "Could not find IP for interface '$CONSUL_BIND_INTERFACE', exiting" + exit 1 + fi + + CONSUL_BIND="-bind=$CONSUL_BIND_ADDRESS" + echo "==> Found address '$CONSUL_BIND_ADDRESS' for interface '$CONSUL_BIND_INTERFACE', setting bind option..." + fi +fi + +# You can set CONSUL_CLIENT_INTERFACE to the name of the interface you'd like to +# bind client intefaces (HTTP, DNS, and RPC) to and this will look up the IP and +# pass the proper -client= option along to Consul. +if [ -z "$CONSUL_CLIENT" ]; then + if [ -n "$CONSUL_CLIENT_INTERFACE" ]; then + CONSUL_CLIENT_ADDRESS=$(ip -o -4 addr list $CONSUL_CLIENT_INTERFACE | head -n1 | awk '{print $4}' | cut -d/ -f1) + if [ -z "$CONSUL_CLIENT_ADDRESS" ]; then + echo "Could not find IP for interface '$CONSUL_CLIENT_INTERFACE', exiting" + exit 1 + fi + + CONSUL_CLIENT="-client=$CONSUL_CLIENT_ADDRESS" + echo "==> Found address '$CONSUL_CLIENT_ADDRESS' for interface '$CONSUL_CLIENT_INTERFACE', setting client option..." + fi +fi + +# CONSUL_DATA_DIR is exposed as a volume for possible persistent storage. The +# CONSUL_CONFIG_DIR isn't exposed as a volume but you can compose additional +# config files in there if you use this image as a base, or use CONSUL_LOCAL_CONFIG +# below. +if [ -z "$CONSUL_DATA_DIR" ]; then + CONSUL_DATA_DIR=/consul/data +fi + +if [ -z "$CONSUL_CONFIG_DIR" ]; then + CONSUL_CONFIG_DIR=/consul/config +fi + +# You can also set the CONSUL_LOCAL_CONFIG environemnt variable to pass some +# Consul configuration JSON without having to bind any volumes. +if [ -n "$CONSUL_LOCAL_CONFIG" ]; then + echo "$CONSUL_LOCAL_CONFIG" > "$CONSUL_CONFIG_DIR/local.json" +fi + +# If the user is trying to run Consul directly with some arguments, then +# pass them to Consul. +if [ "${1:0:1}" = '-' ]; then + set -- consul "$@" +fi + +# Look for Consul subcommands. +if [ "$1" = 'agent' ]; then + shift + set -- consul agent \ + -data-dir="$CONSUL_DATA_DIR" \ + -config-dir="$CONSUL_CONFIG_DIR" \ + $CONSUL_BIND \ + $CONSUL_CLIENT \ + "$@" +elif [ "$1" = 'version' ]; then + # This needs a special case because there's no help output. + set -- consul "$@" +elif consul --help "$1" 2>&1 | grep -q "consul $1"; then + # We can't use the return code to check for the existence of a subcommand, so + # we have to use grep to look for a pattern in the help output. + set -- consul "$@" +fi + +# If we are running Consul, make sure it executes as the proper user. +if [ "$1" = 'consul' -a -z "${CONSUL_DISABLE_PERM_MGMT+x}" ]; then + # Allow to setup user and group via envrironment + if [ -z "$CONSUL_UID" ]; then + CONSUL_UID="$(id -u consul)" + fi + + if [ -z "$CONSUL_GID" ]; then + CONSUL_GID="$(id -g consul)" + fi + + # If the data or config dirs are bind mounted then chown them. + # Note: This checks for root ownership as that's the most common case. + if [ "$(stat -c %u "$CONSUL_DATA_DIR")" != "${CONSUL_UID}" ]; then + chown ${CONSUL_UID}:${CONSUL_GID} "$CONSUL_DATA_DIR" + fi + if [ "$(stat -c %u "$CONSUL_CONFIG_DIR")" != "${CONSUL_UID}" ]; then + chown ${CONSUL_UID}:${CONSUL_GID} "$CONSUL_CONFIG_DIR" + fi + + # If requested, set the capability to bind to privileged ports before + # we drop to the non-root user. Note that this doesn't work with all + # storage drivers (it won't work with AUFS). + if [ ! -z ${CONSUL_ALLOW_PRIVILEGED_PORTS+x} ]; then + setcap "cap_net_bind_service=+ep" /bin/consul + fi + + set -- su-exec ${CONSUL_UID}:${CONSUL_GID} "$@" +fi + +exec "$@" diff --git a/.release/linux/package/etc/consul.d/consul.hcl b/.release/linux/package/etc/consul.d/consul.hcl new file mode 100644 index 0000000000..e1b8e6e198 --- /dev/null +++ b/.release/linux/package/etc/consul.d/consul.hcl @@ -0,0 +1,96 @@ +# Fullconfiguration options can be found at https://www.consul.io/docs/agent/options.html + +# datacenter +# This flag controls the datacenter in which the agent is running. If not provided, +# it defaults to "dc1". Consul has first-class support for multiple datacenters, but +# it relies on proper configuration. Nodes in the same datacenter should be on a +# single LAN. +#datacenter = "my-dc-1" + +# data_dir +# This flag provides a data directory for the agent to store state. This is required +# for all agents. The directory should be durable across reboots. This is especially +# critical for agents that are running in server mode as they must be able to persist +# cluster state. Additionally, the directory must support the use of filesystem +# locking, meaning some types of mounted folders (e.g. VirtualBox shared folders) may +# not be suitable. +data_dir = "/opt/consul" + +# client_addr +# The address to which Consul will bind client interfaces, including the HTTP and DNS +# servers. By default, this is "127.0.0.1", allowing only loopback connections. In +# Consul 1.0 and later this can be set to a space-separated list of addresses to bind +# to, or a go-sockaddr template that can potentially resolve to multiple addresses. +#client_addr = "0.0.0.0" + +# ui +# Enables the built-in web UI server and the required HTTP routes. This eliminates +# the need to maintain the Consul web UI files separately from the binary. +# Version 1.10 deprecated ui=true in favor of ui_config.enabled=true +#ui_config{ +# enabled = true +#} + +# server +# This flag is used to control if an agent is in server or client mode. When provided, +# an agent will act as a Consul server. Each Consul cluster must have at least one +# server and ideally no more than 5 per datacenter. All servers participate in the Raft +# consensus algorithm to ensure that transactions occur in a consistent, linearizable +# manner. Transactions modify cluster state, which is maintained on all server nodes to +# ensure availability in the case of node failure. Server nodes also participate in a +# WAN gossip pool with server nodes in other datacenters. Servers act as gateways to +# other datacenters and forward traffic as appropriate. +#server = true + +# Bind addr +# You may use IPv4 or IPv6 but if you have multiple interfaces you must be explicit. +#bind_addr = "[::]" # Listen on all IPv6 +#bind_addr = "0.0.0.0" # Listen on all IPv4 +# +# Advertise addr - if you want to point clients to a different address than bind or LB. +#advertise_addr = "127.0.0.1" + +# Enterprise License +# As of 1.10, Enterprise requires a license_path and does not have a short trial. +#license_path = "/etc/consul.d/consul.hclic" + +# bootstrap_expect +# This flag provides the number of expected servers in the datacenter. Either this value +# should not be provided or the value must agree with other servers in the cluster. When +# provided, Consul waits until the specified number of servers are available and then +# bootstraps the cluster. This allows an initial leader to be elected automatically. +# This cannot be used in conjunction with the legacy -bootstrap flag. This flag requires +# -server mode. +#bootstrap_expect=3 + +# encrypt +# Specifies the secret key to use for encryption of Consul network traffic. This key must +# be 32-bytes that are Base64-encoded. The easiest way to create an encryption key is to +# use consul keygen. All nodes within a cluster must share the same encryption key to +# communicate. The provided key is automatically persisted to the data directory and loaded +# automatically whenever the agent is restarted. This means that to encrypt Consul's gossip +# protocol, this option only needs to be provided once on each agent's initial startup +# sequence. If it is provided after Consul has been initialized with an encryption key, +# then the provided key is ignored and a warning will be displayed. +#encrypt = "..." + +# retry_join +# Similar to -join but allows retrying a join until it is successful. Once it joins +# successfully to a member in a list of members it will never attempt to join again. +# Agents will then solely maintain their membership via gossip. This is useful for +# cases where you know the address will eventually be available. This option can be +# specified multiple times to specify multiple agents to join. The value can contain +# IPv4, IPv6, or DNS addresses. In Consul 1.1.0 and later this can be set to a go-sockaddr +# template. If Consul is running on the non-default Serf LAN port, this must be specified +# as well. IPv6 must use the "bracketed" syntax. If multiple values are given, they are +# tried and retried in the order listed until the first succeeds. Here are some examples: +#retry_join = ["consul.domain.internal"] +#retry_join = ["10.0.4.67"] +#retry_join = ["[::1]:8301"] +#retry_join = ["consul.domain.internal", "10.0.4.67"] +# Cloud Auto-join examples: +# More details - https://www.consul.io/docs/agent/cloud-auto-join +#retry_join = ["provider=aws tag_key=... tag_value=..."] +#retry_join = ["provider=azure tag_name=... tag_value=... tenant_id=... client_id=... subscription_id=... secret_access_key=..."] +#retry_join = ["provider=gce project_name=... tag_value=..."] + diff --git a/.release/linux/package/usr/lib/systemd/system/consul.service b/.release/linux/package/usr/lib/systemd/system/consul.service new file mode 100644 index 0000000000..bde1210aae --- /dev/null +++ b/.release/linux/package/usr/lib/systemd/system/consul.service @@ -0,0 +1,21 @@ +[Unit] +Description="HashiCorp Consul - A service mesh solution" +Documentation=https://www.consul.io/ +Requires=network-online.target +After=network-online.target +ConditionFileNotEmpty=/etc/consul.d/consul.hcl + +[Service] +EnvironmentFile=/etc/consul.d/consul.env +User=consul +Group=consul +ExecStart=/usr/bin/consul agent -config-dir=/etc/consul.d/ +ExecReload=/bin/kill --signal HUP $MAINPID +KillMode=process +KillSignal=SIGTERM +Restart=on-failure +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target + diff --git a/.release/linux/postinstall b/.release/linux/postinstall new file mode 100644 index 0000000000..26dbdd8586 --- /dev/null +++ b/.release/linux/postinstall @@ -0,0 +1,10 @@ +#!/bin/bash + +mkdir -p /opt/consul +chown -R consul:consul /opt/consul +chown -R consul:consul /etc/consul.d + +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true +fi + diff --git a/.release/linux/postremove b/.release/linux/postremove new file mode 100644 index 0000000000..f317598216 --- /dev/null +++ b/.release/linux/postremove @@ -0,0 +1,14 @@ +#!/bin/bash + +if [ "$1" = "purge" ] +then + userdel consul +fi + +if [ "$1" == "upgrade" ] && [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + systemctl restart consul >/dev/null || true +fi + +exit 0 + diff --git a/.release/linux/preinstall b/.release/linux/preinstall new file mode 100644 index 0000000000..09f1ec92d7 --- /dev/null +++ b/.release/linux/preinstall @@ -0,0 +1,14 @@ +#!/bin/bash + +set -eu + +USER="consul" + +if ! id -u $USER > /dev/null 2>&1; then + useradd \ + --system \ + --user-group \ + --shell /bin/false \ + $USER +fi + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..71bf188117 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,63 @@ +# This Dockerfile creates a production release image for the project using crt release flow. +FROM alpine:3.13 as default + +ARG VERSION +ARG BIN_NAME + +# PRODUCT_NAME and PRODUCT_VERSION are the name of the software in releases.hashicorp.com +# and the version to download. Example: PRODUCT_NAME=consul PRODUCT_VERSION=1.2.3. +ENV BIN_NAME=$BIN_NAME +ENV VERSION=$VERSION +#ARG CONSUL_VERSION=$VERSION +#ARG PRODUCT_VERSION +ARG PRODUCT_REVISION +ARG PRODUCT_NAME=$BIN_NAME +# TARGETOS and TARGETARCH are set automatically when --platform is provided. +ARG TARGETOS TARGETARCH + +LABEL org.opencontainers.image.authors="Consul Team " \ + org.opencontainers.image.url="https://www.consul.io/" \ + org.opencontainers.image.documentation="https://www.consul.io/docs" \ + org.opencontainers.image.source="https://github.com/hashicorp/consul" \ + org.opencontainers.image.version=$VERSION \ + org.opencontainers.image.vendor="HashiCorp" \ + org.opencontainers.image.title="consul" \ + org.opencontainers.image.description="Consul is a datacenter runtime that provides service discovery, configuration, and orchestration." + +# Create a consul user and group first so the IDs get set the same way, even as +# the rest of this may change over time. +RUN addgroup $BIN_NAME && \ + adduser -S -G $BIN_NAME $BIN_NAME +COPY dist/$TARGETOS/$TARGETARCH/$BIN_NAME /bin/ + + +RUN mkdir -p /consul/data && \ + mkdir -p /consul/config && \ + chown -R consul:consul /consul + +# Expose the consul data directory as a volume since there's mutable state in there. +VOLUME /consul/data + +# Server RPC is used for communication between Consul clients and servers for internal +# request forwarding. +EXPOSE 8300 + +# Serf LAN and WAN (WAN is used only by Consul servers) are used for gossip between +# Consul agents. LAN is within the datacenter and WAN is between just the Consul +# servers in all datacenters. +EXPOSE 8301 8301/udp 8302 8302/udp + +# HTTP and DNS (both TCP and UDP) are the primary interfaces that applications +# use to interact with Consul. +EXPOSE 8500 8600 8600/udp + +# Consul doesn't need root privileges so we run it as the consul user from the +# entry point script. The entry point script also uses dumb-init as the top-level +# process to reap any zombie processes created by Consul sub-processes. +COPY .release/docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh +ENTRYPOINT ["docker-entrypoint.sh"] + +# By default you'll get an insecure single-node development server that stores +# everything in RAM, exposes a web UI and HTTP endpoints, and bootstraps itself. +# Don't use this configuration for production. +CMD ["agent", "-dev", "-client", "0.0.0.0"]