From a43de98578d04fd24c351fd97ea46ffa52367da3 Mon Sep 17 00:00:00 2001 From: mrkmntal Date: Sat, 1 Nov 2025 20:00:21 -0400 Subject: [PATCH] Refactor Option 13: Streamline bash script to Docker image conversion workflow --- README.md | 4 +++- main.cpp | 19 +++++++++++++------ option13_script.sh | 6 ++++++ tux-dock | Bin 0 -> 78816 bytes 4 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 option13_script.sh create mode 100755 tux-dock diff --git a/README.md b/README.md index 8e055d7..2258dd1 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ It offers a clean, interactive menu for common Docker operations like pulling im - ๐Ÿ”น **Interactive container management** โ€” start, stop, remove, or attach to containers with simple numbered menus. - ๐Ÿ”น **Port mapping made clear** โ€” automatically prompts for and explains host โ†” container port bindings. - ๐Ÿ”น **Image operations** โ€” pull, list, and delete Docker images. +- ๐Ÿ”น **Script-to-image workflow** โ€” turn a bash setup script into a Dockerfile and build the resulting image in one go. - ๐Ÿ”น **Quick MySQL setup** โ€” spin up a MySQL container with version, password, and port configuration in seconds. - ๐Ÿ”น **Get container IP address** โ€” cleanly retrieves and displays only the containerโ€™s assigned IP. - ๐Ÿ”น **Modern C++ design** โ€” built with classes, minimal dependencies, and clear abstractions. @@ -59,7 +60,8 @@ Tux-Dock: Docker Management Menu 10. Attach Shell to Running Container 11. Spin Up MySQL Container 12. Get Container IP Address -13. Exit +13. Create Dockerfile & Build Image from Bash Script +14. Exit ``` Each action guides you through the required steps. diff --git a/main.cpp b/main.cpp index 2bb7995..16b6fe9 100644 --- a/main.cpp +++ b/main.cpp @@ -197,7 +197,7 @@ void DockerManager::showContainerIP() { } void DockerManager::createDockerfile() { - string baseImage, bashScriptPath, outputFile; + string baseImage, bashScriptPath, outputFile, imageName; cout << "Enter base Docker image (e.g., ubuntu:22.04): "; cin >> baseImage; @@ -243,8 +243,17 @@ void DockerManager::createDockerfile() { scriptFile.close(); cout << "Dockerfile created successfully: " << outputFile << "\n"; - cout << "You can edit it or build it with:\n"; - cout << " docker build -t myimage -f " << outputFile << " .\n"; + cout << "Enter image name to build from this Dockerfile (e.g., myimage): "; + cin >> imageName; + + if (imageName.empty()) { + cout << "No image name provided. Skipping build.\n"; + return; + } + + cout << "Building Docker image '" << imageName << "'...\n"; + runCommand("docker build -t " + imageName + " -f " + outputFile + " ."); + cout << "Docker build command executed.\n"; } // ---------------- Menu ---------------- @@ -268,7 +277,7 @@ int main() { << "10. Attach Shell to Running Container\n" << "11. Spin Up MySQL Container\n" << "12. Get Container IP Address\n" - << "13. Create Dockerfile from Bash Script\n" + << "13. Create Dockerfile & Build Image from Bash Script\n" << "14. Exit\n" << "----------------------------------\n" << "Choose an option: "; @@ -297,5 +306,3 @@ int main() { } } } - - diff --git a/option13_script.sh b/option13_script.sh new file mode 100644 index 0000000..3020570 --- /dev/null +++ b/option13_script.sh @@ -0,0 +1,6 @@ +#!/bin/bash +echo "Setting up application directory" +mkdir -p /app/bin +echo '#!/bin/bash' > /app/bin/run.sh +echo 'echo "Hello from Tux-Dock generated image"' >> /app/bin/run.sh +chmod +x /app/bin/run.sh diff --git a/tux-dock b/tux-dock new file mode 100755 index 0000000000000000000000000000000000000000..5312b2c39c6ce2ec1631e6f36f6104cccc9eba88 GIT binary patch literal 78816 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