bootapp

command module
v1.0.20 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 8, 2026 License: MIT Imports: 1 Imported by: 0

README

bootapp

Docker CLI Plugin for multi-project Docker networking made easy.

Automatically manages:

  • Unique subnet allocation per project (prevents conflicts)
  • /etc/hosts entries for containers with DOMAIN configuration
  • SSL certificates for domains in SSL_DOMAINS (auto-generated, system trusted)
  • Smart route setup for macOS (checks connectivity before adding routes)

Installation

Method 1: Using Homebrew (macOS)
brew install yejune/tap/bootapp

Homebrew automatically:

  • Downloads and builds the latest version
  • Installs as Docker CLI plugin (docker bootapp)
  • Installs standalone binary (bootapp)
  • Checks dependencies
Method 2: Using install script (Linux/macOS)
# Clone the repository
git clone https://github.com/yejune/bootapp.git
cd bootapp

# Run install script
bash install.sh

The install script automatically:

  • Checks for Go and Docker
  • Builds the binary
  • Installs to ~/.docker/cli-plugins/bootapp (Docker plugin)
  • Installs to /usr/local/bin/bootapp (standalone binary)
  • Checks platform-specific dependencies
Method 3: Using go install
go install github.com/yejune/bootapp@latest
bootapp install

Or build locally:

git clone https://github.com/yejune/bootapp.git
cd bootapp
go build
./bootapp install

The install command automatically:

  • Copies binary to ~/.docker/cli-plugins/bootapp
  • Installs standalone binary to /usr/local/bin/bootapp
  • Sets executable permissions
  • Checks platform dependencies
Method 4: Manual installation
make build
cp build/bootapp ~/.docker/cli-plugins/bootapp
chmod +x ~/.docker/cli-plugins/bootapp
sudo cp build/bootapp /usr/local/bin/bootapp
sudo chmod +x /usr/local/bin/bootapp

Usage

Start containers
# Auto-detect docker-compose.yml
docker bootapp up

# Specify compose file
docker bootapp -f docker-compose.local.yml up

If multiple compose files are found, you'll be prompted to select interactively:

Select compose file:
▸ docker-compose.yml
  docker-compose.local.yml
  docker-compose.prod.yml

Use ↑/↓ arrows to navigate, Enter to select

Supported file patterns:

  • docker-compose.yml, docker-compose.yaml
  • docker-compose.*.yml, docker-compose.*.yaml (e.g., docker-compose.local.yml)
  • compose.yml, compose.yaml

Options:

  • -d, --detach: Run in background (default: true)
  • --no-build: Don't build images
  • --pull: Pull images before starting
  • -F, --force-recreate: Force recreate containers + regenerate SSL certificates

This will:

  1. Allocate unique subnet for the project (172.18-31.x.x range)
  2. Parse docker-compose file for DOMAIN/SSL_DOMAINS configuration
  3. Generate SSL certificates for SSL_DOMAINS (if not exists)
  4. Install certificates to system trust store (macOS Keychain / Linux ca-certificates)
  5. Start containers with docker-compose up
  6. Discover container IPs from default compose network
  7. Add /etc/hosts entries for containers with domain config
  8. Setup routing if needed (macOS)
Stop containers
docker bootapp down
docker bootapp -f docker-compose.local.yml down

Options:

  • -v, --volumes: Remove volumes
  • --remove-orphans: Remove orphan containers
  • --keep-hosts: Keep /etc/hosts entries
  • --remove-config: Remove project from global config
List projects
docker bootapp ls

Domain Configuration

Supported Environment Variables

All of these environment variables are used for both:

  • Host machine access (/etc/hosts)
  • Container-to-container access (Docker network aliases)

Supported variables (duplicates removed, each supports single, comma, space, or newline separated values):

  • DOMAIN
  • DOMAINS
  • SSL_DOMAINS
  • APP_DOMAIN
  • VIRTUAL_HOST (nginx-proxy compatible)
services:
  app:
    image: nginx
    environment:
      SSL_DOMAINS: |
        myapp.local
        www.myapp.local

  db:
    image: mysql:8
    environment:
      DOMAIN: db.local db-backup.local

  redis:
    image: redis
    # No DOMAIN = no /etc/hosts entry (IP only)
Container-to-Container Communication

Domains set via DOMAIN/DOMAINS are automatically registered as Docker network aliases, allowing containers to reach each other:

services:
  db:
    image: mariadb
    environment:
      DOMAIN: db.local db-delivery.local

  api:
    image: nginx
    environment:
      DOMAIN: api.local
    # api can reach db via: db.local or db-delivery.local
    # db can reach api via: api.local

This replaces the deprecated external_links and works automatically with Docker's built-in DNS.

Traefik Labels

Traefik router rules are also supported:

services:
  web:
    image: nginx
    labels:
      - "traefik.http.routers.web.rule=Host(`web.local`)"
      # Multiple hosts supported:
      - "traefik.http.routers.api.rule=Host(`api.local`) || Host(`api2.local`)"
      # Or comma-separated:
      - "traefik.http.routers.app.rule=Host(`app.local`, `www.app.local`)"
Result

Only services with explicit domain configuration get /etc/hosts entries:

## bootapp:myproject
172.18.0.2    myapp.local
## bootapp:myproject
172.18.0.2    www.myapp.local
## bootapp:myproject
172.18.0.3    mysql.myapp.local

Services without DOMAIN config (like redis above) are not added to /etc/hosts.

SSL Certificates

Automatic Generation

bootapp automatically generates self-signed SSL certificates for domains specified in SSL_DOMAINS:

services:
  app:
    image: nginx
    environment:
      SSL_DOMAINS: myapp.test
    volumes:
      - ./var/certs:/etc/nginx/certs:ro

Certificates are:

  • Generated in ./var/certs/ directory (.crt, .key, .pem files)
  • Automatically trusted in system keychain (macOS) or ca-certificates (Linux)
  • Valid for 10 years
  • Include proper SAN (Subject Alternative Name) for browser compatibility
Certificate Files
var/certs/
├── myapp.test.crt    # Certificate
├── myapp.test.key    # Private key
└── myapp.test.pem    # Combined cert + key
Force Regenerate

To delete and regenerate certificates:

docker bootapp -f docker-compose.local.yml up -F

The -F flag will:

  1. Remove existing certificates from trust store
  2. Delete local certificate files
  3. Generate new certificates
  4. Install to trust store
  5. Force recreate containers
nginx Configuration Example
server {
    listen 443 ssl;
    server_name myapp.test;

    ssl_certificate /etc/nginx/certs/myapp.test.crt;
    ssl_certificate_key /etc/nginx/certs/myapp.test.key;

    # ... rest of config
}

macOS Networking

docker-mac-net-connect is required for direct container IP access on macOS.

Docker Desktop runs containers inside a Linux VM, so macOS cannot directly access container IPs without a network tunnel.

Installation
brew install chipmk/tap/docker-mac-net-connect
sudo brew services start docker-mac-net-connect

bootapp will check for docker-mac-net-connect and show installation instructions if not found.

Linux

All features work natively on Linux!

Linux support includes:

  1. Docker Networking

    • Unique subnet per container
    • Direct container IP access (no additional tools needed)
  2. SSL Certificate Auto-generation & Trust

    • Debian/Ubuntu: update-ca-certificates
    • RHEL/CentOS: update-ca-trust
    • Self-signed certificates automatically trusted system-wide
  3. Automatic /etc/hosts Management

    • Domain → Container IP mapping
    • Auto register/cleanup per project
  4. Standalone Binary + Docker Plugin

    • Use bootapp or docker bootapp commands

Installation:

# Requires Go
bash install.sh
# or
make build install

Unlike macOS, Linux doesn't need additional network tools (docker-mac-net-connect) - everything works out of the box!

Domain TLD Recommendations

Recommended TLDs:

  • .test - RFC 2606 reserved for testing ✅
  • .localhost - Local only ✅
  • .internal - Private networks ✅

Avoid:

  • .local - Conflicts with macOS mDNS (slow DNS lookups)
  • .dev - Google-owned, forces HTTPS
  • .app - Google-owned, forces HTTPS

Configuration

Global configuration is stored in ~/.bootapp/projects.json:

{
  "myproject": {
    "path": "/path/to/project",
    "subnet": "172.18.0.0/16",
    "domain": "myproject.local"
  },
  "another-project": {
    "path": "/path/to/another",
    "subnet": "172.19.0.0/16",
    "domain": "another.local"
  }
}

Each project gets a unique subnet (172.18.x.x through 172.31.x.x) to prevent IP conflicts between projects.

License

MIT

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL