Skip to main content
Floci discovers and runs shell scripts at startup and shutdown. Use hooks to create buckets, seed SSM parameters, configure queues, or clean up state — anything you’d otherwise do manually after docker compose up. Scripts ending with .sh are discovered in two directories:
  • Startup hooks (/etc/floci/init/start.d) — run after the HTTP server is ready and accepting connections on port 4566. Hooks can safely make AWS API calls back to Floci.
  • Shutdown hooks (/etc/floci/init/stop.d) — run when Floci is shutting down, after destroy() is triggered.
If a hook directory does not exist, contains no .sh files, or the path is not a directory, Floci skips it and continues normally.

Setting up hooks in Docker Compose

1

Create your hook directories

Create the startup and shutdown directories alongside your docker-compose.yml:
mkdir -p ./init/start.d ./init/stop.d
2

Write your hook scripts

Hook scripts must be executable shell scripts. Name them with a numeric prefix to control execution order:
# ./init/start.d/01-seed-parameter.sh
#!/bin/sh
set -eu

aws --endpoint-url http://localhost:4566 \
  ssm put-parameter \
  --name /demo/app/bootstrapped \
  --type String \
  --value true \
  --overwrite
chmod +x ./init/start.d/01-seed-parameter.sh
3

Mount the directories into the container

Add read-only volume mounts for both hook directories in your Compose service definition:
services:
  floci:
    image: hectorvent/floci:latest
    ports:
      - "4566:4566"
    volumes:
      - ./data:/app/data
      - ./init/start.d:/etc/floci/init/start.d:ro
      - ./init/stop.d:/etc/floci/init/stop.d:ro
4

Start Floci

docker compose up
Startup hooks run automatically once the server is ready. You’ll see hook output in the Floci container logs.

Execution behavior

Scripts run in lexicographical (alphabetical) order, sequentially — one at a time. To control the execution order, prefix script filenames with numbers: 01-, 02-, 03-, and so on. Floci uses a fail-fast strategy:
  • If a script exits with a non-zero status, remaining hooks are not executed.
  • If a script exceeds the configured timeout, it is terminated and remaining hooks are not executed.
  • A shutdown hook failure is logged but does not prevent shutdown from completing.
A startup hook failure triggers application shutdown. If your startup hook exits with a non-zero status or exceeds timeout-seconds, Floci will shut down rather than start in a partially initialized state.

Example: startup hook

This hook seeds a known SSM parameter so your tests and local services can rely on it being present:
#!/bin/sh
set -eu

aws --endpoint-url http://localhost:4566 \
  ssm put-parameter \
  --name /demo/app/bootstrapped \
  --type String \
  --value true \
  --overwrite
Store this at ./init/start.d/01-seed-parameter.sh.

Example: shutdown hook

This hook removes the parameter during shutdown, leaving the environment clean for the next run:
#!/bin/sh
set -eu

aws --endpoint-url http://localhost:4566 \
  ssm delete-parameter \
  --name /demo/app/bootstrapped
Store this at ./init/stop.d/01-cleanup-parameter.sh.

AWS CLI in hooks

The published Floci Docker image does not include the AWS CLI. If your hooks call aws, you need to extend the image. The apk package manager is available in the base image.
FROM ghcr.io/hectorvent/floci:latest
RUN apk add --no-cache aws-cli
Build and reference your custom image in docker-compose:
services:
  floci:
    build: .        # uses the Dockerfile above
    ports:
      - "4566:4566"
    volumes:
      - ./init/start.d:/etc/floci/init/start.d:ro
      - ./init/stop.d:/etc/floci/init/stop.d:ro
If your hooks depend on other CLI tools (e.g. jq, curl, psql), add them to the same RUN layer.

Configuration

KeyDefaultDescription
floci.init-hooks.shell-executable/bin/bashShell used to run hook scripts
floci.init-hooks.timeout-seconds30Max execution time per script before it is terminated
floci.init-hooks.shutdown-grace-period-seconds2Time to wait after destroy() before force-stopping the process
Use FLOCI_INIT_HOOKS_* environment variables for the same settings:
FLOCI_INIT_HOOKS_SHELL_EXECUTABLE=/bin/sh
FLOCI_INIT_HOOKS_TIMEOUT_SECONDS=60
FLOCI_INIT_HOOKS_SHUTDOWN_GRACE_PERIOD_SECONDS=10
Or configure via application.yml when hooks need more time — for example, when seeding large amounts of test data or provisioning many resources:
floci:
  init-hooks:
    shell-executable: /bin/sh      # Portable POSIX-compatible scripts
    timeout-seconds: 60            # Give startup hooks more time
    shutdown-grace-period-seconds: 10  # Give shutdown hooks more time to clean up

Build docs developers (and LLMs) love