Skip to content

Instantly share code, notes, and snippets.

@christopher-talke
Last active December 15, 2022 08:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save christopher-talke/11c655de511dd799a1d9c3cf156e7a94 to your computer and use it in GitHub Desktop.
Save christopher-talke/11c655de511dd799a1d9c3cf156e7a94 to your computer and use it in GitHub Desktop.
Docker Deployment via Remote SSH
#!/bin/bash
# Basic Script to Automate Docker Deployment
# - Details for how this script works, see here:
# - https://gist.github.com/christopher-talke/11c655de511dd799a1d9c3cf156e7a94#gistcomment-2935112
# Created By: christopher.talke <christopher.talke@gmail.com>
##### VARIABLES SECTION #####
# Details for Host & Docker Network, example below:
# user=root
# host=112.114.7.123 OR subdomain.domain.com
# networkName=local-connect-app1
user=<REMOTEUSER>
host=<IP OR DNS NAME>
networkName=<DOCKER NETWORK NAME>
# Details for App, example below:
# org=acme
# imageName=app1
# APPShortHand=acme-app1
org=<ORGNAME>
imageName=<APP IMAGENAME>
APPshortHand=<SHORTHAND FOR CONTAINER>
# Details for Reverse Proxy, example below:
# reverseProxyName=acme-cont-rp01
# RPshortHand=acme-rp01
reverseProxyName=<REVERSE PROXY NAME>
RPshortHand=<SHORTHAND FOR RP>
########################
##### SCRIPT START #####
########################
# Compress Folder Contents (uses .gitignore values)
git archive -o app.tar.gz master
# SSH and create deployment folder in the users root '~/'
ssh $user@$host "mkdir -p auto-deploy"
# Transfer Files to said folder '~/auto-deploy'
scp app.tar.gz .env $user@$host:~/auto-deploy
# Connect to Server
ssh $user@$host << EOF
cd ~/auto-deploy
tar xvzf app.tar.gz
# Creates internal network that will be used to connect the RP and APP
docker network create --internal $networkName
# Build, Remove and Deploy Container
docker build -t $org/$imageName:latest .
docker container rm -f $imageName\_prod
docker run \
--name $imageName\_prod \
-dit \
--restart unless-stopped \
$org/$imageName:latest
# Connects App to Reverse Proxy via Network 'local-connect'
docker network connect \
--link $imageName\_prod:$APPshortHand \
$networkName \
$reverseProxyName
# Connects Reverse Proxy to App via Network 'local-connect'
docker network connect \
--link $reverseProxyName:$RPshortHand \
local-connect \
$imageName\_prod
# Cleanup Files
rm -r ~/auto-deploy/*
# Check Docker
docker ps
# Disconnect
exit
EOF
@christopher-talke
Copy link
Author

christopher-talke commented Jun 5, 2019

High-Level Diagram Overview of Script

alt text


Example of Variables in a Production App

Here is a example of how I use the variables section in a production deployment...

...

user=autoDeploy
host=tlk-lxc-host01.christopher-talke.com
networkName=local-connect

org=tlk
imageName=quote-tool
APPshortHand=TLK-QT

reverseProxyName=TLK-CONT-NGINX01
RPshortHand=TLK-RP

...

Missing Puzzle Pieces

This deployment script is reliant on 'puzzle pieces' not seen within the script, this includes:

  • Setup and installation of docker on the remote host

Details on how to install docker on a remote host, see here:
https://docs.docker.com/install

  • Setup and configuration of docker image for the repository

Here are some good resources on how to dockerize your image
https://www.youtube.com/watch?v=6aBsjT5HoGY
https://docs.docker.com/engine/examples
https://hackernoon.com/how-to-dockerize-any-application-b60ad00e76da

  • Setup and configuration of NGINX with a Reverse Proxy configuration, I tend to use the following Docker image:

https://hub.docker.com/r/linuxserver/letsencrypt
Please Note You could just use the normal NGINX image, however, you'll need to spend time getting LetsEncrypt setup, which can be a pain if you don't know what you are doing...

  • Setting up an SSH Key with the remote host, here is a good guide I used
  • Setting up Git / Git Bash on your local machine, see below resources for help

https://gitforwindows.org or https://git-scm.com

  • Using .env files with your source code, if you have multiple environments or dynamic secrets you need to use environment variables will probably come in handy. Here is some useful resources to wrap your head around this

https://www.youtube.com/watch?v=HRBNeERE5PU (NodeJS Specific)
https://medium.com/chingu/an-introduction-to-environment-variables-and-how-to-use-them-f602f66d15fa (High-Level Overview)
https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables


To Do

  • Setup error handling for required dependencies, both on the local machine and remote host
  • Setup error handling for things going wrong (pre-exisiting docker link and/or network)
  • Add --env=staging || --env=production option to deploy multiple environments
  • Add --silent option to silence output
  • Add Colours and UX Stuff to the output
  • Add a --help flag, might not be necessary, but would be nice...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment