waitup - Wait for TCP Ports & HTTP Services | Docker/Kubernetes Ready
The Modern Port Checker and Service Health Monitor for DevOps
waitup is a powerful TCP port checker and service health monitor that waits for services to become available. Essential for Docker, Kubernetes, CI/CD pipelines, and microservices orchestration. Replace wait-for-it, dockerize, and other dependency management tools with a single, fast, reliable solution.
📖 Table of Contents
- 🚀 Why waitup?
- 📊 vs Other Tools
- 🎯 Common Use Cases
- ⚙️ Installation
- 📘 Usage Examples
- ❓ FAQ
- 🔧 Quick Solutions
- 📚 Resources
🚀 Why waitup? The Best Port Checker for Modern DevOps
Perfect for developers who need to:
- Wait for database startup in Docker containers
- Check if port is open before starting services
- Monitor service health in Kubernetes clusters
- Ensure service dependencies are ready in CI/CD
- Test HTTP endpoints with custom headers and status codes
⚡ Key Advantages Over Alternatives
- ✅ TCP & HTTP Support: Check ports and HTTP endpoints with custom headers
- ✅ Multiple Service Monitoring: Wait for any or all services simultaneously
- ✅ Smart Retry Logic: Exponential backoff with configurable intervals
- ✅ Rich Output Options: JSON, verbose, and quiet modes for any workflow
- ✅ Container Optimized: Alpine Docker images under 10MB
- ✅ Production Ready: Built with Rust for speed, safety, and reliability
📊 waitup vs Other Tools
Choose the best port checker and service health monitor:
| Feature | waitup | dockerize | wait-on | wait-for-it |
|---|---|---|---|---|
| Language | Rust 🦀 | Go | Node.js | Bash |
| HTTP Support | ✅ Full | ✅ Basic | ✅ Basic | ❌ None |
| Custom Headers | ✅ Yes | ❌ No | ❌ No | ❌ No |
| JSON Output | ✅ Yes | ❌ No | ❌ No | ❌ No |
| Multiple Targets | ✅ Any/All | ❌ No | ✅ Basic | ❌ No |
| DNS Resolution | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
| Binary Size | ~6MB | ~8MB | N/A | N/A |
| Shell Completions | ✅ Yes | ❌ No | ❌ No | ❌ No |
| Library Support | ✅ Rust | ❌ No | ❌ No | ❌ No |
| Docker Ready | ✅ Alpine | ✅ Yes | ✅ Yes | ✅ Yes |
🎯 Common Use Cases - When to Use waitup
Database Startup in Docker
# Wait for PostgreSQL before running migrations
# Wait for multiple databases
Kubernetes Init Containers
# Wait for external services before pod starts
CI/CD Pipeline Dependencies
# Ensure test services are ready
Microservices Health Checks
# Wait for API dependencies with custom headers
Docker Compose Service Dependencies
services:
app:
depends_on:
- db-ready
command:
db-ready:
image: waitup:alpine
command:
Installation
Prerequisites
- Rust toolchain (1.70.0 or later)
- Git for cloning the repository
- Docker (optional, for containerized usage)
Quick Start
The fastest way to get started with waitup:
# Clone and install in one step
&& &&
# Verify installation
Installation Methods
📦 From Source (Recommended)
# 1. Clone the repository
# 2. Build and install
# 3. Verify installation
🐳 Docker
Option 1: Use pre-built image from source
# Build the standard image
# Test it works
Option 2: Use Alpine variant (smaller size)
# Build Alpine image (recommended for production)
# Test it works
Option 3: Use in your Dockerfile
# Multi-stage build example
FROM rust:1.70 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/waitup /usr/local/bin/waitup
ENTRYPOINT ["waitup"]
🔧 Development Setup
For contributing or development:
# Clone with full history
# Install development dependencies
# Run tests
# Install for development
Post-Installation Setup
Shell Completions
Enhance your command-line experience with auto-completions:
# Bash (system-wide)
# Bash (user-specific)
# Zsh
# Fish
# PowerShell (Windows)
Environment Configuration
Set default values to avoid repetitive flags:
# Add to your shell profile (.bashrc, .zshrc, etc.)
# Now you can use shorter commands
Verification
Confirm everything is working:
# Check version
# Test basic functionality
# Verify completions (if installed)
Troubleshooting
Command not found after installation:
# Ensure Cargo's bin directory is in your PATH
Permission denied for shell completions:
# Use user-specific directories instead of system-wide
Docker build fails:
# Ensure you have the latest base images
Usage
Basic TCP Connection
# Wait for a service to be ready
# With timeout and custom interval
DNS Resolution
# Works with hostnames
Multiple Targets
# Wait for all services (default)
# Wait for any service to be ready
HTTP Health Checks
# HTTP endpoint health check
# Custom status code expectation
# With custom headers (authentication, etc.)
Command Execution
# Run command after successful connection
# Multiple services before command
Progress and Verbose Output
# Verbose mode with progress information
# Quiet mode (no output)
# JSON output for CI/CD integration
Exponential Backoff
# Custom backoff configuration
Environment Variables
Configure defaults using environment variables:
Exit Codes
0: Success - all targets are reachable1: Timeout - failed to connect within timeout period2: Invalid arguments or configuration3: Command execution failed (when using--syntax)
Examples
Docker Compose
services:
app:
image: myapp
depends_on:
- db
command:
db:
image: postgres
Kubernetes Init Container
initContainers:
- name: waitup-db
image: waitup:latest
command:
CI/CD Pipeline
# Wait for test database before running tests
Microservices Health Check
# Wait for multiple dependencies
Time Format
Supports human-readable durations:
30s- 30 seconds2m- 2 minutes1h30m- 1 hour 30 minutes500ms- 500 milliseconds
Development
- Fork the repository
- Create a feature branch
- Run tests:
cargo test - Submit a pull request
Advanced Features
Retry Limits and Timeouts
# Limit retry attempts
# Custom connection timeout per attempt
JSON Output for Automation
# Perfect for CI/CD pipelines
|
# Example JSON output:
{
{
}
}
Library Usage
You can use waitup as a Rust library in your applications. Check the source code and documentation in the repository for API details.
Docker Usage
As a Kubernetes Init Container
apiVersion: v1
kind: Pod
spec:
initContainers:
- name: waitup-deps
image: waitup:alpine
command:
args:
containers:
- name: app
image: myapp:latest
In Docker Compose
version: "3.8"
services:
app:
image: myapp:latest
depends_on:
db-ready:
condition: service_completed_successfully
db-ready:
image: waitup:alpine
command:
depends_on:
- postgres
postgres:
image: postgres:15
Configuration Options
| Option | Environment Variable | Description |
|---|---|---|
--timeout |
WAITUP_TIMEOUT |
Total timeout (default: 30s) |
--interval |
WAITUP_INTERVAL |
Initial retry interval (default: 1s) |
--max-interval |
- | Maximum retry interval (default: 30s) |
--connection-timeout |
- | Per-attempt timeout (default: 10s) |
--retry-limit |
- | Maximum retry attempts |
--expect-status |
- | Expected HTTP status (default: 200) |
❓ Frequently Asked Questions
How do I wait for a database to start in Docker?
Use waitup database:5432 --timeout 60s -- your-app-command to wait for PostgreSQL, MySQL, or any database before starting your application.
What's the best way to check if a port is open?
Returns exit code 0 if successful, 1 if timeout, 2 for invalid arguments.
How do I wait for multiple services before starting my app?
# Wait for ALL services (default)
# Wait for ANY service to be ready
Can waitup replace wait-for-it in Docker containers?
Yes! waitup is a modern replacement with better features:
- ✅ HTTP health checks (wait-for-it only does TCP)
- ✅ JSON output for automation
- ✅ Multiple target strategies
- ✅ Custom headers for authenticated endpoints
- ✅ Smaller binary size (~6MB vs bash dependency)
How do I wait for HTTP services with authentication?
Does waitup work with IPv6 addresses?
Yes! waitup supports both IPv4 and IPv6 through Rust's standard networking stack. Use IPv6 addresses normally: waitup [::1]:8080
What's the difference between waitup and dockerize?
| Feature | waitup | dockerize |
|---|---|---|
| HTTP Headers | ✅ Yes | ❌ No |
| JSON Output | ✅ Yes | ❌ No |
| Multiple Strategies | ✅ Any/All | ❌ Sequential |
| Language | Rust | Go |
| Binary Size | ~6MB | ~8MB |
How do I troubleshoot "connection refused" errors?
- Check the service is running:
docker psorkubectl get pods - Verify the port: Use
--verboseflag to see connection attempts - Increase timeout: Services might take longer to start
- Check networking: Ensure containers can reach each other
Can I use waitup in Kubernetes init containers?
Absolutely! Perfect for waiting for external dependencies:
initContainers:
- name: wait-for-db
image: waitup:alpine
command:
How do I wait for a service to be completely ready, not just accepting connections?
Use HTTP health checks instead of TCP:
# Instead of: waitup api:8080
# Use health endpoint:
🔧 Quick Solutions for Common Problems
"Connection Refused" Error
# Problem: Service not accepting connections yet
# Solution: Increase timeout and add verbose logging
# For Docker: Ensure containers are on same network
Service Takes Too Long to Start
# Problem: Default timeout too short
# Solution: Increase timeout and interval
Docker Compose Dependencies Not Working
# Problem: App starts before database ready
# Solution: Use waitup in entrypoint
services:
app:
entrypoint:
depends_on:
- postgres
Kubernetes Pod Won't Start
# Problem: External dependencies not ready
# Solution: Add waitup init container
initContainers:
- name: wait-deps
image: waitup:alpine
command:
HTTP Health Check Failing
# Problem: API returns 503 during startup
# Solution: Wait for specific status or use different endpoint
# OR
CI/CD Pipeline Timeouts
# Problem: Tests failing because services not ready
# Solution: Add explicit wait with JSON output
if [; then ; fi
📚 Related Tools and Resources
- Docker Compose Wait Strategies - Official Docker guidance
- Kubernetes Init Containers - Pod initialization patterns
- Health Check Patterns - Microservices health monitoring
- 12-Factor App Dependencies - Dependency management best practices
Migration Guides
- From wait-for-it: Replace
./wait-for-it.sh host:portwithwaitup host:port - From dockerize: Replace
dockerize -wait tcp://host:portwithwaitup host:port - From wait-on: Replace
wait-on tcp:host:portwithwaitup host:port - Request Migration Guide - Need help migrating?
Contributing
We welcome contributions! Please see CONTRIBUTING.md for details.
Performance
Built with Rust for high performance, low memory usage, and fast startup times.
Security
waitup follows security best practices:
- Runs as non-root user in containers
- No sensitive data logging
- Minimal attack surface
- Regularly updated dependencies
See SECURITY.md for vulnerability reporting.
License
MIT License - see LICENSE file for details.
Acknowledgments
- Inspired by dockerize
- Built with Rust and Tokio
- Thanks to all contributors!