From f6e6d4dba9608d71f87df422520b1b86c99d4f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rcio=20Fernandes?= Date: Sat, 6 Sep 2025 23:32:31 +0000 Subject: [PATCH] ssh server alpha --- ...e.deploy.yml => docker-image-deploy.yaml} | 11 +- docker/{ => ssh-client}/Dockerfile | 2 +- docker/ssh-server/.env | 1 + docker/ssh-server/.env.dev | 6 + docker/ssh-server/.vscode/launch.json | 27 ++++ docker/ssh-server/.vscode/tasks.json | 26 ++++ docker/ssh-server/Dockerfile | 48 +++++++ docker/ssh-server/Dockerfile.dev | 75 +++++++++++ docker/ssh-server/README.md | 24 ++++ docker/ssh-server/app/.gitignore | 1 + docker/ssh-server/app/globals.py | 25 ++++ docker/ssh-server/app/init.py | 43 +++++++ docker/ssh-server/app/main.py | 14 ++ docker/ssh-server/app/requirements.txt | 1 + docker/ssh-server/app/sshserver.py | 120 ++++++++++++++++++ docker/ssh-server/app/users.py | 89 +++++++++++++ docker/ssh-server/build.env | 1 + docker/ssh-server/build.env.dev | 2 + docker/ssh-server/scripts/build.sh | 92 ++++++++++++++ docker/ssh-server/scripts/run-dev.sh | 39 ++++++ 20 files changed, 643 insertions(+), 4 deletions(-) rename .gitea/workflows/{ docker-image.deploy.yml => docker-image-deploy.yaml} (67%) rename docker/{ => ssh-client}/Dockerfile (55%) create mode 100644 docker/ssh-server/.env create mode 100644 docker/ssh-server/.env.dev create mode 100644 docker/ssh-server/.vscode/launch.json create mode 100644 docker/ssh-server/.vscode/tasks.json create mode 100644 docker/ssh-server/Dockerfile create mode 100644 docker/ssh-server/Dockerfile.dev create mode 100644 docker/ssh-server/README.md create mode 100644 docker/ssh-server/app/.gitignore create mode 100644 docker/ssh-server/app/globals.py create mode 100644 docker/ssh-server/app/init.py create mode 100644 docker/ssh-server/app/main.py create mode 100644 docker/ssh-server/app/requirements.txt create mode 100644 docker/ssh-server/app/sshserver.py create mode 100644 docker/ssh-server/app/users.py create mode 100644 docker/ssh-server/build.env create mode 100644 docker/ssh-server/build.env.dev create mode 100755 docker/ssh-server/scripts/build.sh create mode 100755 docker/ssh-server/scripts/run-dev.sh diff --git a/.gitea/workflows/ docker-image.deploy.yml b/.gitea/workflows/ docker-image-deploy.yaml similarity index 67% rename from .gitea/workflows/ docker-image.deploy.yml rename to .gitea/workflows/ docker-image-deploy.yaml index 72ca033..38a7f3b 100644 --- a/.gitea/workflows/ docker-image.deploy.yml +++ b/.gitea/workflows/ docker-image-deploy.yaml @@ -22,11 +22,16 @@ jobs: username: ${{ secrets.GITLIMBO_DOCKER_REGISTRY_USERNAME }} password: ${{ secrets.GITLIMBO_DOCKER_REGISTRY_PASSWORD }} - - name: Build and push Docker images + - name: Build and push ssh-client Docker images id: push uses: docker/build-push-action@v6 with: context: . - file: ${{gitea.workspace}}/docker/Dockerfile + file: ${{gitea.workspace}}/docker/ssh-client/Dockerfile push: true - tags: git.limbosolutions.com/kb/ssh-client \ No newline at end of file + tags: git.limbosolutions.com/kb/ssh-client + + - name: Build ssh-server images + run: | + cd ${{gitea.workspace}}/ssh-server + BUILD_ENV=prod ./scripts/build.sh \ No newline at end of file diff --git a/docker/Dockerfile b/docker/ssh-client/Dockerfile similarity index 55% rename from docker/Dockerfile rename to docker/ssh-client/Dockerfile index 0dc2c5c..5edccc7 100644 --- a/docker/Dockerfile +++ b/docker/ssh-client/Dockerfile @@ -1,4 +1,4 @@ FROM ubuntu:latest RUN apt-get update && apt-get upgrade -y -RUN apt-get install -y openssh-client --fix-missing \ No newline at end of file +RUN apt-get install -y openssh-server --fix-missing \ No newline at end of file diff --git a/docker/ssh-server/.env b/docker/ssh-server/.env new file mode 100644 index 0000000..9c44a86 --- /dev/null +++ b/docker/ssh-server/.env @@ -0,0 +1 @@ +SSH_PORT="2222" diff --git a/docker/ssh-server/.env.dev b/docker/ssh-server/.env.dev new file mode 100644 index 0000000..b142e9e --- /dev/null +++ b/docker/ssh-server/.env.dev @@ -0,0 +1,6 @@ +#DEBUG_FILE="sshserver.py" +#DEBUG_FILE="sshserver.py" +#DEBUG_FILE="users.py" +SSH_SERVER_ENABLED="true" +CONTAINER_TAG="ssh-server:dev" + diff --git a/docker/ssh-server/.vscode/launch.json b/docker/ssh-server/.vscode/launch.json new file mode 100644 index 0000000..61ffc31 --- /dev/null +++ b/docker/ssh-server/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + "version": "0.2.0", + "configurations": [ + + { + "name": "Python: Remote Attach", + "type": "debugpy", + "request": "attach", + "connect": { + "host": "localhost", + "port": 5678 + }, + "pathMappings": [ + { + "localRoot": "${workspaceFolder}/app", + "remoteRoot": "/app" + } + ], + "justMyCode": false, + "preLaunchTask": "debug" + } + ] +} + + + + diff --git a/docker/ssh-server/.vscode/tasks.json b/docker/ssh-server/.vscode/tasks.json new file mode 100644 index 0000000..e4dc805 --- /dev/null +++ b/docker/ssh-server/.vscode/tasks.json @@ -0,0 +1,26 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "debug", + "type": "shell", + "command": "RUN_ENV=dev ./scripts/run-dev.sh", + "problemMatcher": [], + "detail": "Runs the container with environment from .env" + }, + { + "label": "build: debug", + "type": "shell", + "command": "BUILD_ENV=dev ./scripts/build.sh", + "problemMatcher": [], + "detail": "Builds docker image with debug requirements" + }, + { + "label": "build: production", + "type": "shell", + "command": "./scripts/build.sh", + "problemMatcher": [], + "detail": "Builds docker image for productions" + } + ] +} \ No newline at end of file diff --git a/docker/ssh-server/Dockerfile b/docker/ssh-server/Dockerfile new file mode 100644 index 0000000..8bbd184 --- /dev/null +++ b/docker/ssh-server/Dockerfile @@ -0,0 +1,48 @@ +# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +# ┃ 🐳 Dockerfile: Multi-Stage Build for Python + SSH App ┃ +# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + +# ──────────────── Stage 1: Base ──────────────── +# Base image using Debian Bullseye +FROM debian:bullseye as base + + +# Suppress interactive prompts during package installation +ENV DEBIAN_FRONTEND=noninteractive + +# Install core dependencies: +# - Python 3 and pip +# - OpenSSH server for remote access +# - sudo for privilege escalation +RUN apt-get update && \ + apt-get install -y \ + python3 \ + python3-pip \ + openssh-server \ + sudo && \ + mkdir /var/run/sshd && \ + apt-get clean + +# Create config directory for app (can be used by dev/prod stages) +RUN mkdir -p /etc/app/config + +# ──────────────── Stage 2: Prod ──────────────── +# Production stage inherits from base +FROM base AS prod + +# Copy full app code into image (self-contained) +COPY app/ /app + +# Set working directory +WORKDIR /app +RUN pip install --no-cache-dir -r requirements.txt + + +ENV CONFIGURATION=Production +ENV DEBUG=False + +# Default command for production container +CMD ["python3", "/app/main.py"] + + +#EXPOSE 22 diff --git a/docker/ssh-server/Dockerfile.dev b/docker/ssh-server/Dockerfile.dev new file mode 100644 index 0000000..8487540 --- /dev/null +++ b/docker/ssh-server/Dockerfile.dev @@ -0,0 +1,75 @@ +# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +# ┃ 🐳 Dockerfile: Multi-Stage Build for Python + SSH App /(dev) ┃ +# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + +# ──────────────── Stage 1: Base ──────────────── +# Base image using Debian Bullseye +FROM debian:bullseye as base + +# Suppress interactive prompts during package installation +ENV DEBIAN_FRONTEND=noninteractive + +# Install core dependencies: +# - Python 3 and pip +# - OpenSSH server for remote access +# - sudo for privilege escalation +RUN apt-get update && \ + apt-get install -y \ + python3 \ + python3-pip \ + openssh-server \ + sudo && \ + mkdir /var/run/sshd && \ + apt-get clean + +# Create config directory for app (can be used by dev/prod stages) +RUN mkdir -p /etc/app/config + +# ──────────────── Stage 2: Dev ──────────────── +# Development stage inherits from base +FROM base AS dev + + + +# Install debugging tools (e.g. debugpy for remote debugging) +RUN echo "Installing debug tools..." && \ + pip install debugpy + + +# Set working directory +WORKDIR /app + +# Install Python dependencies from requirements.txt +COPY app/requirements.txt requirements.txt + +# This allows caching of dependencies even if app code is mounted +RUN pip install --no-cache-dir -r requirements.txt + +EXPOSE 5678 + + +# runtime environment +ENV CONFIGURATION=Debug +ENV DEBUG=True + +# Default command for dev container +CMD ["python3", "/app/main.py"] + + + +# ──────────────── Optional: User & SSH Setup ──────────────── +# Uncomment below to create a non-root user and configure SSH access + +# Create a non-root user with sudo privileges +# RUN useradd -m -s /bin/bash devuser && \ +# echo "devuser:devpass" | chpasswd && \ +# usermod -aG sudo devuser + +# Configure SSH server to allow password login and specific users +# RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \ +# sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \ +# echo "AllowUsers devuser" >> /etc/ssh/sshd_config + +# Expose SSH port + + diff --git a/docker/ssh-server/README.md b/docker/ssh-server/README.md new file mode 100644 index 0000000..fe0e2c2 --- /dev/null +++ b/docker/ssh-server/README.md @@ -0,0 +1,24 @@ +# ssh-server + +## dev and testing + +```bash + + +``` + +```bash +podman container exec -it ssh-server-dev bash - +``` + +```bash +ssh root@0.0.0.0 -p 2333 + +``` + + +# ssh-server + +## dev and testing + +Using vscode, check .vscode folder build and debug tasks as launch settings. diff --git a/docker/ssh-server/app/.gitignore b/docker/ssh-server/app/.gitignore new file mode 100644 index 0000000..ed8ebf5 --- /dev/null +++ b/docker/ssh-server/app/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/docker/ssh-server/app/globals.py b/docker/ssh-server/app/globals.py new file mode 100644 index 0000000..c247b06 --- /dev/null +++ b/docker/ssh-server/app/globals.py @@ -0,0 +1,25 @@ +import os +import yaml +def is_debugging(): return os.getenv("CONFIGURATION") == "Debug" + + +file_path="/etc/app/config.yaml" +config=None + +def config_exits(): + global config + return config is not None + +def sshserver_enabled(): + return not is_debugging() or os.getenv("SSH_SERVER_ENABLED") == "true" + +def get_config(): + global config + return config + +def load_config(): + global config + if os.path.exists(file_path): + with open(file_path, 'r') as f: + config = yaml.safe_load(f) + diff --git a/docker/ssh-server/app/init.py b/docker/ssh-server/app/init.py new file mode 100644 index 0000000..f5af968 --- /dev/null +++ b/docker/ssh-server/app/init.py @@ -0,0 +1,43 @@ +import os +import subprocess +import globals +import sys + +def main(): + + if globals.is_debugging(): + import debugpy + debugpy.listen(("0.0.0.0", 5678)) + print("INFO: Waiting for debugger to attach...") + debugpy.wait_for_client() + print("INFO: Debugger attached") + else: + print("👉 starting setup") + + + globals.load_config() + setup_container() + + if globals.is_debugging(): + debug_file = os.getenv("DEBUG_FILE", "") + if debug_file and os.path.isfile(debug_file): + print(f"🔍 Running debug file: {debug_file}") + subprocess.run(["python3", debug_file], check=True, stdout=sys.stdout, stderr=sys.stderr) + + return False + elif debug_file: + print(f"⚠️ DEBUG_FILE set but file not found: {debug_file}") + return True + +def setup_container(): + marker_file = "/var/run/container_initialized" + if not os.path.exists(marker_file): + print("INFO: First-time setup running...") + # 👉 Your one-time setup logic here + + # Create the marker file + with open(marker_file, "w") as f: + f.write("initialized\n") + else: + print("TRACE: Already initialized. Skipping setup.") + diff --git a/docker/ssh-server/app/main.py b/docker/ssh-server/app/main.py new file mode 100644 index 0000000..6a4c3d9 --- /dev/null +++ b/docker/ssh-server/app/main.py @@ -0,0 +1,14 @@ +import globals +import subprocess +import init +import users +import sshserver + +if init.main(): + users.load() + sshserver.load() + + + + + diff --git a/docker/ssh-server/app/requirements.txt b/docker/ssh-server/app/requirements.txt new file mode 100644 index 0000000..ca12944 --- /dev/null +++ b/docker/ssh-server/app/requirements.txt @@ -0,0 +1 @@ +PyYAML>=5.4 \ No newline at end of file diff --git a/docker/ssh-server/app/sshserver.py b/docker/ssh-server/app/sshserver.py new file mode 100644 index 0000000..46f3bef --- /dev/null +++ b/docker/ssh-server/app/sshserver.py @@ -0,0 +1,120 @@ +import yaml +import subprocess +import crypt +import os +import globals +import sys + +config_file_path='/etc/ssh/sshd_config' + +def set_sshd_option(file_path: str, key: str, value: str) -> None: + updated = False + lines = [] + + with open(file_path, 'r') as f: + for line in f: + if line.strip().startswith(key): + lines.append(f"{key} {value}\n") + updated = True + else: + lines.append(line) + + if not updated: + lines.append(f"{key} {value}\n") + + with open(file_path, 'w') as f: + f.writelines(lines) + + print(f"✅ Updated {key} to '{value}' in {file_path}") + +def load(): + setup() + print_server_config() + if globals.sshserver_enabled(): + start_server() + + + + +def setup_certs(): + certs=[ + "/etc/ssh/certs/ssh_host_rsa_key", + "/etc/ssh/certs/ssh_host_ecdsa_key", + "/etc/ssh/certs/ssh_host_ed25519_key" + ] + if not os.path.exists("/etc/ssh/certs"): + os.makedirs("/etc/ssh/certs") + print(f"📁 Created folder: /etc/ssh/certs") + + if not os.listdir("/etc/ssh/certs"): + subprocess.run([ + "ssh-keygen", "-t", "rsa", "-f", + "/etc/ssh/certs/ssh_host_rsa_key" + ], check=True, stdout=sys.stdout, stderr=sys.stderr) + print(f"✅ RSA key and certificate created:🔑 /etc/ssh/certs/ssh_host_rsa_key") + + subprocess.run([ + "ssh-keygen", "-t", "ecdsa", "-f", + "/etc/ssh/certs/ssh_host_ecdsa_key" + ], check=True, stdout=sys.stdout, stderr=sys.stderr) + print(f"✅ RSA key and certificate created:🔑 /etc/ssh/certs/ssh_host_ecdsa_key") + + subprocess.run([ + "ssh-keygen", "-t", "ed25519", "-f", + "/etc/ssh/certs/ssh_host_ed25519_key" + ], check=True, stdout=sys.stdout, stderr=sys.stderr) + print(f"✅ RSA key and certificate created:🔑 /etc/ssh/certs/ssh_host_ed25519_key") + + certLines=[] + for cert in certs: + if os.path.exists(cert): + certLines.append(f"HostKey {cert}\n") + else: + print(f"❌ HostKey path not found {cert}") + if not certLines: RuntimeError("❌ Missing server certificates configuration. Bind Volume to /etc/ssh/certs") + + lines = [] + with open(config_file_path, 'r') as f: + for line in f: + if line.strip().startswith("HostKey"): + continue # remove existing HostKey lines + lines.append(line) + + for key in certLines: + print(f"✅ HostKey path updated to use {key}") + lines.append(key) + + with open(config_file_path, 'w') as f: + f.writelines(lines) + + + +def setup(): + global config_file_path + + serverConfig = globals.get_config().get("server") if globals.config_exits() else None + + if not serverConfig: + return + + optionsConfig = serverConfig.get("options") + if optionsConfig: + for option in optionsConfig: + set_sshd_option(config_file_path, option, optionsConfig[option]) + setup_certs() + + + +def print_server_config(): + with open(config_file_path, 'r') as f: + content = f.read() + print(content) + + +def start_server(): + print("INFO: Starting ssh server.") + subprocess.run(["/usr/sbin/sshd", "-D", "-e"]) + +if __name__ == "__main__": + globals.load_config() + load() \ No newline at end of file diff --git a/docker/ssh-server/app/users.py b/docker/ssh-server/app/users.py new file mode 100644 index 0000000..bc9b7b3 --- /dev/null +++ b/docker/ssh-server/app/users.py @@ -0,0 +1,89 @@ +import yaml +import subprocess +import crypt +import os +import globals +import pwd +# users: +# - username: alice +# authorized_keys: publich ssh key +# - username: bob +# password: hunter2 + + +def user_exists(username): + try: + pwd.getpwnam(username) + return True + except KeyError: + return False + +def create_user(uid, username ,password, shell="/bin/bash"): + + if not shell: shell = "/bin/bash" + + if not username: + return + + useradd_cmd = [ + 'useradd', + '-m', + '-s', shell, + ] + + if uid: useradd_cmd.append("-u " + str(uid)) + if password: useradd_cmd.append("-p" + crypt.crypt(password, crypt.mksalt(crypt.METHOD_SHA512))) + useradd_cmd.append(username) + + try: + subprocess.run(useradd_cmd + , check=True) + print(f"✅ User '{username}' created with shell '{shell}' and password.") + except subprocess.CalledProcessError as e: + print(f"❌ Failed to create user '{username}': {e}") + + + + +def setup_ssh(username, public_key): + ssh_dir = f"/home/{username}/.ssh" + auth_keys = os.path.join(ssh_dir, "authorized_keys") + uid = pwd.getpwnam(username).pw_uid + gid = pwd.getpwnam(username).pw_gid + + os.makedirs(ssh_dir, mode=0o700, exist_ok=True) + + # Check if key already exists + key_exists = False + if os.path.exists(auth_keys): + with open(auth_keys, "r") as f: + existing_keys = f.read().splitlines() + key_exists = public_key.strip() in existing_keys + + if not key_exists: + with open(auth_keys, "a") as f: + f.write(public_key.strip() + "\n") + print(f"🔐 SSH key added for '{username}'.") + else: + print(f"⚠️ SSH key already exists for '{username}'. Skipping.") + + os.chmod(ssh_dir, 0o700) + os.chmod(auth_keys, 0o600) + os.chown(ssh_dir, uid, gid) + os.chown(auth_keys, uid, gid) + +def load(): + users = globals.get_config()["users"] if globals.config_exits() else None + if users: + for user in users: + if not user_exists(user.get('username')): + create_user(user.get('uid'), user.get('username'),user.get('password'), user.get('shell')) + if user.get('public_keys'): + for public_key in user.get('public_keys'): + setup_ssh(user.get('username'), public_key) + + + +if __name__ == "__main__": + globals.load_config() + load() diff --git a/docker/ssh-server/build.env b/docker/ssh-server/build.env new file mode 100644 index 0000000..fe70d78 --- /dev/null +++ b/docker/ssh-server/build.env @@ -0,0 +1 @@ +BUILD_ENV_IMAGE_TAG="git.limbosolutions.com/kb/ssh-server:latest" diff --git a/docker/ssh-server/build.env.dev b/docker/ssh-server/build.env.dev new file mode 100644 index 0000000..4139c69 --- /dev/null +++ b/docker/ssh-server/build.env.dev @@ -0,0 +1,2 @@ +BUILD_ENV_IMAGE_TAG="ssh-server:dev" +BUILD_ENV_DOCKER_FILE="Dockerfile.dev" diff --git a/docker/ssh-server/scripts/build.sh b/docker/ssh-server/scripts/build.sh new file mode 100755 index 0000000..0fa122f --- /dev/null +++ b/docker/ssh-server/scripts/build.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +# ┃ 🐳 Podman Build Script with Layered .env Configuration ┃ +# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +# +# This script builds a Podman image using a specified Dockerfile, +# dynamically injecting build-time environment variables from a +# prioritized set of `.env` files. +# +# ──────────────── Behavior ──────────────── +# - Loads variables from the following files (in order): +# build.env +# build.env.${BUILD_ENV} +# build.local.env +# +# - Later files override earlier ones (last-write-wins) +# - Variables starting with `BUILD_ENV` are excluded from build args +# +# ──────────────── Required Environment Variables ──────────────── +# - BUILD_ENV: (optional) Environment name (e.g. dev, prod) +# - BUILD_ENV_DOCKER_FILE: Dockerfile to use (default: Dockerfile) +# - BUILD_ENV_IMAGE_TAG: Tag to assign to the built image +# +# ──────────────── Example Usage ──────────────── +# BUILD_ENV=dev BUILD_ENV_IMAGE_TAG=myapp:dev ./build.sh +# BUILD_ENV=prod BUILD_ENV_DOCKER_FILE=Dockerfile.prod BUILD_ENV_IMAGE_TAG=myapp:prod ./build.sh +# +# ──────────────── Output ──────────────── +# - Logs each loaded file +# - Displays the final build command +# - Executes the podman build with all resolved --build-arg flags +# +# Author: Márcio +# Last Updated: September 2025 + +POSSIBLE_BUILD_ARGS_FILES="\ + build.env \ +" + + +if [ -n "${BUILD_ENV+x}" ]; then + POSSIBLE_BUILD_ARGS_FILES="$POSSIBLE_BUILD_ARGS_FILES \ + build.env.${BUILD_ENV} \ + " +fi + +POSSIBLE_BUILD_ARGS_FILES="$POSSIBLE_BUILD_ARGS_FILES \ +.build.local" + + +# load variables into this context +declare -A build_args_map +BUILD_ARGS="" + +for file in $POSSIBLE_BUILD_ARGS_FILES; do + if [ -f "$file" ]; then + echo "🔧 Loading variables from $file" + set -a + source "$file" + set +a + while IFS= read -r line || [ -n "$line" ]; do + # Skip comments and empty lines + [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue + + # Extract key and value + key="$(echo "$line" | cut -d= -f1 | xargs)" + value="$(echo "$line" | cut -d= -f2- | xargs)" + + # Skip keys that start with BUILD_ENV + if [[ "$key" == BUILD_ENV* ]]; then + echo "Skipping key starting with BUILD_ENV: $key" + continue + fi + build_args_map["$key"]="$value" + done < "$file" + else + echo "⚠️ Skipping missing file: $file" + fi +done + +for key in "${!build_args_map[@]}"; do + BUILD_ARGS+=" --build-arg $key=${build_args_map[$key]}" +done +# sets default docker file +BUILD_ENV_DOCKER_FILE="${BUILD_ENV_DOCKER_FILE:-Dockerfile}" + +echo "Build env: $BUILD_ENV" +echo "Build DockerFile: $BUILD_ENV_DOCKER_FILE" +echo "Build Tag: $BUILD_ENV_IMAGE_TAG" +echo "Running: podman build -f $BUILD_ENV_DOCKER_FILE $BUILD_ARGS -t $BUILD_ENV_IMAGE_TAG ." +podman build -f $BUILD_ENV_DOCKER_FILE $BUILD_ARGS -t $BUILD_ENV_IMAGE_TAG . + diff --git a/docker/ssh-server/scripts/run-dev.sh b/docker/ssh-server/scripts/run-dev.sh new file mode 100755 index 0000000..89460c8 --- /dev/null +++ b/docker/ssh-server/scripts/run-dev.sh @@ -0,0 +1,39 @@ +#!/bin/bash +RUN_ENV=dev + +POSSIBLE_ENV_FILES="\ + .env +" + +if [ -n "${RUN_ENV+x}" ]; then + POSSIBLE_ENV_FILES="$POSSIBLE_ENV_FILES \ + .env.${RUN_ENV} \ + " +fi + +POSSIBLE_ENV_FILES="$POSSIBLE_ENV_FILES \ +.env.local" + +for file in $POSSIBLE_ENV_FILES; do + if [ -f "$file" ]; then + echo "🔧 Loading variables from $file" + set -a + source "$file" + set +a + else + echo "⚠️ Skipping missing file: $file" + fi +done +# Ignored if uing dev docker file: +# - DEBUG_FILE +# - SSH_SERVER_ENABLED +podman container run -d --rm \ + -e DEBUG_FILE="${DEBUG_FILE}" \ + -e SSH_SERVER_ENABLED="${SSH_SERVER_ENABLED:-false}" \ + -p 2222:22 \ + -p 5678:5678 \ + -v ./app:/app \ + -v ./local/config:/etc/app \ + -v ./local/server-certs:/etc/ssh/certs \ + ${CONTAINER_TAG} + \ No newline at end of file