From 3153c010caeecef1e6208b017c09ac2de04fd640 Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Sat, 17 Aug 2024 16:09:20 +0200 Subject: [PATCH] (feature): init --- LICENSE.md | 21 +++++ README.md | 196 +++++++++++++++++++++++++++++++++++++++++++++++ src/Dockerfile | 32 ++++++++ src/build.bat | 7 ++ src/build.ps1 | 48 ++++++++++++ src/build.sh | 59 ++++++++++++++ src/storage.conf | 7 ++ 7 files changed, 370 insertions(+) create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 src/Dockerfile create mode 100644 src/build.bat create mode 100644 src/build.ps1 create mode 100644 src/build.sh create mode 100644 src/storage.conf diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..3af1574 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Maksym Sadovnychyy (MAKS-IT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e86e499 --- /dev/null +++ b/README.md @@ -0,0 +1,196 @@ +# Podman Container Project + +## Overview + +This repository contains the configuration and scripts for building a container image designed to perform Docker image building tasks using either Docker or Podman, similar to tools like Kaniko. The primary goal of this project is to provide a secure and efficient environment for building Docker images, with configurations tailored to support rootless containerization and flexibility in choosing the container runtime. + +## Features + +- **Rootless Containerization**: The container is configured to run as a non-root user, enhancing security. +- **Container Runtime Flexibility**: Supports both Docker and Podman as the container runtime. Docker is the default, but you can easily switch to Podman using a flag. +- **Customizable Image Name**: Set the image name directly in the script to match your needs. +- **Customizable Storage Configuration**: Configured with `fuse-overlayfs` for storage management, suitable for rootless environments. +- **Automated Build and Push**: Scripts provided to automate the build and push process of Docker images to a specified container registry. + +## Repository Structure + +- **build.bat**: Batch script for initiating the build process on Windows environments. It triggers the PowerShell script `build.ps1`. +- **build.ps1**: PowerShell script that supports selecting between Docker and Podman as the container runtime, creates a `config.json` file for authentication, builds the container image, and pushes it to the specified container registry. +- **build.sh**: Bash script that supports selecting between Docker and Podman as the container runtime, creates a `config.json` file for authentication, builds the container image, and pushes it to the specified container registry. +- **Dockerfile**: Dockerfile for creating the container image. The container is configured with a non-root user and necessary storage settings. +- **storage.conf**: Configuration file for storage settings, utilizing the `fuse-overlayfs` driver for rootless operation. + +## Prerequisites + +- **Podman/Docker**: Ensure that either Podman or Docker is installed on your system. +- **Environment Variables**: The `CR_MAKS_IT` environment variable is used in the examples for pushing images to the registry. + +### Generating and Setting the `CR_MAKS_IT` Environment Variable + +Create a base64-encoded string of your `username:password` and set it as a permanent environment variable on your system. Here’s how: + +#### Linux/Unix + +1. **Create the Base64-Encoded Credentials**: + - Open a terminal and run the following command to encode your `username:password` in base64: + ```bash + echo -n 'username:password' | base64 + ``` + - This will output a base64-encoded string, for example: + ``` + dXNlcm5hbWU6cGFzc3dvcmQ= + ``` + +2. **Set the Encoded String as a Permanent Environment Variable**: + - Open your shell profile in a text editor (e.g., `~/.bashrc`, `~/.zshrc`, etc.): + ```bash + nano ~/.bashrc # Or ~/.zshrc for Zsh users + ``` + - Add the following line to set the `CR_MAKS_IT` environment variable permanently: + ```bash + export CR_MAKS_IT="dXNlcm5hbWU6cGFzc3dvcmQ=" + ``` + - Save the file and reload your shell profile to apply the changes: + ```bash + source ~/.bashrc # Or source ~/.zshrc + ``` + +3. **Verify the Environment Variable**: + - Run the following command to verify that the `CR_MAKS_IT` variable is set: + ```bash + echo $CR_MAKS_IT + ``` + +#### Windows + +1. **Create the Base64-Encoded Credentials**: + - Open a PowerShell prompt and run the following command to encode your `username:password` in base64: + ```powershell + [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("username:password")) + ``` + - This will output a base64-encoded string, for example: + ``` + dXNlcm5hbWU6cGFzc3dvcmQ= + ``` + +2. **Set the Encoded String as a Permanent Environment Variable**: + - To set the environment variable permanently, add the following line to your PowerShell profile (`$PROFILE`): + ```powershell + [System.Environment]::SetEnvironmentVariable("CR_MAKS_IT", "dXNlcm5hbWU6cGFzc3dvcmQ=", "User") + ``` + - Alternatively, you can set it via the Windows GUI: + - Open the Start Menu and search for "Environment Variables". + - Click on "Edit the system environment variables". + - In the System Properties window, click "Environment Variables". + - Under "User variables", click "New" and add: + - **Variable name**: `CR_MAKS_IT` + - **Variable value**: `dXNlcm5hbWU6cGFzc3dvcmQ=` + - Click OK to save the changes. + +3. **Verify the Environment Variable**: + - Run the following command in PowerShell to verify that the `CR_MAKS_IT` variable is set: + ```powershell + echo $env:CR_MAKS_IT + ``` + +## Configuration + +Before using the build scripts, you may need to update the registry URL and image name according to your setup: + +1. **Update the Registry URL and Image Name**: + - Open the `build.ps1` or `build.sh` script in a text editor. + - Update the `registryUrl` variable to match your Docker or Podman registry: + ```powershell + $registryUrl = "your-registry-url.com" + ``` + ```bash + registryUrl="your-registry-url.com" + ``` + - Set the image name directly in the script: + ```powershell + $ImageName = "your-image-name:latest" + ``` + ```bash + imageName="your-image-name:latest" + ``` + +## Usage + +### Windows + +1. Clone the repository: + ```bash + git clone https://your-repository-url/podman.git + cd podman + ``` + +2. Ensure the `CR_MAKS_IT` environment variable is set with your registry authentication token. + +3. Run the build script with Docker (default): + ```cmd + build.bat + ``` + +### Unix/Linux + +1. Clone the repository: + ```bash + git clone https://your-repository-url/podman.git + cd podman + ``` + +2. Ensure the `CR_MAKS_IT` environment variable is set with your registry authentication token. + +3. Run the build script with Docker (default): + ```bash + ./build.sh + ``` + +4. Run the build script with Podman: + ```bash + ./build.sh --container-runtime podman + ``` + +## Contributing + +Contributions are welcome! Please submit issues or pull requests to help improve this project. + +## License + +This project is licensed under the MIT License. See the [LICENSE](LICENSE.md) file for details. + +### Additional Note: Setting Up Podman API on RHEL-Based Distributions (e.g., Fedora) + +If you need to set up the Podman API service to allow remote management of containers, follow these steps: + +1. **Modify the Podman Service File**: + - Open the Podman systemd service file for editing: + ```bash + sudo nano /usr/lib/systemd/system/podman.service + ``` + - Locate the line starting with `ExecStart` and modify it to enable the Podman API over TCP. Change the line to: + ```bash + ExecStart=/usr/bin/podman $LOGGING system service --time=0 tcp:0.0.0.0: + ``` + - This configuration sets up the Podman service to listen on all network interfaces on port ``. + +2. **Reload Systemd Daemon**: + - After making changes to the service file, reload the systemd daemon to apply the modifications: + ```bash + sudo systemctl daemon-reload + ``` + +3. **Restart the Podman Service**: + - Restart the Podman service to activate the changes: + ```bash + sudo systemctl restart podman.service + ``` + +4. **Test the Remote Podman API**: + - You can verify that the Podman API is running and accessible remotely by using `curl`: + ```bash + curl http://:/v1.40/libpod/info + ``` + - Replace `` with the actual IP address of your machine. This command should return information about the Podman service, confirming that the API is accessible. + +>**Note** Exposing the Podman API over TCP without proper security (e.g., TLS, authentication) can pose security risks. Make sure to implement appropriate security measures in production environments. \ No newline at end of file diff --git a/src/Dockerfile b/src/Dockerfile new file mode 100644 index 0000000..71c31c7 --- /dev/null +++ b/src/Dockerfile @@ -0,0 +1,32 @@ +FROM registry.fedoraproject.org/fedora:40 + +# Set environment variables for storage configuration +ENV CONTAINERS_STORAGE_CONF=/etc/containers/storage.conf \ + STORAGE_RUNROOT=/run/containers/storage \ + STORAGE_GRAPHROOT=/var/lib/containers/storage \ + _CONTAINERS_USERNS_CONFIGURED="" + +# Install necessary packages +RUN dnf install -y podman fuse-overlayfs shadow-utils && \ + dnf clean all + +# Set the setuid bit on newuidmap and newgidmap +RUN chmod u+s /usr/bin/newuidmap /usr/bin/newgidmap + +# Create a non-root user and group with UID/GID 1000 +RUN groupadd -g 1000 podmanuser && \ + useradd -u 1000 -g podmanuser -m -s /bin/bash podmanuser && \ + mkdir -p /run/containers/storage /var/lib/containers/storage && \ + chown -R podmanuser:podmanuser /run/containers/storage /var/lib/containers/storage + +# Copy the storage.conf file from the host to the container +COPY storage.conf /etc/containers/storage.conf + +# Switch to the non-root user +USER podmanuser + +# Create a volume for persistent storage if needed +# VOLUME /home/podmanuser/.local/share/containers/storage + +# Run an infinite sleep to keep the container running +CMD ["sleep", "infinity"] diff --git a/src/build.bat b/src/build.bat new file mode 100644 index 0000000..d97e5f2 --- /dev/null +++ b/src/build.bat @@ -0,0 +1,7 @@ +@echo off + +REM Change directory to the location of the script +cd /d %~dp0 + +REM Invoke the PowerShell script (build.ps1) in the same directory +powershell -ExecutionPolicy Bypass -File "%~dp0build.ps1" diff --git a/src/build.ps1 b/src/build.ps1 new file mode 100644 index 0000000..0c2b279 --- /dev/null +++ b/src/build.ps1 @@ -0,0 +1,48 @@ +$containerRuntime = "docker" + +$registryUrl = "cr.maks-it.com" # Modify this line to set your registry URL +$imageName = "library/podman:latest" # Modify this line to set your desired image name + +param( + [string]$ContainerRuntime = $containerRuntime +) + +if ($ContainerRuntime -ne "docker" -and $ContainerRuntime -ne "podman") { + Write-Host "Error: Unsupported container runtime. Use 'docker' or 'podman'." -ForegroundColor Red + exit 1 +} + +$configFile = "$PSScriptRoot\config.json" + +# Retrieve the auth value from the CR_MAKS_IT environment variable +$authValue = $env:CR_MAKS_IT + +# Check if the CR_MAKS_IT environment variable is set and not empty +if (-not $authValue) { + Write-Host "Error: Environment variable CR_MAKS_IT is not set or is empty." -ForegroundColor Red + exit 1 +} + +# Create the JSON object +$json = @{ + auths = @{ + $registryUrl = @{ + auth = $authValue + } + } +} | ConvertTo-Json -Depth 10 -Compress:$false + +# Write the JSON object to the config.json file with 2-space indentation +$jsonString = $json -replace " ", " " +$jsonString | Set-Content -Path $configFile + +# Build the container image +& $ContainerRuntime build -t "$registryUrl/$ImageName" -f Dockerfile . + +# Push the container image using the generated config.json +& $ContainerRuntime --config $configFile push "$registryUrl/$ImageName" + +# Delete the config.json file after the push +Remove-Item -Path $configFile -Force + +Write-Host "Build and push completed successfully." -ForegroundColor Green diff --git a/src/build.sh b/src/build.sh new file mode 100644 index 0000000..9e85df6 --- /dev/null +++ b/src/build.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# Define default container runtime and image name +containerRuntime="docker" + +registryUrl="cr.maks-it.com" # Modify this line to set your registry URL +imageName="library/podman:latest" # Modify this line to set your desired image name + +# Parse command-line arguments for --container-runtime flag only +while [[ "$#" -gt 0 ]]; do + case $1 in + --container-runtime) containerRuntime="$2"; shift ;; + *) echo "Unknown parameter passed: $1"; exit 1 ;; + esac + shift +done + +# Validate the container runtime option +if [[ "$containerRuntime" != "docker" && "$containerRuntime" != "podman" ]]; then + echo "Error: Unsupported container runtime. Use 'docker' or 'podman'." + exit 1 +fi + +configFile="$(pwd)/config.json" + +# Retrieve the auth value from the CR_MAKS_IT environment variable +# Ensure that the CR_MAKS_IT variable is set and not empty +if [ -z "$CR_MAKS_IT" ]; then + echo "Environment variable CR_MAKS_IT is not set." + exit 1 +fi + +authValue="$CR_MAKS_IT" + +# Create the JSON object +json=$(cat < "$configFile" + +# Build the container image +$containerRuntime build -t "$registryUrl/$imageName" -f Dockerfile . + +# Push the container image using the generated config.json +$containerRuntime --config "$configFile" push "$registryUrl/$imageName" + +# Delete the config.json file after the push +rm -f "$configFile" + +echo "Build and push completed successfully." diff --git a/src/storage.conf b/src/storage.conf new file mode 100644 index 0000000..e380d51 --- /dev/null +++ b/src/storage.conf @@ -0,0 +1,7 @@ +[storage] +driver = "overlay" +runroot = "/run/containers/storage" +graphroot = "/var/lib/containers/storage" + +[storage.options] +mount_program = "/usr/bin/fuse-overlayfs"