diff --git a/Dockerfile b/Dockerfile index de01258..8e8ffdb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,9 @@ LABEL 'com.github.actions.description'='supports docker-compose and Docker Swarm LABEL 'com.github.actions.icon'='send' LABEL 'com.github.actions.color'='green' -RUN apk --no-cache add openssh-client +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories + +RUN apk --no-cache add openssh-client socat COPY docker-entrypoint.sh /docker-entrypoint.sh diff --git a/action.yml b/action.yml index da19a60..5da1699 100644 --- a/action.yml +++ b/action.yml @@ -2,32 +2,35 @@ name: Docker Remote (SSH) Deployment description: A GitHub Action that supports docker-compose and Docker Swarm deployments inputs: remote_docker_host: - description: Remote Docker host ie (user@host). + description: Remote Docker host. + required: true + remote_docker_user: + description: Remote Docker user. required: true remote_docker_port: description: Remote Docker ssh port ie (22). required: false default: '22' - ssh_public_key: - description: Remote Docker SSH public key eg (~/.ssh/rsa_id.pub). - required: true + # ssh_public_key: + # description: Remote Docker SSH public key eg (~/.ssh/rsa_id.pub). + # required: true ssh_private_key: description: SSH private key used to connect to the docker host eg (~/.ssh/rsa_id). required: true + ssh_proxy_cmd: + description: SSH ProxyCommand used to connect to the docker host. + required: false args: description: Deployment command args. required: true - deployment_mode: - description: Deployment mode either docker-swarm or docker-compose. Default is docker-compose. - required: false - copy_stack_file: - description: Copy stack file to remote server and deploy from the server. Default is false. - required: false deploy_path: - description: The path where the stack files will be copied to. Default ~/docker-deployment. + description: The absolute path on remote docker host to deploy, default rely on repo working directory . required: false stack_file_name: - description: Docker stack file used. Default is docker-compose.yml. + description: Compose configuration files. + required: false + env_file_name: + description: Specify an alternate environment file. required: false keep_files: description: Number of the files to be kept on the server. Default is 3. @@ -38,9 +41,6 @@ inputs: pre_deployment_command_args: description: The args for the pre deploument command. required: false - pull_images_first: - description: Pull docker images before deploying. Default is false. - required: false docker_registry_username: description: The docker registry username. required: false diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 234b6e2..5da245f 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,86 +1,43 @@ #!/bin/sh set -eu -execute_ssh(){ - echo "Execute Over SSH: $@" - ssh -q -t -i "$HOME/.ssh/id_rsa" \ - -o UserKnownHostsFile=/dev/null \ - -p $INPUT_REMOTE_DOCKER_PORT \ - -o StrictHostKeyChecking=no "$INPUT_REMOTE_DOCKER_HOST" "$@" -} - -if [ -z "${INPUT_REMOTE_DOCKER_PORT+x}" ]; then +if [ -z "${INPUT_REMOTE_DOCKER_PORT+x}" ] || [ -z "$INPUT_REMOTE_DOCKER_PORT" ]; then INPUT_REMOTE_DOCKER_PORT=22 fi -if [ -z "${INPUT_REMOTE_DOCKER_HOST+x}" ]; then +if [ -z "${INPUT_REMOTE_DOCKER_HOST+x}" ] || [ -z "$INPUT_REMOTE_DOCKER_HOST" ]; then echo "Input remote_docker_host is required!" exit 1 fi -if [ -z "${INPUT_SSH_PUBLIC_KEY+x}" ]; then - echo "Input ssh_public_key is required!" +if [ -z "${INPUT_REMOTE_DOCKER_USER+x}" ] || [ -z "$INPUT_REMOTE_DOCKER_USER" ]; then + echo "Input remote_docker_user is required!" exit 1 fi -if [ -z "${INPUT_SSH_PRIVATE_KEY+x}" ]; then +if [ -z "${INPUT_SSH_PRIVATE_KEY+x}" ] || [ -z "$INPUT_SSH_PRIVATE_KEY" ]; then echo "Input ssh_private_key is required!" exit 1 fi -if [ -z "${INPUT_ARGS+x}" ]; then +if [ -z "${INPUT_ARGS+x}" ] || [ -z "$INPUT_ARGS" ]; then echo "Input input_args is required!" exit 1 fi -if [ -z "${INPUT_DEPLOY_PATH+x}" ]; then - INPUT_DEPLOY_PATH=~/docker-deployment +if ! [ -z "${INPUT_DEPLOY_PATH+x}" ] && ! [ -z "$INPUT_DEPLOY_PATH" ]; then + echo "Change working directory" + echo "Current: `pwd`" + echo "Target: $INPUT_DEPLOY_PATH" + mkdir -p $INPUT_DEPLOY_PATH + cp -rfp ./. $INPUT_DEPLOY_PATH + cd $INPUT_DEPLOY_PATH fi -if [ -z "${INPUT_STACK_FILE_NAME+x}" ]; then - INPUT_STACK_FILE_NAME=docker-compose.yaml -fi - -if [ -z "${INPUT_KEEP_FILES+x}" ]; then - INPUT_KEEP_FILES=4 -else - INPUT_KEEP_FILES=$((INPUT_KEEP_FILES+1)) -fi - -if [ -z "${INPUT_DOCKER_REGISTRY_URI+x}" ]; then +if [ -z "${INPUT_DOCKER_REGISTRY_URI+x}" ] || [ -z "$INPUT_DOCKER_REGISTRY_URI" ]; then INPUT_DOCKER_REGISTRY_URI=https://registry.hub.docker.com fi -if [ -z "${INPUT_COPY_STACK_FILE+x}" ]; then - INPUT_COPY_STACK_FILE=false -fi - -STACK_FILE=${INPUT_STACK_FILE_NAME} -DEPLOYMENT_COMMAND_OPTIONS="" - - -if [ "$INPUT_COPY_STACK_FILE" == "true" ]; then - STACK_FILE="$INPUT_DEPLOY_PATH/$STACK_FILE" -else - DEPLOYMENT_COMMAND_OPTIONS=" --log-level debug --host ssh://$INPUT_REMOTE_DOCKER_HOST:$INPUT_REMOTE_DOCKER_PORT" -fi - -case $INPUT_DEPLOYMENT_MODE in - - docker-swarm) - DEPLOYMENT_COMMAND="docker $DEPLOYMENT_COMMAND_OPTIONS stack deploy --compose-file $STACK_FILE" - ;; - - *) - INPUT_DEPLOYMENT_MODE="docker-compose" - DEPLOYMENT_COMMAND="docker compose -f $STACK_FILE $DEPLOYMENT_COMMAND_OPTIONS" - ;; -esac - -echo `docker-compose -v` - -SSH_HOST=${INPUT_REMOTE_DOCKER_HOST#*@} - echo "Registering SSH keys..." # register the private key with the agent. @@ -88,23 +45,34 @@ mkdir -p ~/.ssh ls ~/.ssh printf '%s\n' "$INPUT_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa -printf '%s\n' "$INPUT_SSH_PUBLIC_KEY" > ~/.ssh/id_rsa.pub -chmod 600 ~/.ssh/id_rsa.pub -#chmod 600 "~/.ssh" eval $(ssh-agent) ssh-add ~/.ssh/id_rsa -echo "Add known hosts" -ssh-keyscan -p $INPUT_REMOTE_DOCKER_PORT "$SSH_HOST" >> ~/.ssh/known_hosts -ssh-keyscan -p $INPUT_REMOTE_DOCKER_PORT "$SSH_HOST" >> /etc/ssh/ssh_known_hosts +echo "Add REMOTE_DOCKER_HOST alias to ~/.ssh/config" +touch ~/.ssh/config +echo >> ~/.ssh/config +echo "Host REMOTE_DOCKER_HOST" >> ~/.ssh/config +echo " HostName $INPUT_REMOTE_DOCKER_HOST" >> ~/.ssh/config +echo " User $INPUT_REMOTE_DOCKER_USER" >> ~/.ssh/config +echo " Port $INPUT_REMOTE_DOCKER_PORT" >> ~/.ssh/config +echo " IdentityFile ~/.ssh/id_rsa" >> ~/.ssh/config +echo " StrictHostKeyChecking no" >> ~/.ssh/config +echo " UserKnownHostsFile /dev/null" >> ~/.ssh/config +if ! [ -z "${INPUT_SSH_PROXY_CMD+x}" ] && ! [ -z "$INPUT_SSH_PROXY_CMD" ]; then + echo "Add ProxyCommand: $INPUT_SSH_PROXY_CMD" + echo " ProxyCommand $INPUT_SSH_PROXY_CMD" >> ~/.ssh/config +fi +echo >> ~/.ssh/config +chmod 600 ~/.ssh/config set context echo "Create docker context" -docker context create remote --docker "host=ssh://$INPUT_REMOTE_DOCKER_HOST:$INPUT_REMOTE_DOCKER_PORT" +docker context create remote --docker "host=ssh://REMOTE_DOCKER_HOST" docker context use remote -if ! [ -z "${INPUT_DOCKER_REGISTRY_USERNAME+x}" ] && ! [ -z "${INPUT_DOCKER_REGISTRY_PASSWORD+x}" ]; then - echo "Connecting to $INPUT_REMOTE_DOCKER_HOST... Command: docker login" +if ! [ -z "${INPUT_DOCKER_REGISTRY_USERNAME+x}" ] && ! [ -z "$INPUT_DOCKER_REGISTRY_USERNAME" ] && + ! [ -z "${INPUT_DOCKER_REGISTRY_PASSWORD+x}" ] && ! [ -z "$INPUT_DOCKER_REGISTRY_PASSWORD" ]; then + echo "Connecting to $INPUT_DOCKER_REGISTRY_URI... Command: docker login" echo "$INPUT_DOCKER_REGISTRY_PASSWORD" | docker login -u "$INPUT_DOCKER_REGISTRY_USERNAME" --password-stdin "$INPUT_DOCKER_REGISTRY_URI" fi @@ -112,34 +80,17 @@ if ! [ -z "${INPUT_DOCKER_PRUNE+x}" ] && [ $INPUT_DOCKER_PRUNE = 'true' ] ; then yes | docker --log-level debug --host "ssh://$INPUT_REMOTE_DOCKER_HOST:$INPUT_REMOTE_DOCKER_PORT" system prune -a 2>&1 fi -if ! [ -z "${INPUT_COPY_STACK_FILE+x}" ] && [ $INPUT_COPY_STACK_FILE = 'true' ] ; then - execute_ssh "mkdir -p $INPUT_DEPLOY_PATH/stacks || true" - FILE_NAME="docker-stack-$(date +%Y%m%d%s).yaml" +DEPLOYMENT_COMMAND="docker --log-level=debug compose" - scp -i "$HOME/.ssh/id_rsa" \ - -o UserKnownHostsFile=/dev/null \ - -o StrictHostKeyChecking=no \ - -P $INPUT_REMOTE_DOCKER_PORT \ - $INPUT_STACK_FILE_NAME "$INPUT_REMOTE_DOCKER_HOST:$INPUT_DEPLOY_PATH/stacks/$FILE_NAME" - - DIRS=$(dirname "$INPUT_DEPLOY_PATH/$INPUT_STACK_FILE_NAME") - mkdir -p "$DIRS" || exit 0 - - execute_ssh "ln -nfs $INPUT_DEPLOY_PATH/stacks/$FILE_NAME $INPUT_DEPLOY_PATH/$INPUT_STACK_FILE_NAME" - execute_ssh "ls -t $INPUT_DEPLOY_PATH/stacks/docker-stack-* 2>/dev/null | tail -n +$INPUT_KEEP_FILES | xargs rm -- 2>/dev/null || true" - - if ! [ -z "${INPUT_PULL_IMAGES_FIRST+x}" ] && [ $INPUT_PULL_IMAGES_FIRST = 'true' ] && [ $INPUT_DEPLOYMENT_MODE = 'docker-compose' ] ; then - execute_ssh ${DEPLOYMENT_COMMAND} "pull" - fi - - if ! [ -z "${INPUT_PRE_DEPLOYMENT_COMMAND_ARGS+x}" ] && [ $INPUT_DEPLOYMENT_MODE = 'docker-compose' ] ; then - execute_ssh "${DEPLOYMENT_COMMAND} $INPUT_PRE_DEPLOYMENT_COMMAND_ARGS" 2>&1 - fi - - execute_ssh ${DEPLOYMENT_COMMAND} "$INPUT_ARGS" 2>&1 -else - echo "Connecting to $INPUT_REMOTE_DOCKER_HOST... Command: ${DEPLOYMENT_COMMAND} ${INPUT_ARGS}" - ${DEPLOYMENT_COMMAND} ${INPUT_ARGS} 2>&1 +if ! [ -z "${INPUT_STACK_FILE_NAME+x}" ] && ! [ -z "$INPUT_STACK_FILE_NAME" ]; then + DEPLOYMENT_COMMAND="$DEPLOYMENT_COMMAND -f ${INPUT_STACK_FILE_NAME//,/ -f }" fi +if ! [ -z "${INPUT_ENV_FILE_NAME+x}" ] && ! [ -z "$INPUT_ENV_FILE_NAME" ]; then + DEPLOYMENT_COMMAND="$DEPLOYMENT_COMMAND --env-file ${INPUT_ENV_FILE_NAME//,/ --env-file }" +fi +# DEPLOYMENT_COMMAND_OPTIONS="" + +echo "Connecting to $INPUT_REMOTE_DOCKER_HOST... Command: ${DEPLOYMENT_COMMAND} ${INPUT_ARGS}" +${DEPLOYMENT_COMMAND} ${INPUT_ARGS} 2>&1 \ No newline at end of file diff --git a/renovate.json b/renovate.json deleted file mode 100644 index f45d8f1..0000000 --- a/renovate.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "config:base" - ] -}