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.4-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

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.

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.4.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.

Advanced Scenarios: S6 Overlay dependencies

If you want to customize an image that uses S6 Overlay (fpm-nginx or fpm-apache), you may have an advanced scenario where you have a custom S6 service that needs to be executed after one of our entrypoint scripts. In order to do this, you'll need to move all our scripts from the /etc/entrypoint.d directory to the /etc/s6-overlay/scripts directory. This would be a very time consuming scenario if you did this manually, but thankfully you can use our docker-php-serversideup-s6-init script to do this for you.

Example Dockerfile

FROM serversideup/php:8.4-fpm-nginx

# Set the user to root for our build steps
USER root

# If you have your own one-shot scripts, copy them to the entrypoint.d directory
COPY --chmod=755 ./entrypoint.d/ /etc/entrypoint.d/

# Copy our entrypoint scripts into the S6 Overlay scripts directory
RUN docker-php-serversideup-s6-init

# If you have your own long running services, copy them to the s6 directory
COPY --chmod=755 ./my-s6-service/ /etc/s6-overlay/s6-rc.d/my-s6-service/

# Drop back to the non-root user
USER www-data

In the above file, we're copying our "one-shot" scripts to the /etc/entrypoint.d directory and our long running services to the /etc/s6-overlay directory. One-shot scripts are scripts that are intended to run quickly and then move on. Long running services are services that are intended to run for a long time and need to be monitored and restarted if they crash.

The magic happens when we run docker-php-serversideup-s6-init. This script will move all our scripts from the /etc/entrypoint.d directory to the /etc/s6-overlay/scripts directory and set the correct dependencies for our S6 services.

You can now reference our script names as dependencies in your own S6 service.

Learn more about writing your own S6 services →