Skip to content

Commit

Permalink
feat: add network, volumes, cpus, memory
Browse files Browse the repository at this point in the history
  • Loading branch information
bjarneo committed Nov 16, 2024
1 parent 571875d commit f179800
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 21 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ go build -o copepod
| --dockerfile | | Dockerfile | Dockerfile path |
| --build-arg | BUILD_ARGS | | Build arguments (KEY=VALUE) |
| --rollback | | | Rollback to the previous instance |
| --network | DOCKER_NETWORK | | Docker network to connect to |
| --volume | | | Volume mount (host:container) |
| --cpus | DOCKER_CPUS | | Number of CPUs |
| --memory | DOCKER_MEMORY | | Memory limit |

### Example Commands

Expand Down Expand Up @@ -125,6 +129,17 @@ Using build arguments:
./copepod --host example.com --user deploy --build-arg GIT_HASH=$(git rev-parse HEAD)
```

Advanced deployment with resource limits and volumes:

```bash
./copepod --host example.com --user deploy \
--network my-network \
--volume /host/data:/container/data \
--volume /host/config:/container/config \
--cpus 2 \
--memory 1g
```

## Directory Structure

Your project directory should look like this:
Expand Down
87 changes: 66 additions & 21 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ type Config struct {
EnvFile string `json:"envFile"`
Rollback bool `json:"rollback"`
BuildArgs map[string]string `json:"buildArgs"`
Network string `json:"network"`
Volumes []string `json:"volumes"`
CPUs string `json:"cpus"`
Memory string `json:"memory"`
}

// Logger handles logging to both console and file
Expand Down Expand Up @@ -60,36 +64,47 @@ Usage:
Options:
--host Remote host to deploy to
--user SSH user for remote host
--image Docker image name (default: copepod_app)
--image Docker image name (default: app)
--dockerfile Path to the dockerfile (default: Dockerfile)
--tag Docker image tag (default: latest)
--platform Docker platform (default: linux/amd64)
--ssh-key Path to SSH key (default: "")
--container-name Name for the container (default: copepod_app)
--container-name Name for the container (default: app)
--container-port Container port (default: 3000)
--host-port Host port (default: 3000)
--env-file Environment file (default: "")
--build-arg Build arguments (can be specified multiple times, format: KEY=VALUE)
--network Docker network to connect to
--volume Volume mount (can be specified multiple times, format: host:container)
--cpus Number of CPUs (e.g., '0.5' or '2')
--memory Memory limit (e.g., '512m' or '2g')
--rollback Rollback to the previous version
--version Show version information
--help Show this help message
Environment Variables:
HOST Remote host to deploy to
HOST_USER SSH user for remote host
DOCKER_IMAGE_NAME Docker image name
DOCKER_IMAGE_TAG Docker image tag
HOST_PLATFORM Docker platform
SSH_KEY_PATH Path to SSH key
DOCKER_CONTAINER_NAME Name for the container
DOCKER_CONTAINER_PORT Container port
HOST_PORT Host port
DOCKER_CONTAINER_ENV_FILE Environment file
BUILD_ARGS Build arguments (comma-separated KEY=VALUE pairs)
HOST Remote host to deploy to
HOST_USER SSH user for remote host
HOST_PORT Host port
HOST_PLATFORM Docker platform
SSH_KEY_PATH Path to SSH key
DOCKER_IMAGE_NAME Docker image name
DOCKER_IMAGE_TAG Docker image tag
DOCKER_CONTAINER_NAME Name for the container
DOCKER_CONTAINER_PORT Container port
DOCKER_BUILD_ARGS Build arguments (comma-separated KEY=VALUE pairs)
DOCKER_CONTAINER_ENV_FILE Environment file
DOCKER_NETWORK Docker network to connect to
DOCKER_CPUS Number of CPUs
DOCKER_MEMORY Memory limit
Examples:
copepod --host example.com --user deploy
copepod --host example.com --user deploy --build-arg VERSION=1.0.0 --build-arg ENV=prod
copepod --env-file .env.production --build-arg GIT_HASH=$(git rev-parse HEAD)
copepod --host example.com --user deploy --cpus "0.5" --memory "512m"
copepod --rollback # Rollback to the previous version
`

