rfswift image build
Build a container image from a YAML recipe.
rfswift image build creates your own container image from a short YAML recipe. Use it when you want an RF Swift image with extra tools or settings baked in, without writing a Dockerfile.
The most common use builds from a recipe file:
rfswift image build -r my-recipe.yamlrfswift image build is the v4 spelling. The older rfswift build still works, takes the same flags and prints a notice with the new name. See the command tree.
Synopsis
rfswift image build [-r RECIPE_FILE] [-t TAG] [--no-cache]Options
| Flag | What it does | Default | Example |
|---|---|---|---|
-r, --recipe STRING |
Path to the recipe file | rfswift-recipe.yaml |
-r my-recipe.yaml |
-t, --tag STRING |
Use this tag instead of the one in the recipe | From the recipe | -t my_custom:v1 |
--no-cache |
Build without Docker’s layer cache | false | --no-cache |
Examples
Build from rfswift-recipe.yaml in the current directory:
rfswift image buildBuild from a specific recipe:
rfswift image build -r custom-sdr-recipe.yamlBuild with a different tag than the one in the recipe:
rfswift image build -r my-recipe.yaml -t my_image:testRebuild everything from scratch, ignoring the cache:
rfswift image build -r recipe.yaml --no-cacheA custom SDR image
This recipe starts from sdr_light, adds three tools and cleans up the package cache. Write it to a file, then build it:
cat > sdr-custom.yaml << 'EOF'
name: my_sdr_custom
tag: sdr_custom:v1.0
base: penthertz/rfswift_resolute:sdr_light
packages:
- gqrx-sdr
- inspectrum
- urh
scripts:
- apt-get clean
- rm -rf /var/lib/apt/lists/*
EOF
rfswift image build -r sdr-custom.yamlRecipe file format
Structure
A recipe has three required keys (name, tag, base) and several optional sections:
# Image metadata
name: my_custom_image
tag: my_custom:v1.0
base: penthertz/rfswift_resolute:sdr_full
# Package installation
packages:
- package1
- package2
- package3
# Environment variables
environment:
- VAR1=value1
- VAR2=value2
# File copies
files:
- src: local/file.txt
dest: /container/path/
# Custom commands
commands:
- command1
- command2
# Cleanup scripts
scripts:
- cleanup_command1
- cleanup_command2
# Working directory
workdir: /root/workspaceComplete example
This recipe adds SDR and cellular tools to sdr_full, sets environment variables, copies a few files in and prepares working folders:
name: advanced_sdr_setup
tag: advanced_sdr:v2.0
base: penthertz/rfswift_resolute:sdr_full
# Install additional tools
packages:
- gqrx-sdr
- inspectrum
- urh
- universal-radio-hacker
- gr-gsm
- gr-lte
# Set environment
environment:
- SDR_BUFFER_SIZE=262144
- DISPLAY=:0
- PULSE_SERVER=tcp:127.0.0.1:34567
# Copy custom files
files:
- src: ./configs/sdr-config.conf
dest: /root/.config/
- src: ./scripts/startup.sh
dest: /usr/local/bin/
- src: ./tools/custom-tool
dest: /opt/tools/
# Post-installation commands
commands:
- chmod +x /usr/local/bin/startup.sh
- chmod +x /opt/tools/custom-tool
- ln -s /opt/tools/custom-tool /usr/local/bin/
- mkdir -p /root/captures
- mkdir -p /root/analysis
# Cleanup
scripts:
- apt-get clean
- rm -rf /var/lib/apt/lists/*
- rm -rf /tmp/*
- rm -rf /root/.cache/*
# Set working directory
workdir: /root/workspaceRecipe sections
name (required)
A name for the image, used for documentation.
name: my_custom_sdrtag (required)
The Docker tag of the image you build, in repository:tag form.
tag: my_custom_sdr:v1.0The -t flag overrides it:
rfswift image build -r recipe.yaml -t override_tag:v2base (required)
The image to start from, usually an RF Swift image.
base: penthertz/rfswift_resolute:sdr_fullCommon base images:
penthertz/rfswift_resolute:sdr_full: the complete SDR stackpenthertz/rfswift_resolute:sdr_light: the essential SDR toolspenthertz/rfswift_resolute:bluetooth: Bluetooth toolspenthertz/rfswift_resolute:wifi: Wi-Fi toolspenthertz/rfswift_resolute:hardware: hardware security tools
packages (optional)
APT packages to install.
packages:
- gqrx-sdr
- inspectrum
- wireshark
- python3-pipenvironment (optional)
Environment variables to set in the image.
environment:
- PATH=/opt/tools:$PATH
- CUSTOM_VAR=value
- DEBUG=1files (optional)
Files to copy into the image. src is relative to the recipe file; dest is an absolute path in the image.
files:
- src: ./local/config.txt
dest: /root/.config/
- src: ./scripts/
dest: /opt/scripts/
- src: ./tool
dest: /usr/local/bin/toolcommands (optional)
Commands to run during the build.
commands:
- chmod +x /usr/local/bin/script.sh
- pip3 install custom-package
- git clone https://github.com/user/repo /opt/repo
- make -C /opt/repo installscripts (optional)
Cleanup commands, run at the end of the build.
scripts:
- apt-get clean
- rm -rf /var/lib/apt/lists/*
- rm -rf /tmp/*
- history -cworkdir (optional)
The default working directory of the image.
workdir: /root/projectsFiles must exist next to the recipe
Every file in the files section must exist, relative to the recipe file’s location. Prefix paths with ./ for clarity, and check they are there before you build.
When to use --no-cache
Docker reuses cached layers, so repeated builds are fast. Use --no-cache when you want every package updated and every command run again.
Troubleshooting
“recipe file not found”
The full error is Error: recipe file not found. RF Swift looks for rfswift-recipe.yaml in the current directory unless you pass -r. Check the file is there, or give its full path:
ls -l rfswift-recipe.yaml
pwd
rfswift image build -r /full/path/to/recipe.yaml“invalid YAML”
The full error is Error parsing recipe: invalid YAML. The usual causes are a missing colon after a key, wrong indentation, or tabs instead of spaces. Check the syntax, and look for tabs (shown as ^I):
yamllint recipe.yaml
cat -A recipe.yaml | grep "^I"“base image not found”
The full error is Error: base image not found. Pull the base image first, then check its exact name in your recipe:
rfswift image pull -i penthertz/rfswift_resolute:sdr_full
rfswift image local
grep "^base:" recipe.yaml“Unable to locate package”
The full error is E: Unable to locate package. Check the package name first:
apt-cache search package-nameIf the name is right, refresh the package lists before installing: add an update step at the start of packages, or run the install from the commands section:
packages:
- apt-update # Add this first
commands:
- apt-get update
- apt-get install -y your-package“COPY failed: no such file or directory”
The full error looks like COPY failed: stat /src/file: no such file or directory. A src path in files does not exist relative to the recipe. Check the file and the folder layout:
ls -l ./configs/file.txt
tree .Then use the correct relative path:
files:
- src: ./configs/file.txt # Relative to recipe location
dest: /root/.config/The build does not pick up your changes
Docker’s cache reused an old layer. Rebuild without the cache, or clear Docker’s build cache:
rfswift image build -r recipe.yaml --no-cache
docker builder prune