From 86bacf9ad5fcffd344417d0b5ad8c37086a72c6f Mon Sep 17 00:00:00 2001 From: Allan Eising Date: Thu, 1 Aug 2024 09:28:48 +0200 Subject: [PATCH] Initial commit --- Dockerfile | 9 ++++++ README.md | 3 ++ action.yml | 48 ++++++++++++++++++++++++++++++ entrypoint.sh | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 action.yml create mode 100755 entrypoint.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..acee95c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM alpine:3.20 + +RUN apk --update add git-crypt git-lfs openssh bash + +WORKDIR /gitea/workspace + +COPY entrypoint.sh . + +ENTRYPOINT ["/gitea/workspace/entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..349f872 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Action to deploy docker projects over SSH + +This is more or less a carbon copy of the git-crypt-ssh-deploy action minus the git crypt. diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..523e4f4 --- /dev/null +++ b/action.yml @@ -0,0 +1,48 @@ +name: Docker-SSH-Deploy +description: Action to deploy docker projects over ssh. +author: "Allan Eising" +branding: + icon: "unlock" + color: "blue" + +inputs: + ssh_private_key: + description: "Private SSH key used for logging into remote system." + required: true + ssh_host: + description: Host to deploy to. + required: true + ssh_port: + description: SSH Port + default: 22 + required: true + ssh_user: + description: Remote user name. + required: true + swarm_mode: + description: Use swarm mode instead of docker compose + default: "false" + required: true + action: + description: Action, i.e., "up" or "down" + default: "up" + required: true + docker_compose_project: + description: Compose project name + required: true + docker_compose_filename: + description: Compose file to use + default: docker-compose.yml + +runs: + using: docker + image: Dockerfile + env: + SSH_PRIVATE_KEY: ${{ inputs.ssh_private_key }} + SSH_HOST: ${{ inputs.ssh_host }} + SSH_PORT: ${{ inputs.ssh_port }} + SSH_USER: ${{ inputs.ssh_user }} + DOCKER_COMPOSE_PROJECT: ${{ inputs.docker_compose_project }} + DOCKER_COMPOSE_FILENAME: ${{ inputs.docker_compose_filename }} + DEPLOY_ACTION: ${{ inputs.action }} + SWARM_MODE: ${{ inputs.swarm_mode }} diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..2d27fc3 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +set -eu + + +log() { + echo ">> [local]" $@ +} + +cleanup() { + set +e + log "Killing ssh agent." + ssh-agent -k + log "Removing workspace archive." + rm -f /tmp/workspace.tar.bz2 +} + +trap cleanup EXIT + +compress_workdir() { + log "Packing workspace into archive to transfer to remove machine." + tar jcvf /tmp/workspace.tar.bz2 --exclude .git --exclude vendor . +} + +start_ssh_agent() { + log "Launching SSH agent" + eval $(ssh-agent -s) + ssh-add <(echo "$SSH_PRIVATE_KEY") +} + +compose_up() { + echo "set -e ; log() { echo '>> [remote]' \$@ ; } ; cleanup() { log 'Removing workspace...'; rm -rf \"\$HOME/workspace\" ; } ; log 'Creating workspace directory...' ; mkdir -p \"\$HOME/workspace\" ; trap cleanup EXIT ; log 'Unpacking workspace...' ; tar -C \"\$HOME/workspace\" -xjv ; log 'Launching docker compose...' ; cd \"\$HOME/workspace\" ; docker compose -f \"$DOCKER_COMPOSE_FILENAME\" -p \"$DOCKER_COMPOSE_PROJECT\" pull ; docker compose -f \"$DOCKER_COMPOSE_FILENAME\" -p \"$DOCKER_COMPOSE_PROJECT\" up -d --remove-orphans --build" +} + +compose_down() { + echo "set -e ; log() { echo '>> [remote]' \$@ ; } ; cleanup() { log 'Removing workspace...'; rm -rf \"\$HOME/workspace\" ; } ; log 'Creating workspace directory...' ; mkdir -p \"\$HOME/workspace\" ; trap cleanup EXIT ; log 'Unpacking workspace...' ; tar -C \"\$HOME/workspace\" -xjv ; log 'Launching docker compose...' ; cd \"\$HOME/workspace\" ; docker compose -f \"$DOCKER_COMPOSE_FILENAME\" -p \"$DOCKER_COMPOSE_PROJECT\" down" +} + +stack_up() { + echo "set -e ; log() { echo '>> [remote]' \$@ ; } ; cleanup() { log 'Removing workspace...'; rm -rf \"\$HOME/workspace\" ; } ; log 'Creating workspace directory...' ; mkdir -p \"\$HOME/workspace/$DOCKER_COMPOSE_PROJECT\" ; trap cleanup EXIT ; log 'Unpacking workspace...' ; tar -C \"\$HOME/workspace/$DOCKER_COMPOSE_PROJECT\" -xjv ; log 'Launching docker stack deploy...' ; cd \"\$HOME/workspace/$DOCKER_COMPOSE_PROJECT\" ; docker stack deploy -c \"$DOCKER_COMPOSE_FILENAME\" --prune \"$DOCKER_COMPOSE_PROJECT\"" +} + +stack_down() { + # It is not at all necessary to transfer and unpack the workspace here, but I'll do it anyway for simplicity's sake. + echo "set -e ; log() { echo '>> [remote]' \$@ ; } ; cleanup() { log 'Removing workspace...'; rm -rf \"\$HOME/workspace\" ; } ; log 'Creating workspace directory...' ; mkdir -p \"\$HOME/workspace/$DOCKER_COMPOSE_PROJECT\" ; trap cleanup EXIT ; log 'Unpacking workspace...' ; tar -C \"\$HOME/workspace/$DOCKER_COMPOSE_PROJECT\" -xjv ; log 'Launching docker stack rm...' ; cd \"\$HOME/workspace/$DOCKER_COMPOSE_PROJECT\" ; docker stack rm \"$DOCKER_COMPOSE_PROJECT\"" +} + +deploy() { + local remote_command + if $SWARM_MODE; then + if [ "$DEPLOY_ACTION" == "up" ]; then + log "Deploying docker swarm stack ${DOCKER_COMPOSE_PROJECT}." + remote_command=$(stack_up) + else + log "Removing docker swarm stack ${DOCKER_COMPOSE_PROJECT}" + remote_command=$(stack_down) + fi + else + if [ "$DEPLOY_ACTION" == "up" ]; then + log "Deploying docker compose project ${DOCKER_COMPOSE_PROJECT}." + remote_command=$(compose_up) + else + log "Removing docker compose project ${DOCKER_COMPOSE_PROJECT}." + remote_command=$(compose_down) + fi + fi + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "$SSH_USER@$SSH_HOST" -p "$SSH_PORT" \ + "$remote_command" \ + < /tmp/workspace.tar.bz2 + +} + +if [ -n "${RUN_DIR:-}" ]; then + cd ${RUN_DIR} + log "Running action from ${RUN_DIR}" +fi + +log "Starting deployment main function." +compress_workdir +start_ssh_agent +deploy