// NewLogger creates a new logger instance
Expand Down Expand Up @@ -149,6 +164,7 @@ func LoadConfig() Config {
var showHelp bool
var showVersion bool
var buildArgs arrayFlags
var volumeFlags arrayFlags

// Initialize BuildArgs map
config.BuildArgs = make(map[string]string)
Expand All @@ -166,6 +182,10 @@ func LoadConfig() Config {
flag.StringVar(&config.HostPort, "host-port", getEnv("HOST_PORT", "3000"), "Host port")
flag.StringVar(&config.EnvFile, "env-file", getEnv("DOCKER_CONTAINER_ENV_FILE", ""), "Environment file")
flag.Var(&buildArgs, "build-arg", "Build argument in KEY=VALUE format (can be specified multiple times)")
flag.Var(&volumeFlags, "volume", "Volume mount in format 'host:container' (can be specified multiple times)")
flag.StringVar(&config.Network, "network", getEnv("DOCKER_NETWORK", ""), "Docker network to connect to")
flag.StringVar(&config.CPUs, "cpus", getEnv("DOCKER_CPUS", ""), "Number of CPUs (e.g., '0.5' or '2')")
flag.StringVar(&config.Memory, "memory", getEnv("DOCKER_MEMORY", ""), "Memory limit (e.g., '512m' or '2g')")
flag.BoolVar(&showHelp, "help", false, "Show help message")
flag.BoolVar(&config.Rollback, "rollback", false, "Rollback to previous version")
flag.BoolVar(&showVersion, "version", false, "Show version information")
Expand Down Expand Up @@ -198,7 +218,7 @@ func LoadConfig() Config {
}

// Process build arguments from environment variable
if envBuildArgs := os.Getenv("BUILD_ARGS"); envBuildArgs != "" {
if envBuildArgs := os.Getenv("DOCKER_BUILD_ARGS"); envBuildArgs != "" {
for _, arg := range strings.Split(envBuildArgs, ",") {
parts := strings.SplitN(arg, "=", 2)
if len(parts) == 2 {
Expand All @@ -215,6 +235,9 @@ func LoadConfig() Config {
}
}

// Assign volume flags to config
config.Volumes = []string(volumeFlags)

return config
}

Expand Down Expand Up @@ -521,18 +544,40 @@ func Deploy(config *Config, logger *Logger) error {
}
}

// Prepare remote commands
envFileFlag := ""
if _, err := os.Stat(config.EnvFile); err == nil {
envFileFlag = fmt.Sprintf("--env-file ~/%s", config.EnvFile)
// Prepare container configuration
containerConfig := []string{
"-d",
"--name", config.ContainerName,
"--restart", "unless-stopped",
"-p", fmt.Sprintf("%s:%s", config.HostPort, config.ContainerPort),
}

if config.Network != "" {
containerConfig = append(containerConfig, "--network", config.Network)
}

if config.CPUs != "" {
containerConfig = append(containerConfig, "--cpus", config.CPUs)
}

if config.Memory != "" {
containerConfig = append(containerConfig, "--memory", config.Memory)
}

for _, volume := range config.Volumes {
containerConfig = append(containerConfig, "-v", volume)
}

if config.EnvFile != "" {
containerConfig = append(containerConfig, fmt.Sprintf("--env-file ~/%s", config.EnvFile))
}

containerConfig = append(containerConfig, fmt.Sprintf("%s:%s", config.Image, config.Tag))

remoteCommands := strings.Join([]string{
fmt.Sprintf("docker stop %s || true", config.ContainerName),
fmt.Sprintf("docker rm %s || true", config.ContainerName),
fmt.Sprintf("docker run -d --name %s --restart unless-stopped -p %s:%s %s %s:%s",
config.ContainerName, config.HostPort, config.ContainerPort,
envFileFlag, config.Image, config.Tag),
fmt.Sprintf("docker run %s", strings.Join(containerConfig, " ")),
}, " && ")

// Execute remote commands
Expand Down

0 comments on commit f179800

Please sign in to comment.