Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to execute entrypoints on a start #821

Closed
grouvig opened this issue Mar 1, 2021 · 4 comments
Closed

Add the ability to execute entrypoints on a start #821

grouvig opened this issue Mar 1, 2021 · 4 comments
Labels
Request Request for image modification or feature

Comments

@grouvig
Copy link

grouvig commented Mar 1, 2021

Hi,

We have the need to be able to execute entrypoints on each start.
As of now the only entypoint available is executed on first start with initdb: docker-entrypoint-initdb.d

To work around this, we modify your alpine image to add another entrypoint docker-entrypoint-init.d in docker-entrypoint.sh this way:

...
_main() {
	...
	if [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; then
		...
		# only run initialization on an empty data directory
		if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
			...
			docker_process_init_files /docker-entrypoint-initdb.d/*
			...
		else
			...
		fi
		echo "Process custom init file "
		docker_process_init_files /docker-entrypoint-init.d/*
		echo "Process custom init file done "
	fi

	exec "$@"
}
...

Can you add such an entrypoint to the image ?
This will allow to restore db from volumes on start, make additional configurations...

@wglambert wglambert added the Request Request for image modification or feature label Mar 1, 2021
@tianon
Copy link
Member

tianon commented Mar 1, 2021

See #191 and #542 -- this would be extremely disruptive for us to implement generally (since we'd have to start and stop and start again the server on every container startup, which is not generally acceptable), but the entrypoint changes in #496 should make this reasonably straightforward to implement in a dependent image.

@grouvig
Copy link
Author

grouvig commented Mar 2, 2021

@tianon,

I didn't find any documentation about the entrypoint changes in #496.
How am I supposed to do this in a dependent image ?

@yosifkit
Copy link
Member

yosifkit commented Mar 5, 2021

We haven't documented the entrypoint shell functions outside of the code, their implementation (#496), and mentioning them in issues here and there. The basic example I used to verify customization does basically what you want, but has some rough edges: #496 (comment).

@Gruummy
Copy link

Gruummy commented Aug 21, 2023

In my project i do such things already for pgadmin4 container
(i know this is pgadmin and not postgres .... only as example)

# Use non fixed patch version to be able to autorefresh
# Version 7.5 referenced at 27.07.2023
# --> https://hub.docker.com/r/dpage/pgadmin4/tags
#
FROM WhatEverRegistry/dpage/pgadmin4:7.5

USER root

# Add all local parts of source 1 to 1 into the container
# Info: All files here were checked. They are not existing before
#       in the container. So this is only an addition of additional
#       files to the container image.
# Attention: The content of the src directory must be 1 to 1 the
#            file layout inside the container image. All content
#            is directly added to the root of the container as base
#
ADD src /

# Add possibility to include automatically additional scripts to
# "/custom-entrypoint.d/" inside the docker container, if this image is
# used in a docker "FROM" style. (It is a docker BUILD trigger)
#
ONBUILD COPY /src/custom-entrypoint.d/* /custom-entrypoint.d/

# Add ENV variable to container pointing to /etc/profile to force
# the ash shell to start preparing the environment with the contained
# logic when an interactive (login) shell will be requested.
# --> google: how-to-get-etc-profile-to-run-automatically-in-alpine-docker
#
ENV ENV="/etc/profile"

# Extend source image (based on alpine) with special things for special reasons
# To avoid creation of multipe docker layers, all the modifications are done
# here in one big collection of RUN commands during docker build.
#
    # 1. Make all .sh scripts of custom extensions executable inside the container
    #    (for directories which are copied from "/src" folder to "/" inside the image)
RUN find /build/ -type f -iname "*.sh" -exec chmod +x {} \; && \
    find /custom-entrypoint.d/ -type f -iname "*.sh" -exec chmod +x {} \; && \
    chmod +x /custom-entrypoint.sh && \
    #
    # 2. Patch permissions of files inside the container which needs at startup
    #    time to be changeable by *entypoint.sh scripts / startup user.
    /build/docker/FilesToBePatchable.sh && \
    #
    # 3. Remove all only for the build time related contents from the image
    rm -rf /build && \
    #
    # 4. Add empty wpad.dat to root of web to avoid http 404 errors in case
    #    that you run the container locally and Windows tries to scan this file
    touch /pgadmin4/pgadmin/wpad.dat && \
    #
    # 5. home of pgadmin is missing by default, so build of container fails if you
    #    use for example "VSCode" as local developer / test software
    mkdir -p /home/pgadmin && \
    chmod 775 /home/pgadmin && \
    chown -R pgadmin /home/pgadmin && \
    #
    # 6. Add bash for usage in later support actions
    apk --no-cache add --upgrade bash && \
    #
    # 7. Add run-parts in full version (busybox version is to limited)
    apk --no-cache add --upgrade run-parts && \
    #
    # 8. Add tz in to fullfill requirement of TZ="Europe/Berlin"
    apk --no-cache add --upgrade tzdata && \
    #
    # 9. Remove special set capabilities from orignal dockerfile of pgadmin.
    #    Container hardening in AWS EKS removes all capabilities and as a
    #    consequence python can not longer be started
    #
    #    !!! This needs to be revisited when you go to newer pgadmin image !!!
    find /usr/bin/ -type f -iname "python*" -exec setcap -r {} \;


# Now there is no longer a need to be root. We can savely switch to pgadmin user
USER pgadmin

# Go to unpriviledged port to not struggle with kubernetes securityContext.capabilities
EXPOSE 5050

# Now run our custom entrypoint script as a wrapper for the official one
# from the original upstream source
#
ENTRYPOINT ["/custom-entrypoint.sh"]

This give the possibility that at startup any files in a row can be executed however the files are injected / mounted to to container

Here the content of the script which is executed as custom entrypoint

#!/bin/sh
# Alpine does not contain bash as default shell, so do everything in "sh" style

# Custom entrypoint script wrapper. Inspired by:
# https://www.camptocamp.com/en/news-events/flexible-docker-entrypoints-scripts
#
DIR=/custom-entrypoint.d
if [[ -d "$DIR" ]]; then
  /bin/run-parts --verbose --regex '^[a-zA-Z0-9\._-]+$' "$DIR"
fi

# Call the original entrypoint of the base image with trailing "$@" to transfer pid 1
# to the upstream entrypoint so that signals get handeled correctly.
#
exec /entrypoint.sh "$@"

If someone finds this inspiring ... please do not implement "/custom-entrypoint.d" as default in a container image ... choose another namespace ... 'custom*' namespace should be reserved for usage by "custom" extentions ;-)

... please excuse the big amount of the comments there ... but i am a comment ... lover ...

i think all the time when i implement things for the situation ... what i would think if i need to fix / patch things which had been done years ago by other colleagues which i can not ask why it was done this way ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Request Request for image modification or feature
Projects
None yet
Development

No branches or pull requests

5 participants