Adding your own start up scripts

We provide a few default scripts to get you going, but sometimes you want to just add your own. We've made it easy to do that with our entrypoint.d directory.

Entrypoint Script Requirements

We recommend writing your script in /bin/sh for the best compatibility between Alpine and Debian. If you choose to use /bin/bash, your script will only be able to run on Debian-based images.

Choose your execution order

Since we provide default entrypoint scripts, you may want to choose the order in which your scripts are executed. We've made it easy to do that by prefixing your script with a number. The lower the number, the earlier it will be executed.

Long running services

Anything in the /etc/entrypoint.d directory are scripts that are intended to run quickly and then move on. If you run a service as an entrypoint script, that service may crash and not be restarted.

Instead, learn about using S6 overlay so your services can be properly initialized and monitored. See the S6 Overylay project for more details on how to write your own S6 service.

Example: Create a custom entrypoint script

In this example, let's create a 99-my-script.sh so it executes after all the other default scripts.

First, let's take a look at our project structure:

Project Structure

.
├── Dockerfile
├── docker-compose.yml
├── entrypoint.d
│   └── 99-my-script.sh
└── public
    └── index.php

Let's take a look at the script that we want to run. We can keep this simple for now.

99-my-script.sh

#!/bin/sh
echo "👋 Hello, world!"

Now, let's take a look at our Dockerfile:

Dockerfile

FROM serversideup/php:8.3-unit

COPY --chmod=755 ./entrypoint.d/ /etc/entrypoint.d/

In the above file, we're copying our entrypoint.d directory to /etc/entrypoint.d/ in the container. We're also setting the permissions to 755 so our scripts are executable.

Finally, let's take a look at our docker-compose.yml file:

docker-compose.yml

version: '3'
services:
  php:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 80:8080
    volumes:
      - .:/var/www/html

In the above file, we're building our image using the Dockerfile in the current directory. We're also mounting our current directory to /var/www/html in the container.

Don't use exit 0 in your script

If you use exit 0 in your script, it will stop the execution of the rest of the entrypoint scripts. We recommend using return 0 instead. See this discussion for more details on why.

Long story short, we don't use subshells to execute your scripts, so exit 0 will not work as expected. We do this because we want to ensure your script has access to the environment variables that are set in the entrypoint scripts.

Running our example

When we run docker compose up, we should see the following output:

Output of "docker compose up"

example-project  | init-unit: Stopping Unit daemon after initial configuration...
example-project  | 2023/12/05 19:52:37 [notice] 29#29 process 33 exited with code 0
example-project  | init-unit: Waiting for control socket to be removed...
example-project  | 2023/12/05 19:52:37 [notice] 29#29 process 34 exited with code 0
example-project  | 
example-project  | init-unit: Unit initial configuration complete; ready for start up...
example-project  | 
example-project  | 👋 Hello, world!
example-project  | 2023/12/05 19:52:38 [info] 1#1 unit 1.31.1 started
example-project  | 2023/12/05 19:52:38 [info] 65#65 discovery started
example-project  | 2023/12/05 19:52:38 [notice] 65#65 module: php 8.3.0 "/usr/lib/unit/modules/php.unit.so"
example-project  | 2023/12/05 19:52:38 [info] 1#1 controller started
example-project  | 2023/12/05 19:52:38 [notice] 1#1 process 65 exited with code 0
example-project  | 2023/12/05 19:52:38 [info] 67#67 router started
example-project  | 2023/12/05 19:52:38 [info] 67#67 OpenSSL 3.0.11 19 Sep 2023, 300000b0

You can see our 👋 Hello, world! is executing after the initialization of 10-init-unit.sh.