Skip to content

Instantly share code, notes, and snippets.

@victorholt
Created March 7, 2018 18:44
Show Gist options
  • Save victorholt/d124e660131f72d37aaa169a19e1a895 to your computer and use it in GitHub Desktop.
Save victorholt/d124e660131f72d37aaa169a19e1a895 to your computer and use it in GitHub Desktop.
Docker Installer
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"reflect"
"regexp"
"strings"
)
// Standard error checking.
func checkErr(e error, msg ...string) {
if len(msg) > 0 {
fmt.Println(msg[0])
}
if e != nil {
panic(e)
}
}
func stringInArray(value string, arr interface{}) bool {
switch reflect.TypeOf(arr).Kind() {
case reflect.Slice:
s := reflect.ValueOf(arr)
for i := 0; i < s.Len(); i++ {
entry := reflect.Value(s.Index(i)).String()
// fmt.Println(entry)
if strings.Contains(entry, value) {
return true
}
}
}
return false
}
func createImage(prefix string, name string, dockerfilePath string) {
cmd := exec.Command("docker", "build", "-t", prefix+name, "-f", dockerfilePath, ".")
output, err := cmd.CombinedOutput()
cmd.Wait()
checkErr(err, string(output))
fmt.Println(string(output))
}
func removeImage(prefix string, name string) {
cmd := exec.Command("docker", "rmi", prefix+name)
output, err := cmd.CombinedOutput()
cmd.Wait()
checkErr(err, string(output))
}
func restartContainer(prefix string, name string) {
cmd := exec.Command("docker", "restart", prefix+name)
output, err := cmd.CombinedOutput()
cmd.Wait()
checkErr(err, string(output))
}
func stopContainer(prefix string, name string) {
cmd := exec.Command("docker", "stop", prefix+name)
output, err := cmd.CombinedOutput()
cmd.Wait()
checkErr(err, string(output))
}
func removeContainer(prefix string, name string) {
cmd := exec.Command("docker", "rm", prefix+name)
output, err := cmd.CombinedOutput()
cmd.Wait()
checkErr(err, string(output))
}
func updateFileValue(src string, key string, newValue string) {
dat, err := ioutil.ReadFile(src)
checkErr(err)
re := regexp.MustCompile(key)
rdat := re.ReplaceAllString(string(dat), newValue)
checkErr(err)
err = ioutil.WriteFile(src, []byte(rdat), 0755)
checkErr(err)
}
func main() {
workingDir, err := os.Getwd()
checkErr(err)
var appEnv = "dev"
var doBuildWebapp bool = false
var doBuildNginx bool = false
var doBuildDatabase bool = false
// var doBuildApi bool = false
var containerPrefix string = "gs-"
var serverName string = "gamesencha.local"
volumeArr := [...]string{containerPrefix + "webapp-public", containerPrefix + "webapp-data", containerPrefix + "webapp-logs"}
// Update our prefix.
fmt.Print("Your Container Prefix (" + containerPrefix + "): ")
fmt.Scanln(&containerPrefix)
// fmt.Println("Setting up docker containers with prefix: " + containerPrefix)
// Update our application environment.
fmt.Printf("AppEnv (" + appEnv + "): ")
fmt.Scanln(&appEnv)
updateFileValue("./webapp/Dockerfile", "ENV APP_ENV=\".*\"?", "ENV APP_ENV=\""+appEnv+"\"")
fmt.Printf("Enter server name (" + serverName + "): ")
fmt.Scanln(&serverName)
updateFileValue("./webapp/Dockerfile", "ENV GS_BASE_URL=\".*\"?", "ENV GS_BASE_URL=\""+serverName+"\"")
// Grab a list of all images.
cmd := exec.Command("docker", "images")
output, err := cmd.CombinedOutput()
checkErr(err)
dockerImages := strings.Split(string(output), "\n")
// Grab a list of all running containers.
cmd = exec.Command("docker", "ps")
output, err = cmd.CombinedOutput()
checkErr(err)
dockerRunningContainers := strings.Split(string(output), "\n")
// Grab a list of all containers.
cmd = exec.Command("docker", "ps", "-a")
output, err = cmd.CombinedOutput()
checkErr(err)
dockerContainers := strings.Split(string(output), "\n")
// Stop containers.
if stringInArray(containerPrefix+"webserver", dockerRunningContainers) {
stopContainer(containerPrefix, "webserver")
}
if stringInArray(containerPrefix+"api", dockerRunningContainers) {
stopContainer(containerPrefix, "api")
}
if stringInArray(containerPrefix+"webapp", dockerRunningContainers) {
stopContainer(containerPrefix, "webapp")
}
if stringInArray(containerPrefix+"mongodb", dockerRunningContainers) {
stopContainer(containerPrefix, "mongodb")
}
// Build the docker volumes.
// -----------------------------------------------------------------
var buildVolumes string = "n"
var removedAllContainers bool = false
fmt.Print("Would you like to create the webapp volumes? (y/N) ")
fmt.Scanln(&buildVolumes)
if buildVolumes == "y" {
// Delete the containers that exists.
if stringInArray(containerPrefix+"webserver", dockerContainers) {
removeContainer(containerPrefix, "webserver")
}
if stringInArray(containerPrefix+"webapp", dockerContainers) {
removeContainer(containerPrefix, "webapp")
}
if stringInArray(containerPrefix+"api", dockerContainers) {
removeContainer(containerPrefix, "api")
}
if stringInArray(containerPrefix+"mongodb", dockerContainers) {
removeContainer(containerPrefix, "mongodb")
}
removedAllContainers = true
// Grab the list of volumes.
cmd := exec.Command("docker", "volume", "list")
output, err := cmd.CombinedOutput()
checkErr(err)
cmd.Wait()
// Remove any volumes that might already exist.
volumes := strings.Split(string(output), "\n")
for i := range volumes {
for j := range volumeArr {
if strings.Contains(volumes[i], volumeArr[j]) {
fmt.Println("Removing volume: " + volumeArr[j])
cmd := exec.Command("docker", "volume", "rm", volumeArr[j])
err = cmd.Run()
cmd.Wait()
checkErr(err)
}
}
}
// Create our volumes.
for j := range volumeArr {
fmt.Println("Creating volume: " + volumeArr[j])
cmd = exec.Command("docker", "volume", "create", volumeArr[j])
err = cmd.Run()
cmd.Wait()
checkErr(err)
}
fmt.Println("Finished creating volumes")
}
// Build the MongoDB docker container.
// -----------------------------------------------------------------
var buildDatabase string = "n"
if !doBuildWebapp {
fmt.Print("Would you like to build the MongoDB Docker Image? (y/N) ")
fmt.Scanln(&buildDatabase)
}
if buildDatabase == "y" {
doBuildDatabase = true
fmt.Println("Removing old MongoDB containers/images")
if !removedAllContainers && stringInArray(containerPrefix+"mongodb", dockerContainers) {
// Delete the containers that exists.
if stringInArray(containerPrefix+"webserver", dockerContainers) {
removeContainer(containerPrefix, "webserver")
}
if stringInArray(containerPrefix+"webapp", dockerContainers) {
removeContainer(containerPrefix, "webapp")
}
if stringInArray(containerPrefix+"api", dockerContainers) {
removeContainer(containerPrefix, "api")
}
if stringInArray(containerPrefix+"mongodb", dockerContainers) {
removeContainer(containerPrefix, "mongodb")
}
removedAllContainers = true
}
if stringInArray(containerPrefix+"mongodb-img", dockerImages) {
removeImage(containerPrefix, "mongodb-img")
}
fmt.Println("Building MongoDB Server")
createImage(containerPrefix, "mongodb-img", "./mongodb/Dockerfile")
}
// Create the container.
if doBuildDatabase || !stringInArray(containerPrefix+"mongodb", dockerContainers) {
fmt.Println("Creating MongoDB container")
cmd := exec.Command(
"docker",
"run",
"--name", containerPrefix+"mongodb",
"-d",
containerPrefix+"mongodb-img")
output, err := cmd.CombinedOutput()
cmd.Wait()
checkErr(err, string(output))
fmt.Println(string(output))
} else {
// Stop containers.
restartContainer(containerPrefix, "mongodb")
}
// -----------------------------------------------------------------
// Build the Webapp docker container.
// -----------------------------------------------------------------
var buildWebapp string = "n"
fmt.Print("Would you like to build the Webapp Docker Image? (y/N) ")
fmt.Scanln(&buildWebapp)
if buildWebapp == "y" {
doBuildWebapp = true
fmt.Println("Removing old Webapp containers/images")
if !removedAllContainers && stringInArray(containerPrefix+"webapp", dockerContainers) {
removeContainer(containerPrefix, "webapp")
}
if !removedAllContainers && stringInArray(containerPrefix+"api", dockerContainers) {
removeContainer(containerPrefix, "api")
}
if stringInArray(containerPrefix+"webapp-img", dockerImages) {
removeImage(containerPrefix, "webapp-img")
}
fmt.Println("Building Webapp Image")
createImage(containerPrefix, "webapp-img", "./webapp/Dockerfile")
}
// Create the container.
if doBuildWebapp || !stringInArray(containerPrefix+"webapp", dockerContainers) {
// Webapp
fmt.Println("Creating WebApp container" + workingDir)
cmd := exec.Command(
"docker",
"run",
"--name", containerPrefix+"webapp",
"-d",
"-e", "CGO_ENABLED=0",
"-e", "API_SERVER=0",
"-v", workingDir+"/webapp/src/app:/src/app",
"-v", workingDir+"/webapp/src/daemon:/src/daemon",
"-v", workingDir+"/webapp/src/_statics/assets:/src/_statics/assets",
"-v", workingDir+"/webapp/src/_statics/html:/src/_statics/html",
"-v", volumeArr[0]+":/app/public",
"-v", volumeArr[1]+":/app/data",
"-v", volumeArr[2]+":/app/logs",
containerPrefix+"webapp-img")
output, err := cmd.CombinedOutput()
cmd.Wait()
checkErr(err, string(output))
fmt.Println(string(output))
// API
fmt.Println("Creating API container" + workingDir)
cmd = exec.Command(
"docker",
"run",
"--name", containerPrefix+"api",
"-d",
"-e", "CGO_ENABLED=0",
"-e", "API_SERVER=1",
"--link", containerPrefix+"mongodb",
"-v", workingDir+"/webapp/src/app:/src/app",
"-v", workingDir+"/webapp/src/daemon:/src/daemon",
"-v", volumeArr[1]+":/app/data",
"-v", volumeArr[2]+":/app/logs",
containerPrefix+"webapp-img")
output, err = cmd.CombinedOutput()
cmd.Wait()
checkErr(err, string(output))
fmt.Println(string(output))
} else {
// Stop containers.
restartContainer(containerPrefix, "webapp")
restartContainer(containerPrefix, "api")
}
// -----------------------------------------------------------------
// Build the NGINX docker container.
// -----------------------------------------------------------------
var buildServer string = "n"
if !doBuildWebapp {
fmt.Print("Would you like to build the NGINX Docker Image? (y/N) ")
fmt.Scanln(&buildServer)
}
if doBuildWebapp || buildServer == "y" {
doBuildNginx = true
fmt.Println("Removing old NGINX containers/images")
if !removedAllContainers && stringInArray(containerPrefix+"webserver", dockerContainers) {
removeContainer(containerPrefix, "webserver")
}
if stringInArray(containerPrefix+"webserver-img", dockerImages) {
removeImage(containerPrefix, "webserver-img")
}
fmt.Println("Building NGINX Server")
updateFileValue("./webserver/app.conf", "server_name .*?;", "server_name "+serverName+";")
updateFileValue("./webserver/api.conf", "server_name .*?;", "server_name api."+serverName+";")
fmt.Println("Building NGINX @ ServerName:", serverName)
createImage(containerPrefix, "webserver-img", "./webserver/Dockerfile")
}
// Create the container.
if doBuildNginx || !stringInArray(containerPrefix+"webserver", dockerContainers) {
fmt.Println("Creating NGINX container")
cmd := exec.Command(
"docker",
"run",
"--name", containerPrefix+"webserver",
"-d",
"-p", "80:80",
"--link", containerPrefix+"webapp",
"--link", containerPrefix+"api",
"-v", volumeArr[0]+":/app/public",
"-v", volumeArr[1]+":/app/data",
"-v", volumeArr[2]+":/app/logs",
containerPrefix+"webserver-img")
output, err := cmd.CombinedOutput()
cmd.Wait()
checkErr(err, string(output))
fmt.Println(string(output))
} else {
// Stop containers.
restartContainer(containerPrefix, "webserver")
}
// -----------------------------------------------------------------
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment