Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Docker Expert

BSecurity

Swoole-specific Docker patterns and house rules. Covers PHP+Swoole multi-stage builds (pecl and source compile), layer ordering for composer cache, PHP ini and opcache tuning for long-running Swoole processes, PID 1 with tini, graceful shutdown, file-based healthchecks for worker containers, Compose healthcheck-gated depends_on (house pattern), watch mode, profiles, Swoole memory budgeting and fd limits, and Swoole-specific anti-patterns. Does NOT cover general Docker basics, BuildKit feature...

2 stars
0 votes
0 copies
0 views
Added 9/29/2026
devopsgophpbashsqldockerdebugginggitci/cdsecurity

Works with

cli

Security Analysis

B76/100
mediumUses curl or wget to download content
criticalAccesses sensitive system or user directories
highPerforms destructive filesystem operations

Pro scans all 2 files and shows the line behind each finding

Scanned 9/29/2026

$npx -y skills add abnegate/claudes --skill docker-expert --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Docker Expert?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Docker Expert
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/abnegate-docker-expert/badge)](https://www.skillsdirectory.com/skills/abnegate-docker-expert)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: docker-expert
description: Swoole-specific Docker patterns and house rules. Covers PHP+Swoole multi-stage builds (pecl and source compile), layer ordering for composer cache, PHP ini and opcache tuning for long-running Swoole processes, PID 1 with tini, graceful shutdown, file-based healthchecks for worker containers, Compose healthcheck-gated depends_on (house pattern), watch mode, profiles, Swoole memory budgeting and fd limits, and Swoole-specific anti-patterns. Does NOT cover general Docker basics, BuildKit features, image optimization, networking, security hardening, logging, debugging, or CI/CD — those are well-covered in training data. Use when writing or reviewing Dockerfiles and Compose files for PHP/Swoole services.
---

# Docker Expert

Reference for Docker patterns specific to the Appwrite/Swoole ecosystem. **Assumes full Docker knowledge** — only house rules, Swoole-specific patterns, and non-obvious gotchas.

Non-negotiable defaults:
- **Multi-stage builds always.** Builder compiles, runtime copies artifacts.
- **BuildKit enabled.** `# syntax=docker/dockerfile:1` at the top of every Dockerfile.
- **Non-root runtime.** Every production container runs as a non-root user.
- **No secrets in image layers.** `--mount=type=secret`, never `ENV`/`COPY` for credentials.
- **Healthchecks on every long-running service.** `depends_on` with `condition: service_healthy`.
- **Pin base image tags.** `php:8.3-cli-bookworm`, never `php:latest`. Use `@sha256:...` in CI.

---

## 1. PHP + Swoole multi-stage builds

### 1.1 Standard pattern (pecl)

```dockerfile
# syntax=docker/dockerfile:1
FROM php:8.3-cli-bookworm AS builder

RUN apt-get update && apt-get install -y --no-install-recommends \
        libpq-dev libcurl4-openssl-dev libssl-dev libsqlite3-dev zlib1g-dev \
    && docker-php-ext-install -j$(nproc) pdo_mysql pdo_pgsql pdo_sqlite sockets \
    && pecl install swoole \
    && docker-php-ext-enable swoole \
    && rm -rf /var/lib/apt/lists/*

FROM php:8.3-cli-bookworm AS runtime
COPY --from=builder /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
COPY --from=builder /usr/local/etc/php/conf.d/ /usr/local/etc/php/conf.d/
COPY --from=builder /usr/lib/x86_64-linux-gnu/libpq.so* /usr/lib/x86_64-linux-gnu/
COPY --from=builder /usr/lib/x86_64-linux-gnu/libsqlite3.so* /usr/lib/x86_64-linux-gnu/
COPY --chown=appwrite:appwrite . /app
WORKDIR /app
USER appwrite
ENTRYPOINT ["php", "server.php"]
```

- Copy the extensions **directory**, not individual `.so` files -- survives version bumps.
- Copy shared lib `.so*` glob -- catches symlinks (`libpq.so.5 -> libpq.so.5.17`).
- `--chown` on COPY -- avoids a separate `chown` layer.

### 1.2 Source compile (when custom flags needed)

```dockerfile
ARG SWOOLE_VERSION=6.0.0
RUN apt-get update && apt-get install -y --no-install-recommends \
        libcurl4-openssl-dev libssl-dev libpq-dev libsqlite3-dev liburing-dev \
    && cd /tmp \
    && curl -fSL "https://github.com/swoole/swoole-src/archive/v${SWOOLE_VERSION}.tar.gz" | tar xz \
    && cd "swoole-src-${SWOOLE_VERSION}" \
    && phpize && ./configure \
        --enable-openssl --enable-swoole-curl --enable-swoole-pgsql \
        --enable-swoole-sqlite --enable-sockets \
    && make -j$(nproc) && make install \
    && docker-php-ext-enable swoole
```

Use `pecl install swoole` for standard builds. Source compile only for `--enable-swoole-curl`, `--enable-iouring`, etc.

### 1.3 Layer ordering for cache efficiency

```dockerfile
# Order: base packages (monthly) -> extensions (monthly) -> deps (weekly) -> code (every commit)
COPY composer.json composer.lock ./
RUN --mount=type=cache,target=/root/.composer/cache \
    composer install --no-dev --prefer-dist --no-scripts --no-autoloader
COPY . .
RUN composer dump-autoload --optimize --classmap-authoritative
```

---

## 2. PHP ini and opcache for Swoole containers

```ini
; appwrite.ini -- long-running process settings
max_execution_time = 0          ; Swoole workers run indefinitely
memory_limit = 512M             ; per worker, not per request (worker_num * limit <= container memory)
max_input_time = -1             ; Swoole manages lifecycle
post_max_size = 128M
upload_max_filesize = 128M
display_errors = Off
log_errors = On
error_reporting = E_ALL
error_log = /dev/stderr
```

```ini
; opcache.ini -- CRITICAL settings for Swoole
opcache.enable = 1
opcache.enable_cli = 1
opcache.validate_timestamps = 0         ; files don't change at runtime; reload workers for updates
opcache.preload = /app/preload.php      ; hot classes shared across workers
opcache.preload_user = appwrite
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 32
opcache.max_accelerated_files = 30000
opcache.jit = 1255                      ; profile-guided for Swoole hot paths
opcache.jit_buffer_size = 128M
```

For development: `validate_timestamps=1` or file watch + `$server->reload()`.

---

## 3. Signal handling, PID 1, and healthchecks

### PID 1 + tini

PID 1 in a container: no default signal handlers (SIGTERM ignored), must reap zombie children.

```dockerfile
RUN apt-get update && apt-get install -y --no-install-recommends tini
ENTRYPOINT ["tini", "--"]
CMD ["php", "server.php"]
```

Or Compose `init: true`. Swoole signal handlers (`Process::signal(SIGTERM, ...)`) work but don't reap zombies.

### Graceful shutdown

```yaml
services:
  app:
    stop_grace_period: 30s  # must be >= swoole max_wait_time; SIGKILL after expiry
```

Sequence: SIGTERM -> tini forwards -> Swoole master signals workers -> workers drain -> exit.

### Healthchecks

```dockerfile
# HTTP server -- TCP or curl
HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=3 \
    CMD curl -f http://127.0.0.1:8080/health || exit 1
```

```php
// Worker/queue containers (no port) -- file-based heartbeat
file_put_contents('/tmp/heartbeat', (string) time());  // in worker loop
```

```dockerfile
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
    CMD php -r "exit(time() - (int)file_get_contents('/tmp/heartbeat') > 60 ? 1 : 0);"
```

---

## 4. Compose orchestration (house patterns)

### 4.1 Healthcheck-gated dependencies

```yaml
services:
  mariadb:
    image: mariadb:11
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    volumes:
      - mariadb-data:/var/lib/mysql

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3

  app:
    build: .
    depends_on:
      mariadb:
        condition: service_healthy   # NEVER bare depends_on -- waits for start, not ready
      redis:
        condition: service_healthy
```

### 4.2 Watch mode and profiles

```yaml
services:
  app:
    develop:
      watch:
        - action: sync
          path: ./src
          target: /app/src
        - action: rebuild
          path: ./composer.lock
        - action: sync+restart
          path: ./config
          target: /app/config

  maildev:
    image: maildev/maildev
    profiles: ["dev"]
  prometheus:
    image: prom/prometheus
    profiles: ["monitoring"]
```

```bash
docker compose watch          # or: docker compose up --watch
docker compose --profile dev up
```

---

## 5. Resource limits for Swoole

```yaml
services:
  app:
    deploy:
      resources:
        limits:
          memory: 1G
          cpus: "2.0"
        reservations:
          memory: 512M
          cpus: "1.0"
    ulimits:
      nofile:
        soft: 65535       # Swoole needs high fd limit for concurrent connections
        hard: 65535       # default 1024 is far too low
```

**Memory budget**: `worker_num * memory_limit + master overhead + buffer`. 4 workers * 512M + 200M = ~2.3G limit.

**Logging**: `ENV SWOOLE_LOG_FILE=/dev/stderr` -- never write logs to container filesystem.

**Alpine caveat**: DNS `ndots:5` in k8s causes 5x queries -- set `ndots:1`.

---

## 6. Anti-patterns (Swoole-specific and non-obvious)

| About to write | Write instead | Why |
|---|---|---|
| `COPY . .` before `RUN composer install` | `COPY composer.json composer.lock ./` first | Code changes bust dependency cache |
| `depends_on: [mariadb]` (bare) | `depends_on: { mariadb: { condition: service_healthy } }` | Started != ready; race condition |
| No resource limits | `deploy.resources.limits` | OOM container takes down host |
| `restart: always` without healthcheck | `restart: unless-stopped` + healthcheck | Crash loop burns CPU undetected |
| `volumes: [./vendor:/app/vendor]` | Named volume or don't mount | Wrong platform binaries; defeats caching |
| `json-file` without rotation | Always set `max-size` and `max-file` | Default has NO rotation -- disk fills |
| `version: "3.8"` at top | Omit entirely | Deprecated since Compose v2; ignored |
| Default ulimits for Swoole | `nofile: 65535` | Default 1024 starves fd-heavy Swoole |
| `memory_limit=-1` in Swoole container | Explicit per-worker limit | One leak takes down entire container |
| `opcache.validate_timestamps=1` in prod | `validate_timestamps=0` + worker reload | Stat calls on every request in long-running process |

Attribution

abnegateabnegate
View sourceSee grades on GitHubMore from abnegate →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Terraform Module Library

Build reusable Terraform modules for AWS, Azure, and GCP infrastructure following infrastructure-as-code best practices. Use when creating infrastructure modules, standardizing cloud provisioning, or implementing reusable IaC components.

401991 votes

sematext-otel

Wire a service's OpenTelemetry output to Sematext Cloud. Walks through region, App-type, instrumentation flow (managed OTLP endpoint vs Sematext Agent), and signal selection (traces/metrics/logs), then produces the exact env-var block and points at a runnable reference example in this repo. Invoke when instrumenting a new app for Sematext.

01 votes

Deployment Patterns

Deployment workflows, CI/CD pipeline patterns, Docker containerization, health checks, rollback strategies, and production readiness checklists for web applications. Use when setting up deployment infrastructure or planning releases.

2699140 votes

Babysit

Watch a pull request or review cycle until it is ready to merge. Use when asked to babysit, monitor, or keep checking PR comments, reviews, and CI until all actionable issues are resolved.

971540 votes

V7 Roster

Interact with the Paperclip control plane API for task coordination and governance. Use when checking assignments, updating issue status, posting comments, delegating work, managing routines, or calling Paperclip API endpoints.

953190 votes
View all in devops →