if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
exec gosu postgres "$@"
fi
exec "$@"
```
This script uses [the `exec` Bash command](https://wiki.bash-hackers.org/commands/builtin/exec) so that the final running application becomes the container's PID 1. This allows the application to receive any Unix signals sent to the container. For more information, see the [`ENTRYPOINT` reference](/reference/dockerfile.md#entrypoint).
In the following example, a helper script is copied into the container and run via `ENTRYPOINT` on
container start:
```dockerfile
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["postgres"]
```
This script lets you interact with Postgres in several ways.
It can simply start Postgres:
```console
$ docker run postgres
```
Or, you can use it to run Postgres and pass parameters to the server:
```console
$ docker run postgres postgres --help
```
Lastly, you can use it to start a totally different tool, such as Bash:
```console
$ docker run --rm -it postgres bash
```
For more information about `ENTRYPOINT`, see [Dockerfile reference for the ENTRYPOINT instruction](/reference/dockerfile.md#entrypoint).
### VOLUME
You should use the `VOLUME` instruction to expose any database storage area,
configuration storage, or files and folders created by your Docker container. You
are strongly encouraged to use `VOLUME` for any combination of mutable or user-serviceable
parts of your image.
For more information about `VOLUME`, see [Dockerfile reference for the VOLUME instruction](/reference/dockerfile.md#volume).
### USER
If a service can run without privileges, use `USER` to change to a non-root
user. Start by creating the user and group in the Dockerfile with something
like the following example:
```dockerfile
RUN groupadd -r postgres && useradd --no-log-init -r -g postgres postgres
```
> [!NOTE]
>
> Consider an explicit UID/GID.
>
> Users and groups in an image are assigned a non-deterministic UID/GID in that
> the "next" UID/GID is assigned regardless of image rebuilds. So, if it’s
> critical, you should assign an explicit UID/GID.
> [!NOTE]
>
> Due to an [unresolved bug](https://github.com/golang/go/issues/13548) in the
> Go archive/tar package's handling of sparse files, attempting to create a user
> with a significantly large UID inside a Docker container can lead to disk