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

Upgrade to 4.31 causes Permission denied #354

Closed
geddah opened this issue Jan 27, 2025 · 8 comments
Closed

Upgrade to 4.31 causes Permission denied #354

geddah opened this issue Jan 27, 2025 · 8 comments
Assignees

Comments

@geddah
Copy link

geddah commented Jan 27, 2025

Steps to reproduce:
Upgrade liquibase to 4.31

Getting the following log when running liquibase as one of the init-containers in kubernetes 1.29:

/bin/bash: /liquibase/docker-entrypoint.sh: Permission denied

We are using liquibase as a base image for our init container.
Using the following command to to run the docker image:

CMD ["sh", "-c", "./create-liquibase-props.sh && docker-entrypoint.sh --defaultsFile=config/liquibase.properties update"]

We verified the above command works until v4.30

@jandroav
Copy link
Contributor

Hello @geddah,

Could you please provide the content for create-liquibase-props.sh ?

Could you please also provide the full Dockerfile you are using to extend the official image?

Thanks!

@geddah
Copy link
Author

geddah commented Jan 28, 2025

Hey @jandroav. Thank you for the quick reply.

Here's the docker file:

FROM liquibase:4.31
COPY changelog/ /liquibase/changelog/db/changelog/
RUN ls --recursive /liquibase/
COPY --chown=liquibase:liquibase create-liquibase-props.shh /liquibase/

USER root
RUN chmod +x /liquibase/create-liquibase-props.sh && \
    mkdir -m777 -p /liquibase/config && \
    chmod +x /liquibase/docker-entrypoint.sh
USER 1001

# We run create-liquibase-props.sh to populate /liquibase/config/liquibase.properties and then start
# the Liquibase script (docker-entrypoint.sh) to do the migrations with the generated properties.
CMD ["sh", "-c", "./create-liquibase-props.sh && docker-entrypoint.sh --defaultsFile=config/liquibase.properties update"]

create-liquibase-props.sh is populating the properties file '/liquibase/config/liquibase.properties', Contents inside create-liquibase-props.sh:

#!/usr/bin/env bash

# *************************************************************************************
# NOTE: This is used by the Liquibase init container to setup the liquibase.properties
#       from environment variables.
# *************************************************************************************

set -e

# NOTE: This allows an AWS image to generate the auth token and store it in the auth_token file for us to use now.
if [[ -f "/liquibase/config/auth_token" ]]; then
	export PASSWORD=$(</liquibase/config/auth_token)
	export SSL_MODIFIER="?sslmode=require"
fi

if [[ ! -v USERNAME ]]; then
	echo "USERNAME not set"
fi

if [[ ! -v PASSWORD ]]; then
	echo "PASSWORD not set"
fi

if [[ ! -v DB_HOST ]]; then
	echo "DB_HOST not set"
fi

if [[ ! -v DB_PORT ]]; then
	echo "DB_PORT not set"
fi

if [[ ! -v DB_NAME ]]; then
	echo "DB_NAME not set"
fi

echo "username: ${USERNAME}" > /liquibase/config/liquibase.properties
echo "password: ${PASSWORD}" >> /liquibase/config/liquibase.properties
echo "url: jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}${SSL_MODIFIER}" >> /liquibase/config/liquibase.properties
echo "contexts: ${DB_CONTEXT}" >> /liquibase/config/liquibase.properties
echo "classpath: /liquibase/changelog" >> /liquibase/config/liquibase.properties
echo "changeLogFile: db/changelog/db.changelog-master.yaml" >> /liquibase/config/liquibase.properties

exit 0

@jandroav
Copy link
Contributor

Hello @geddah I was locally testing it with your files and I was not able to reproduce it so I believe it is related to the specific Kubernetes environment. I could see the following when executing this command using your Dockerfile:

docker run --rm -it liquibase:4.31.0-gh ls -l /liquibase/docker-entrypoint.sh

-rwxr-xr-x 1 liquibase liquibase 614 Jan 28 02:15 /liquibase/docker-entrypoint.sh

In Kubernetes, stricter permission handling or different runtime configurations might result in the Permission denied error, especially when the container runs as a non-root user (1001 in this case).

Could you please add chmod +x /liquibase/docker-entrypoint.sh && \ in your Dockerfile:

Image

Please let me know how it goes and we can further troubleshoot it.

Regards,

@geddah
Copy link
Author

geddah commented Jan 29, 2025

Hello @jandroav. Apologies for the delayed response.
I have done some debugging yesterday and found out the root cause to be one of the security configs we have in our kubernetes deployment manifest:

securityContext:
  runAsUser: 1337

We are running the liquibase container as another user with UID 1337(not 1001 nor root). When I configure the runAsUser config to 1001, it is able to run the container successfully.

I will do some more digging as to why the same configuration does not throw any errors with previous versions of liquibase.
I will keep posted in this thread on the progress.
For now, I don't think there is anything I need from your side. You may close this thread if I don't reply in a reasonable amount of time.

Thanks!!!

@jandroav
Copy link
Contributor

jandroav commented Jan 29, 2025

hey @geddah this can be related to #355

Previously, we did not specify --create-home --home-dir /liquibase and the /liquibase directory was manually created and assigned ownership (chown liquibase /liquibase). This meant:

  • The directory and its contents could be accessed by other users, depending on default permissions.
  • If Kubernetes ran the container as runAsUser: 1337, it might have had sufficient permissions to execute docker-entrypoint.sh and other files.

Now that the home directory is explicitly created, it is likely that:

  • The home directory (/liquibase) is created with stricter permissions by default.
  • Files inside /liquibase are now owned by liquibase (UID 1001) and may not be accessible to UID 1337 (the user Kubernetes is enforcing).
  • The docker-entrypoint.shscript may not have execute permissions for non-owners, leading to the Permission denied error.

@geddah
Copy link
Author

geddah commented Jan 29, 2025

That makes sense. Thanks!!

@geddah geddah closed this as completed Jan 29, 2025
@Sax388
Copy link

Sax388 commented Feb 7, 2025

Just wanted to make sure if this is a good approach for a custom image after the changes in 4.31:

FROM docker.io/liquibase/liquibase:4.31

COPY changelog /liquibase/changelogs/db/changelog

WORKDIR /liquibase/changelogs

ENV CHANGELOG_FILE "db/changelog/db.changelog-master.yaml"

# Set user to root to fix permissions
USER root

# Ensure the liquibase binary is executable for all users
RUN chmod +x /liquibase/liquibase && chown -R 999:999 /liquibase

# Set user back to 999 for security
USER 999

CMD ["sh", "-c", "\
    liquibase update \
    --changelogFile=$CHANGELOG_FILE \
    --url=$DB_URL \
    --username=$DB_LIQUIBASE_USERNAME \
    --password=$DB_LIQUIBASE_PASSWORD"]

In the k8s deployment I'm using

runAsGroup: 999
runAsNonRoot: true
runAsUser: 999

Thanks for your support 🙂 !

@jandroav
Copy link
Contributor

jandroav commented Feb 7, 2025

Helo @Sax388,

Your approach looks solid, and using runAsUser: 999 in Kubernetes ensures alignment with the container.

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

No branches or pull requests

3 participants