Skip to main content

Overview

The post-start.sh script runs every time the development container starts. It verifies the workspace, builds it if necessary, and provides quick start instructions. Location: .devcontainer/post-start.sh Execution: Automatically run by postStartCommand in devcontainer.json Runtime:
  • First run: 2-3 minutes (full build)
  • Subsequent runs: < 5 seconds (skip build)

Script structure

Initialization

#!/bin/bash
set -e

echo "=========================================="
echo "Post-start: Building TurtleBot3 workspace"
echo "=========================================="
Sets strict error handling and displays banner.

Environment setup

source /opt/ros/jazzy/setup.bash
cd /workspace/turtlebot3_ws
Sources ROS2 Jazzy and navigates to workspace.

Filesystem synchronization

sleep 2
Purpose: Waits for filesystem to fully synchronize Why needed: Some mount types (especially on Windows) may have delayed file availability

Package verification

PACKAGE_COUNT=$(find src/ -name "package.xml" 2>/dev/null | wc -l)

if [ "$PACKAGE_COUNT" -eq 0 ]; then
    # Try ls method for Windows mounts
    PACKAGE_COUNT=$(ls src/*/package.xml 2>/dev/null | wc -l)
fi

echo "Found $PACKAGE_COUNT ROS2 packages"

if [ "$PACKAGE_COUNT" -eq 0 ]; then
    echo "[ERROR] No packages found!"
    echo "Something went wrong with post-create.sh"
    echo "The container may not work correctly."
    exit 1
fi
Verification steps:
  1. Try to find packages using find command
  2. If no packages found, try ls method (Windows compatibility)
  3. Report count
  4. Exit with error if no packages found
Why two methods: Windows mounts sometimes don’t work well with find, so ls provides a fallback.

Build status check

if [ -f "install/setup.bash" ]; then
    source install/setup.bash
    
    if ros2 pkg list | grep -q turtlebot3; then
        echo "[OK] Workspace already built"
        
        echo ""
        echo "=========================================="
        echo "[OK] TurtleBot3 Jazzy ready!"
        echo "=========================================="
        echo ""
        echo "Quick start:"
        echo "  tb3_empty  - Launch empty world"
        echo "  tb3_teleop - Keyboard control"
        echo "  VNC: http://localhost:6080 (password: ros)"
        echo "=========================================="
        exit 0
    fi
fi
Logic:
  1. Check if install/setup.bash exists
  2. Source it if it does
  3. Verify TurtleBot3 packages are available
  4. If yes: Skip build and exit successfully
  5. If no: Continue to build phase
Performance optimization: Avoids unnecessary rebuilds on container restart.

Workspace build

echo "Building workspace... (first time: 2-3 minutes)"
echo ""

rm -rf build install log

colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release

if [ $? -ne 0 ]; then
    echo ""
    echo "[ERROR] Build failed!"
    exit 1
fi
Build process:
  1. Display estimated build time
  2. Clean previous build artifacts
  3. Run colcon build with optimized settings
  4. Check exit status
  5. Exit with error if build fails
Build flags:
  • --symlink-install: Create symlinks instead of copying files (faster iteration)
  • --cmake-args -DCMAKE_BUILD_TYPE=Release: Optimized release build

Build verification

echo ""
echo "[OK] Build successful!"
source install/setup.bash

echo ""
echo "TurtleBot3 packages:"
ros2 pkg list | grep turtlebot3
Verification:
  1. Source the newly built workspace
  2. List all TurtleBot3 packages
  3. Provides visual confirmation of what was built
Expected packages:
  • turtlebot3
  • turtlebot3_bringup
  • turtlebot3_cartographer
  • turtlebot3_description
  • turtlebot3_fake_node
  • turtlebot3_gazebo
  • turtlebot3_navigation2
  • turtlebot3_node
  • turtlebot3_teleop
  • turtlebot3_example (if available)

Success message

echo ""
echo "=========================================="
echo "[OK] TurtleBot3 Jazzy ready!"
echo "=========================================="
echo ""
echo "Quick start:"
echo "  tb3_empty  - Launch empty world"
echo "  tb3_teleop - Keyboard control"
echo "  VNC: http://localhost:6080 (password: ros)"
echo "=========================================="
Provides immediate guidance on how to start using the environment.

Execution flow

Exit codes

CodeMeaning
0Success (workspace ready)
1Error (no packages or build failed)

Build optimization

--symlink-install
Benefits:
  • Faster development iteration
  • No need to rebuild when editing Python scripts or launch files
  • Reduces disk space usage
How it works: Instead of copying files to install/, creates symlinks to src/

Release build

--cmake-args -DCMAKE_BUILD_TYPE=Release
Benefits:
  • Optimized code generation
  • Better runtime performance
  • Smaller binary sizes
Trade-off: Harder to debug (no debug symbols)

Common scenarios

First container start

# Full build process
[Post-start] Found 15 packages
[Post-start] Building workspace... (2-3 minutes)
[colcon output...]
[Post-start] Build successful!
[Post-start] TurtleBot3 packages:
  turtlebot3
  turtlebot3_gazebo
  ...
[Post-start] TurtleBot3 Jazzy ready!

Container restart

# Skip build
[Post-start] Found 15 packages
[Post-start] Workspace already built
[Post-start] TurtleBot3 Jazzy ready!

After modifying source code

Container restart will skip the build. To rebuild:
# Use the cb alias
cb
Or manually:
cd /workspace/turtlebot3_ws
colcon build --symlink-install

Troubleshooting

No packages found error

[ERROR] No packages found!
Something went wrong with post-create.sh
Cause: post-create.sh didn’t run successfully or repositories weren’t cloned Solution:
bash /workspace/turtlebot3_ws/.devcontainer/post-create.sh

Build failed error

[ERROR] Build failed!
Cause: Missing dependencies or compilation errors Solution:
# Update dependencies
rosdep update
rosdep install --from-paths src --ignore-src -r -y

# Try building again
cb

Build succeeds but packages not found

Cause: Workspace not sourced Solution:
sb  # source /workspace/turtlebot3_ws/install/setup.bash

Long build times on subsequent runs

Cause: Clean build is triggered instead of incremental Solution: The script only does a clean build on first run. For manual builds, avoid rm -rf build install log and just run:
colcon build --symlink-install

Performance considerations

Build time factors

FactorImpact
Number of CPU coresHigher = faster
Disk I/O speedSSD much faster than HDD
Available RAMLow RAM = slower builds
Network mountLocal disk faster than network

Parallel builds

Colcon automatically uses parallel builds. To limit:
colcon build --parallel-workers 2

Integration with development workflow

  1. Container start: post-start.sh ensures workspace is ready
  2. Development: Edit code in src/
  3. Build: Use cb alias
  4. Source: Use sb alias
  5. Test: Run your nodes/launch files
  6. Iterate: Repeat steps 2-5

Build docs developers (and LLMs) love