├── .gitignore ├── .dockerignore ├── Makefile ├── example ├── README.md ├── docker-compose.yaml └── nginx │ └── default.conf ├── Dockerfile ├── README.md ├── docker-entrypoint.sh └── .github └── workflows └── multiarch.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | ./data 2 | .github 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | image_name := aiogram/telegram-bot-api 2 | image_tag := $(shell date +%Y%m%d) 3 | 4 | .PHONY: build 5 | build: 6 | rm -rf telegram-bot-api 7 | git clone --recursive https://github.com/tdlib/telegram-bot-api.git 8 | docker build -t $(image_name):$(image_tag) --build-arg nproc=$(shell nproc) . 9 | docker tag $(image_name):$(image_tag) $(image_name):latest 10 | 11 | .PHONY: publish 12 | publish: 13 | docker push $(image_name):$(image_tag) 14 | docker push $(image_name):latest 15 | 16 | .PHONY: release 17 | release: update build publish 18 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | By default, [tdlib/telegram-bot-api](https://github.com/tdlib/telegram-bot-api) 4 | doesn't provide possibility to download files from API (without local-mode) 5 | so that's meat you will need to expose files somehow differently, for example by nginx. 6 | 7 | In this example used docker-compose configuration with running 2 containers: 8 | - [aiogram/telegram-bot-api](https://hub.docker.com/r/aiogram/telegram-bot-api) 9 | - [nginx](https://hub.docker.com/_/nginx) 10 | 11 | This example is recommended only for local development but in production you can use it only by your own risk. 12 | -------------------------------------------------------------------------------- /example/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | api: 3 | image: aiogram/telegram-bot-api:latest 4 | restart: unless-stopped 5 | environment: 6 | TELEGRAM_API_ID: "XXX" 7 | TELEGRAM_API_HASH: "YYY" 8 | #TELEGRAM_LOCAL: 1 # allow files >20mb 9 | volumes: 10 | - telegram-bot-api-data:/var/lib/telegram-bot-api 11 | 12 | nginx: 13 | image: nginx:1.27.3-alpine 14 | restart: unless-stopped 15 | depends_on: 16 | - api 17 | volumes: 18 | - telegram-bot-api-data:/var/lib/telegram-bot-api 19 | - ./nginx:/etc/nginx/conf.d/ 20 | ports: 21 | - "80:80" 22 | 23 | volumes: 24 | telegram-bot-api-data: 25 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG ALPINE_VERSION=latest 2 | FROM alpine:${ALPINE_VERSION} AS build 3 | 4 | ENV CXXFLAGS="" 5 | WORKDIR /usr/src/telegram-bot-api 6 | 7 | RUN apk add --no-cache --update alpine-sdk linux-headers git zlib-dev openssl-dev gperf cmake 8 | COPY telegram-bot-api /usr/src/telegram-bot-api 9 | ARG nproc=1 10 | RUN mkdir -p build \ 11 | && cd build \ 12 | && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=.. .. \ 13 | && cmake --build . --target install -j ${nproc} \ 14 | && strip /usr/src/telegram-bot-api/bin/telegram-bot-api 15 | 16 | FROM alpine:${ALPINE_VERSION} 17 | 18 | ENV TELEGRAM_WORK_DIR="/var/lib/telegram-bot-api" \ 19 | TELEGRAM_TEMP_DIR="/tmp/telegram-bot-api" 20 | 21 | RUN apk add --no-cache --update openssl libstdc++ 22 | COPY --from=build /usr/src/telegram-bot-api/bin/telegram-bot-api /usr/local/bin/telegram-bot-api 23 | COPY docker-entrypoint.sh /docker-entrypoint.sh 24 | RUN addgroup -g 101 -S telegram-bot-api \ 25 | && adduser -S -D -H -u 101 -h ${TELEGRAM_WORK_DIR} -s /sbin/nologin -G telegram-bot-api -g telegram-bot-api telegram-bot-api \ 26 | && chmod +x /docker-entrypoint.sh \ 27 | && mkdir -p ${TELEGRAM_WORK_DIR} ${TELEGRAM_TEMP_DIR} \ 28 | && chown telegram-bot-api:telegram-bot-api ${TELEGRAM_WORK_DIR} ${TELEGRAM_TEMP_DIR} 29 | 30 | EXPOSE 8081/tcp 8082/tcp 31 | ENTRYPOINT ["/docker-entrypoint.sh"] 32 | -------------------------------------------------------------------------------- /example/nginx/default.conf: -------------------------------------------------------------------------------- 1 | # use $sanitized_request instead of $request to hide Telegram token 2 | log_format token_filter '$remote_addr - $remote_user [$time_local] ' 3 | '"$sanitized_request" $status $body_bytes_sent ' 4 | '"$http_referer" "$http_user_agent"'; 5 | 6 | upstream telegram-bot-api { 7 | server api:8081; 8 | } 9 | 10 | server { 11 | listen 80; 12 | server_name _; 13 | 14 | chunked_transfer_encoding on; 15 | proxy_connect_timeout 600; 16 | proxy_send_timeout 600; 17 | proxy_read_timeout 600; 18 | send_timeout 600; 19 | client_max_body_size 2G; 20 | client_body_buffer_size 30M; 21 | keepalive_timeout 0; 22 | 23 | set $sanitized_request $request; 24 | if ( $sanitized_request ~ (\w+)\s(\/bot\d+):[-\w]+\/(\S+)\s(.*) ) { 25 | set $sanitized_request "$1 $2:/$3 $4"; 26 | } 27 | access_log /var/log/nginx/access.log token_filter; 28 | 29 | # Handle full paths (e.g., "/var/lib/telegram-bot-api/TOKEN/videos/file_0.mp4") 30 | location ~* ^/file\/bot[^/]+\/var\/lib\/telegram-bot-api(.*) { 31 | rewrite ^/file\/bot[^/]+\/var\/lib\/telegram-bot-api(.*) /$1 break; 32 | try_files $uri @files; 33 | } 34 | 35 | # Handle partial paths (e.g., "videos/file_0.mp4") 36 | location ~* \/file\/bot\d+:(.*) { 37 | rewrite ^/file\/bot(.*) /$1 break; 38 | try_files $uri @files; 39 | } 40 | 41 | location / { 42 | try_files $uri @api; 43 | } 44 | 45 | location @files { 46 | root /var/lib/telegram-bot-api; 47 | gzip on; 48 | gzip_vary on; 49 | gzip_proxied any; 50 | gzip_comp_level 6; 51 | gzip_buffers 64 8k; 52 | gzip_http_version 1.1; 53 | gzip_min_length 1100; 54 | } 55 | 56 | location @api { 57 | proxy_pass http://telegram-bot-api; 58 | proxy_redirect off; 59 | proxy_set_header Host $host; 60 | proxy_set_header X-Real-IP $remote_addr; 61 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 62 | proxy_set_header X-Forwarded-Host $server_name; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unofficial Docker image of Telegram Bot API 2 | 3 | Here is Docker image for https://github.com/tdlib/telegram-bot-api 4 | 5 | The Telegram Bot API provides an HTTP API for creating [Telegram Bots](https://core.telegram.org/bots). 6 | 7 | If you've got any questions about bots or would like to report an issue with your bot, kindly contact us at [@BotSupport](https://t.me/BotSupport) in Telegram. 8 | 9 | ## Quick reference 10 | 11 | Before start, you will need to obtain `api-id` and `api-hash` as described in https://core.telegram.org/api/obtaining_api_id and specify them using the `TELEGRAM_API_ID` and `TELEGRAM_API_HASH` environment variables. 12 | 13 | And then to start the Telegram Bot API all you need to do is 14 | `docker run -d -p 8081:8081 --name=telegram-bot-api --restart=always -v telegram-bot-api-data:/var/lib/telegram-bot-api -e TELEGRAM_API_ID= -e TELEGRAM_API_HASH= aiogram/telegram-bot-api:latest` 15 | 16 | ## Configuration 17 | 18 | Container can be configured via environment variables 19 | 20 | ### `TELEGRAM_API_ID`, `TELEGRAM_API_HASH` 21 | 22 | Application identifiers for Telegram API access, which can be obtained at https://my.telegram.org as described in https://core.telegram.org/api/obtaining_api_id 23 | 24 | ### `TELEGRAM_STAT` 25 | 26 | Enable statistics HTTP endpoint. 27 | 28 | Usage: `-e TELEGRAM_STAT=1 -p 8082:8082` and then check that `curl http://:8082` returns server statistic 29 | 30 | ### `TELEGRAM_FILTER` 31 | 32 | "/". Allow only bots with 'bot_user_id % modulo == remainder' 33 | 34 | ### `TELEGRAM_MAX_WEBHOOK_CONNECTIONS` 35 | 36 | default value of the maximum webhook connections per bot 37 | 38 | ### `TELEGRAM_VERBOSITY` 39 | 40 | log verbosity level 41 | 42 | ### `TELEGRAM_LOG_FILE` 43 | 44 | Filename where logs will be redirected (By default logs will be written to stdout/stderr streams) 45 | 46 | ### `TELEGRAM_MAX_CONNECTIONS` 47 | 48 | maximum number of open file descriptors 49 | 50 | ### `TELEGRAM_PROXY` 51 | 52 | HTTP proxy server for outgoing webhook requests in the format http://host:port 53 | 54 | ### `TELEGRAM_LOCAL` 55 | 56 | allow the Bot API server to serve local requests 57 | 58 | ### `TELEGRAM_HTTP_IP_ADDRESS` 59 | 60 | Use the `TELEGRAM_HTTP_IP_ADDRESS: "[::]"` parameter to listen on the ipv6 intranet 61 | 62 | ### `TELEGRAM_HTTP_PORT` 63 | 64 | Set which port the api server should listen to if you want to run the image in network mode as host and want to change the port. 65 | 66 | If not set then the api server will listen to port 8081. 67 | 68 | ## Start with persistent storage 69 | 70 | Server working directory is `/var/lib/telegram-bot-api` so if you want to persist the server data you can mount this folder as volume: 71 | 72 | `-v telegram-bot-api-data:/etc/telegram/bot/api` 73 | 74 | Note that all files in this directory will be owned by user `telegram-bot-api` and group `telegram-bot-api` (uid: `101`, gid: `101`, compatible with [nginx](https://hub.docker.com/_/nginx) image) 75 | 76 | ## Usage via docker stack deploy or docker-compose 77 | 78 | ```yaml 79 | version: '3.7' 80 | 81 | services: 82 | telegram-bot-api: 83 | image: aiogram/telegram-bot-api:latest 84 | environment: 85 | TELEGRAM_API_ID: "" 86 | TELEGRAM_API_HASH: "" 87 | volumes: 88 | - telegram-bot-api-data:/var/lib/telegram-bot-api 89 | ports: 90 | - "8081:8081" 91 | 92 | volumes: 93 | telegram-bot-api-data: 94 | ``` 95 | -------------------------------------------------------------------------------- /docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | 4 | USERNAME="telegram-bot-api" 5 | GROUPNAME="telegram-bot-api" 6 | 7 | COMMAND="telegram-bot-api" 8 | 9 | # Appends an argument to the COMMAND variable. 10 | append_args() { 11 | COMMAND="$COMMAND $1" 12 | } 13 | 14 | # Sets $env_var from $file_env_var content or directly from $env_var. 15 | # Usage: file_env 16 | # - If both or neither variables are set, exits with an error. 17 | # - If only $file_env_var is set, reads content from the file path and sets $env_var. 18 | # - Exits with an error if the file does not exist. 19 | file_env() { 20 | env_var="$1" 21 | file_env_var="$2" 22 | env_value=$(printenv "$env_var") || env_value="" 23 | file_path=$(printenv "$file_env_var") || file_path="" 24 | 25 | if [ -z "$env_value" ] && [ -z "$file_path" ]; then 26 | echo "error: expected $env_var or $file_env_var env vars to be set" 27 | exit 1 28 | elif [ -n "$env_value" ] && [ -n "$file_path" ]; then 29 | echo "both $env_var and $file_env_var env vars are set, expected only one of them" 30 | exit 1 31 | elif [ -n "$file_path" ]; then 32 | if [ -f "$file_path" ]; then 33 | export "$env_var=$(cat "$file_path")" 34 | else 35 | echo "error: $env_var=$file_path: file '$file_path' does not exist" 36 | exit 1 37 | fi 38 | fi 39 | } 40 | 41 | # Checks if an environment variable is set. 42 | # Usage: check_required_env 43 | # - Exits with an error if the variable is not set. 44 | check_required_env() { 45 | var_name="$1" 46 | 47 | if [ -z "$(printenv "$var_name")" ]; then 48 | echo "error: environment variable $var_name is required" 49 | exit 1 50 | fi 51 | } 52 | 53 | # Appends an argument to CUSTOM_ARGS based on the environment variable value. 54 | # Usage: append_arg_from_env 55 | # - If is set, uses its value; otherwise, uses . 56 | # - Appends "=" to CUSTOM_ARGS if a value is found. 57 | append_arg_from_env() { 58 | var_name="$1" 59 | arg_name="$2" 60 | default_value="$3" 61 | env_value=$(printenv "$var_name") || env_value="" 62 | 63 | [ -n "$env_value" ] || env_value="$default_value" 64 | if [ -n "$env_value" ]; then 65 | append_args "${arg_name}=$env_value" 66 | fi 67 | } 68 | 69 | # Appends a flag to CUSTOM_ARGS if the environment variable is set (non-empty). 70 | # Usage: append_flag_from_env 71 | # - If is set, appends to CUSTOM_ARGS. 72 | append_flag_from_env() { 73 | var_name="$1" 74 | flag_name="$2" 75 | 76 | if [ -n "$(printenv "$var_name")" ]; then 77 | append_args "$flag_name" 78 | fi 79 | } 80 | 81 | check_required_env "TELEGRAM_WORK_DIR" 82 | chown "${USERNAME}:${GROUPNAME}" "${TELEGRAM_WORK_DIR}" 83 | 84 | # Telegram Bot API Server knows how to read the API ID and API Hash from a environment variable. 85 | # Is not needed to pass it as arguments. 86 | file_env "TELEGRAM_API_ID" "TELEGRAM_API_ID_FILE" 87 | file_env "TELEGRAM_API_HASH" "TELEGRAM_API_HASH_FILE" 88 | 89 | # Default arguments, passed from the Dockerfile. 90 | # Potentially can be overwritten by environment variables, if needed, but is not recommended. 91 | append_arg_from_env "TELEGRAM_WORK_DIR" "--dir" 92 | check_required_env "TELEGRAM_TEMP_DIR" 93 | append_arg_from_env "TELEGRAM_TEMP_DIR" "--temp-dir" 94 | append_args "--username=${USERNAME}" 95 | append_args "--groupname=${GROUPNAME}" 96 | 97 | check_required_env "TELEGRAM_API_ID" 98 | check_required_env "TELEGRAM_API_HASH" 99 | 100 | # Environment variables that can be passed as arguments from environment by administrator. 101 | append_arg_from_env "TELEGRAM_HTTP_PORT" "--http-port" "8081" 102 | append_flag_from_env "TELEGRAM_LOCAL" "--local" 103 | append_flag_from_env "TELEGRAM_STAT" "--http-stat-port=8082" # maybe change it to dynamic variable in the future 104 | append_arg_from_env "TELEGRAM_LOG_FILE" "--log" 105 | append_arg_from_env "TELEGRAM_FILTER" "--filter" 106 | append_arg_from_env "TELEGRAM_MAX_WEBHOOK_CONNECTIONS" "--max-webhook-connections" 107 | append_arg_from_env "TELEGRAM_VERBOSITY" "--verbosity" 108 | append_arg_from_env "TELEGRAM_MAX_CONNECTIONS" "--max-connections" 109 | append_arg_from_env "TELEGRAM_PROXY" "--proxy" 110 | append_arg_from_env "TELEGRAM_HTTP_IP_ADDRESS" "--http-ip-address" 111 | 112 | echo "$COMMAND" 113 | exec $COMMAND 114 | -------------------------------------------------------------------------------- /.github/workflows/multiarch.yml: -------------------------------------------------------------------------------- 1 | name: Docker multi-arch build and push 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | - cron: '20 4 * * *' 9 | 10 | jobs: 11 | build: 12 | name: Build Docker image (${{ matrix.arch }}) 13 | runs-on: ubuntu-latest 14 | env: 15 | IMAGE_TAG: ${{ secrets.DOCKERHUB_OWNER }}/telegram-bot-api 16 | ALPINE_VERSION: '3.21' 17 | strategy: 18 | matrix: 19 | arch: 20 | - linux/386 21 | - linux/amd64 22 | - linux/arm/v6 23 | - linux/arm/v7 24 | - linux/arm64 25 | - linux/ppc64le 26 | 27 | steps: 28 | - name: Checkout current repo 29 | uses: actions/checkout@v4 30 | 31 | - name: Checkout upstream repo 32 | uses: actions/checkout@v4 33 | with: 34 | repository: tdlib/telegram-bot-api 35 | path: telegram-bot-api 36 | submodules: recursive 37 | 38 | - name: Get version 39 | run: | 40 | # Get latest commit short hash 41 | HASH_VERSION=$(git rev-parse --short HEAD) 42 | 43 | # Get real version from the code 44 | VERSION=$(cat telegram-bot-api/CMakeLists.txt | grep TelegramBotApi | cut -d " " -f3) 45 | 46 | # Convert IMAGE_TAG, HASH_VERSION and VERSION to lowercase (repository name must be lowercase) 47 | IMAGE_TAG=$(echo "$IMAGE_TAG" | awk '{print tolower($0)}') 48 | VERSION=$(echo "$VERSION" | awk '{print tolower($0)}') 49 | ARCH=${{ matrix.arch }} 50 | SAFE_ARCH=${ARCH///} # linux/amd64 -> linuxamd64 51 | 52 | # Store variable for future use 53 | echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV 54 | echo "VERSION=$VERSION" >> $GITHUB_ENV 55 | echo "SAFE_ARCH=$SAFE_ARCH" >> $GITHUB_ENV 56 | 57 | # Print debug info 58 | echo "version: $VERSION" 59 | echo "safe arch: $SAFE_ARCH" 60 | 61 | # Save env to file 62 | cat $GITHUB_ENV > github.env 63 | 64 | - name: Upload environment info as artifact 65 | uses: actions/upload-artifact@v4 66 | if: matrix.arch == 'linux/amd64' # Run this step only once per all matrix builds 67 | with: 68 | name: github_env 69 | path: github.env 70 | 71 | - name: Set up QEMU 72 | uses: docker/setup-qemu-action@v3 73 | 74 | - name: Set up Docker Buildx 75 | uses: docker/setup-buildx-action@v3 76 | 77 | - name: Cache Docker layers 78 | uses: actions/cache@v4 79 | with: 80 | path: /tmp/.buildx-cache 81 | key: ${{ runner.os }}-buildx-${{ env.SAFE_ARCH }}-${{ github.sha }} 82 | restore-keys: | 83 | ${{ runner.os }}-buildx-${{ env.SAFE_ARCH }}- 84 | 85 | - name: Login to Docker Hub registry 86 | uses: docker/login-action@v3 87 | if: ${{ github.event_name != 'pull_request' }} 88 | with: 89 | username: ${{ secrets.DOCKERHUB_LOGIN }} 90 | password: ${{ secrets.DOCKERHUB_TOKEN }} 91 | 92 | - name: Set build parameters 93 | id: build-params 94 | run: | 95 | # Get available CPUs, use 75% for build, minimum 2 96 | AVAILABLE_CPUS=$(nproc) 97 | OPTIMAL_NPROC=$(( AVAILABLE_CPUS * 3 / 4 )) 98 | OPTIMAL_NPROC=$(( OPTIMAL_NPROC > 1 ? OPTIMAL_NPROC : 2 )) 99 | 100 | # ARM architectures might need special handling 101 | if [[ "${{ matrix.arch }}" == *"arm"* ]]; then 102 | # For ARM, be more conservative with resources 103 | OPTIMAL_NPROC=$(( OPTIMAL_NPROC > 2 ? 2 : OPTIMAL_NPROC )) 104 | fi 105 | 106 | echo "nproc=${OPTIMAL_NPROC}" >> $GITHUB_OUTPUT 107 | 108 | - name: Build image 109 | uses: docker/build-push-action@v6 110 | env: 111 | DOCKER_BUILD_SUMMARY: false 112 | DOCKER_BUILD_RECORD_UPLOAD: false 113 | with: 114 | context: . 115 | file: ./Dockerfile 116 | cache-from: type=local,src=/tmp/.buildx-cache 117 | cache-to: type=local,mode=max,dest=/tmp/.buildx-cache 118 | platforms: ${{ matrix.arch }} 119 | build-args: | 120 | ALPINE_VERSION=${{ env.ALPINE_VERSION }} 121 | nproc=${{ steps.build-params.outputs.nproc }} 122 | push: false 123 | load: true 124 | tags: | 125 | ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-${{ env.SAFE_ARCH }} 126 | 127 | - name: Tag and push image 128 | if: ${{ github.event_name != 'pull_request' }} 129 | run: | 130 | docker push ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-${{ env.SAFE_ARCH }} 131 | 132 | - name: Save image as tar archive 133 | if: ${{ github.event_name != 'pull_request' }} 134 | run: | 135 | docker save ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-${{ env.SAFE_ARCH }} -o ${{ env.SAFE_ARCH }}.tar 136 | 137 | - name: Upload image as artifact 138 | uses: actions/upload-artifact@v4 139 | with: 140 | name: image_${{ env.SAFE_ARCH }} 141 | path: ${{ env.SAFE_ARCH }}.tar 142 | 143 | push-manifest: 144 | name: Create and push multi-arch Docker manifest 145 | runs-on: ubuntu-latest 146 | if: ${{ github.event_name != 'pull_request' }} 147 | env: 148 | DOCKER_CLI_EXPERIMENTAL: enabled 149 | needs: build 150 | 151 | steps: 152 | - name: Download artifacts 153 | uses: actions/download-artifact@v4 154 | 155 | - name: Load environment info and built images 156 | run: | 157 | cat github_env/github.env > $GITHUB_ENV 158 | docker load --input image_linux386/linux386.tar 159 | docker load --input image_linuxamd64/linuxamd64.tar 160 | docker load --input image_linuxarmv6/linuxarmv6.tar 161 | docker load --input image_linuxarmv7/linuxarmv7.tar 162 | docker load --input image_linuxarm64/linuxarm64.tar 163 | docker load --input image_linuxppc64le/linuxppc64le.tar 164 | 165 | - name: Login to ghcr registry 166 | uses: docker/login-action@v3 167 | with: 168 | registry: ghcr.io 169 | username: ${{ github.actor }} 170 | password: ${{ secrets.GITHUB_TOKEN }} 171 | 172 | - name: Login to Docker Hub registry 173 | uses: docker/login-action@v3 174 | with: 175 | username: ${{ secrets.DOCKERHUB_LOGIN }} 176 | password: ${{ secrets.DOCKERHUB_TOKEN }} 177 | 178 | - name: Create and push manifest 179 | run: | 180 | docker manifest create ${{ env.IMAGE_TAG }}:${{ env.VERSION }} \ 181 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linux386 \ 182 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxamd64 \ 183 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv6 \ 184 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv7 \ 185 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarm64 \ 186 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxppc64le 187 | docker manifest push ${{ env.IMAGE_TAG }}:${{ env.VERSION }} 188 | 189 | docker manifest create ${{ env.IMAGE_TAG }}:latest \ 190 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linux386 \ 191 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxamd64 \ 192 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv6 \ 193 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv7 \ 194 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarm64 \ 195 | --amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxppc64le 196 | docker manifest push ${{ env.IMAGE_TAG }}:latest 197 | --------------------------------------------------------------------------------