Customize Hasura Docker Image - docker

I have a need to install awscli and jq library in Hasura Docker Image. I tried to use yum, apt-get or apk commands to install the dependencies, but none of them worked.
Docker Image: https://hub.docker.com/r/hasura/graphql-engine/
how to install these dependencies in Hasura Docker Image? Any help is appreciated.
Dockerfile:
FROM hasura/graphql-engine:latest
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
CMD ["./entrypoint.sh"]
entrypoint.sh:
#!/bin/sh
set -o errexit -o nounset -o pipefail
DB_HOST=${DB_HOST:-postgres}
DB_PORT=${DB_PORT:-5432}
if [ -z "${DB_NAME}" ]; then
echo "Must provide DB_NAME environment variable. Exiting...."
exit 1
fi
if [ -z "${DB_USER}" ]; then
echo "Must provide DB_USER environment variable. Exiting...."
exit 1
fi
if [ -z "${DB_PASSWORD}" ]; then
echo "Must provide DB_PASSWORD environment variable. Exiting...."
exit 1
fi
export HASURA_GRAPHQL_DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}#${DB_HOST}:${DB_PORT}/${DB_NAME}
/bin/graphql-engine serve
DB_PASSWORD is encrypted with KMS, so i want to use aws cli to decrypt the password in entrypoint.sh file before setting the Environment Variable: HASURA_GRAPHQL_DATABASE_URL

I was able to customize Hasura Docker Image with the help of Hasura Team support.
Here is the link to github issue: https://github.com/hasura/graphql-engine/issues/2729
Dockerfile:
FROM hasura/graphql-engine:v1.0.0-beta.4 as base
FROM python:3.7-slim-stretch
RUN apt-get -y update \
&& apt-get install -y --no-install-recommends libpq-dev jq \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /usr/share/doc/ \
&& rm -rf /usr/share/man/ \
&& rm -rf /usr/share/locale/ \
&& pip install awscli
# copy hausra binary from base container
COPY --from=base /bin/graphql-engine /bin/graphql-engine
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
CMD ["/entrypoint.sh"]
entrypoint.sh:
#!/bin/bash
set -e
DB_HOST=${DB_HOST:-postgres}
DB_PORT=${DB_PORT:-5432}
AWS_REGION=${AWS_REGION:-us-east-1}
DB_PASSWORD_ENCYPTED=${DB_PASSWORD_ENCYPTED:-false}
if [ -z "${DB_NAME}" ]; then
echo "Must provide DB_NAME environment variable. Exiting...."
exit 1
fi
if [ -z "${DB_USER}" ]; then
echo "Must provide DB_USER environment variable. Exiting...."
exit 1
fi
if [ -z "${DB_PASSWORD}" ]; then
echo "Must provide DB_PASSWORD environment variable. Exiting...."
exit 1
fi
if [ ${DB_PASSWORD_ENCYPTED} == "true" ]
then
echo "loading KMS credentials"
decrypted_value_base64=$( \
aws --region ${AWS_REGION} kms decrypt \
--ciphertext-blob fileb://<(echo "${DB_PASSWORD}" | base64 -d) \
--query Plaintext \
--output text
)
decrypted_value=$(echo $decrypted_value_base64 | base64 -d)
export HASURA_GRAPHQL_DATABASE_URL=postgres://${DB_USER}:${decrypted_value}#${DB_HOST}:${DB_PORT}/${DB_NAME}
else
export HASURA_GRAPHQL_DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}#${DB_HOST}:${DB_PORT}/${DB_NAME}
fi
/bin/graphql-engine serve

Related

Symfony VAR directory still root with docker

I'm trying to setup my project with Docker but I'm facing an issue...
This is my docker-compose:
version: '3.8'
services:
back:
container_name: ${BACK_CONTAINER_NAME}
build:
context: ./back
target: ${TARGET}
args:
USER_ID: ${USER_ID:-0}
GROUP_ID: ${GROUP_ID:-0}
user: ${USER_ID:-0}:${GROUP_ID:-0}
environment:
- SOME_ENVS
volumes:
- ./back:/srv/app
- ./back/opcache.ini:/usr/local/etc/php/conf.d/opcache.ini
networks:
- lan
networks:
lan:
name: ${NETWORK_NAME}
volumes:
db_data_prod:
Dockerfile:
FROM php:8.1.11-fpm as base
ARG USER_ID
ARG GROUP_ID
RUN addgroup --gid $GROUP_ID user
RUN adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID user
RUN apt update --fix-missing \
&& apt install -y zlib1g-dev libonig-dev iputils-ping libzip-dev libicu-dev zip libpq-dev
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint
RUN chmod +x /usr/local/bin/docker-entrypoint
ENTRYPOINT ["docker-entrypoint"]
CMD ["php-fpm"]
WORKDIR /srv/app
RUN docker-php-ext-install pdo pdo_pgsql mbstring zip
COPY . .
# Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
VOLUME /srv/app/var/
RUN PATH=$PATH:/srv/app/vendor/bin:bin
FROM base as dev
RUN composer install --prefer-dist --no-autoloader --no-scripts --no-progress
RUN pecl install xdebug
RUN docker-php-ext-enable mbstring xdebug
USER user
FROM base as prod
RUN docker-php-ext-install opcache
RUN composer install --prefer-dist --no-dev --no-progress --no-scripts --no-interaction
USER user
And the entrypoint:
#!/bin/sh
set -e
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- php-fpm "$#"
fi
if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then
if [ "$APP_ENV" != 'prod' ]; then
composer install --prefer-dist --no-progress --no-interaction
fi
if grep -q DATABASE_URL= .env; then
echo "Waiting for database to be ready..."
ATTEMPTS_LEFT_TO_REACH_DATABASE=60
until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do
if [ $? -eq 255 ]; then
# If the Doctrine command exits with 255, an unrecoverable error occurred
ATTEMPTS_LEFT_TO_REACH_DATABASE=0
break
fi
sleep 1
ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1))
echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left."
done
if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then
echo "The database is not up or not reachable:"
echo "$DATABASE_ERROR"
exit 1
else
echo "The database is now ready and reachable"
fi
if [ "$( find ./migrations -iname '*.php' -print -quit )" ]; then
php bin/console doctrine:migrations:migrate --no-interaction
fi
fi
fi
exec docker-php-entrypoint "$#"
So, when I'm running the container, all the folders are set with the right user (user..) but only the /srv/app/var folder still root... and the app crashs cause of this.
Anyone have an idea?
Thanks

docker entrypoint running in loop

I am new to Docker and trying to adapt a setup from Symfony Docker to another app that uses a different Dockerfile.
I use a docker-entrypoint to run database migrations which, of course, require the database to be up.
My Dockerfile calls docker-entrypoint but somehow in enters into a loop, running it - the entrypoint code - repeatedly.
This is the Dockerfile at /docker/php:
FROM php:8.1-apache AS symfony_php
RUN a2enmod rewrite
RUN apt-get update \
&& apt-get install -y libpq-dev libzip-dev git libxml2-dev nano wget --no-install-recommends \
&& docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
&& docker-php-ext-install pdo pdo_pgsql pgsql zip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN wget https://getcomposer.org/download/2.3.5/composer.phar \
&& mv composer.phar /usr/bin/composer && chmod +x /usr/bin/composer
COPY docker/php/apache.conf /etc/apache2/sites-enabled/000-default.conf
COPY docker/php/php.ini /usr/local/etc/php/conf.d/app.ini
COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
RUN chmod +x /usr/local/bin/docker-entrypoint
ENV SYMFONY_PHPUNIT_VERSION=9
COPY . /var/www
WORKDIR /var/www
RUN mkdir -p var/cache var/log
RUN chmod -R 777 ./var/cache && chmod -R 777 ./var/log
RUN composer install --prefer-dist --no-progress --no-interaction
ENTRYPOINT ["docker-entrypoint"]
The entrypoint also at /docker/php
set -e
if grep -q DATABASE_URL= .env; then
echo "Waiting for database to be ready..."
ATTEMPTS_LEFT_TO_REACH_DATABASE=60
until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do
if [ $? -eq 255 ]; then
# If the Doctrine command exits with 255, an unrecoverable error occurred
ATTEMPTS_LEFT_TO_REACH_DATABASE=0
break
fi
sleep 1
ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1))
echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left."
done
if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then
echo "The database is not up or not reachable:"
echo "$DATABASE_ERROR"
exit 1
else
echo "The database is now ready and reachable"
fi
if ls -A migrations/*.php >/dev/null 2>&1; then
php bin/console doctrine:migrations:migrate --no-interaction
fi
fi
exec docker-php-entrypoint "$#"
The resulting loop:
Adding this to my entrypoint solved the issue:
/usr/sbin/apache2ctl -D FOREGROUND
It seems that the entrypoint interrupts the server process and placing the above snippet forces the server back up.
EDIT:
Even better:
Change Dockerfile as below:
ENTRYPOINT ["docker-entrypoint"]
CMD ["apachectl", "-D", "FOREGROUND"]
And on entrypoint.sh keep as per the original post:
exec docker-php-entrypoint "$#"

Setting conditional variables in a Dockerfile

I'm trying to create a multi-architecture docker image via buildkit, using the predefined TARGETARCH arg variable.
What I want to do is - I think - something like bash variable indirection, but I understand that's not supported and I'm struggling to come up with an alternative.
Here's what I've got:
FROM alpine:latest
# Buildkit should populate this on build with e.g. "arm64" or "amd64"
ARG TARGETARCH
# Set some temp variables via ARG... :/
ARG DOWNLOAD_amd64="x86_64"
ARG DOWNLOAD_arm64="aarch64"
ARG DOWNLOAD_URL="https://download.url/path/to/toolkit-${DOWNLOAD_amd64}"
# DOWNLOAD_URL must also be set in container as ENV var.
ENV DOWNLOAD_URL $DOWNLOAD_URL
RUN echo "Installing Toolkit" && \
curl -sSL ${DOWNLOAD_URL} -o /tmp/toolkit-${DOWNLOAD_amd64}
... which is a bit pseudo-code but hopefully illustrates what I'm trying to do: I want the value of either $DOWNLOAD_amd64 or $DOWNLOAD_arm64 dropped into $DOWNLOAD_URL, depending on what $TARGETARCH is set to.
This is probably a long-solved issue but either I'm googling the wrong stuff or just not getting it.
Ok, was not complete. Here a full working solution:
Dockerfile:
FROM ubuntu:18.04
ARG TARGETARCH
ARG DOWNLOAD_amd64="x86_64"
ARG DOWNLOAD_arm64="aarch64"
WORKDIR /tmp
ARG DOWNLOAD_URL_BASE="https://download.url/path/to/toolkit-"
RUN touch .env; \
if [ "$TARGETARCH" = "arm64" ]; then \
export DOWNLOAD_URL=$(echo $DOWNLOAD_URL_BASE$DOWNLOAD_arm64) ; \
elif [ "$TARGETARCH" = "amd64" ]; then \
export DOWNLOAD_URL=$(echo $DOWNLOAD_URL_BASE$DOWNLOAD_amd64) ; \
else \
export DOWNLOAD_URL="" ; \
fi; \
echo DOWNLOAD_URL=$DOWNLOAD_URL > .env; \
curl ... #ENVS JUST VALID IN THIS RUN!
COPY ./entrypoint.sh ./entrypoint.sh
ENTRYPOINT ["/bin/bash", "entrypoint.sh"]
entrypoint.sh
#!/bin/sh
ENV_FILE=/tmp/.env
if [ -f "$ENV_FILE" ]; then
echo "export " $(grep -v '^#' $ENV_FILE | xargs -d '\n') >> /etc/bash.bashrc
rm $ENV_FILE
fi
trap : TERM INT; sleep infinity & wait
Test:
# bash
root#da1dd15acb64:/tmp# echo $DOWNLOAD_URL
https://download.url/path/to/toolkit-aarch64
Now for Alpine:
Dockerfile
FROM alpine:3.13
RUN apk add --no-cache bash
Entrypoint.sh
ENV_FILE=/tmp/.env
if [ -f "$ENV_FILE" ]; then
echo "export " $(grep -v '^#' $ENV_FILE) >> /etc/profile.d/environ.sh
rm $ENV_FILE
fi
Alpine does not accept xargs -d. But not that interesting here due to the fact URL does not contain any blank..
Testing:
Alpine just uses that for login shells.. so:
docker exec -it containername sh --login
echo $DOWNLOAD_URL
I had a similar problem, and landed here for ideas to solve it. In the end, I used uname -p
curl -sSL https://download.url/path/to/toolkit-$(uname -p) -o /tmp/toolkit-${TARGETARCH}

Issues deploying Self-Hosted Agent on Linux (Ubuntu 18.04) Container

To begin, I followed this documentation in order to deploy a self-hosted agent on a linux container. I didn't do anything other than create the Dockerfile as start.sh file as it stated (copy and paste) to confirm I will add the files here:
Dockerfile
FROM ubuntu:18.04
# To make it easier for build and release pipelines to run apt-get,
# configure apt to not require confirmation (assume the -y argument by default)
ENV DEBIAN_FRONTEND=noninteractive
RUN echo "APT::Get::Assume-Yes \"true\";" > /etc/apt/apt.conf.d/90assumeyes
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
jq \
git \
iputils-ping \
libcurl4 \
libicu60 \
libunwind8 \
netcat \
libssl1.0
WORKDIR /azp
COPY ./start.sh .
RUN chmod +x start.sh
CMD ["./start.sh"]
Start.sh
#!/bin/bash
set -e
if [ -z "$AZP_URL" ]; then
echo 1>&2 "error: missing AZP_URL environment variable"
exit 1
fi
if [ -z "$AZP_TOKEN_FILE" ]; then
if [ -z "$AZP_TOKEN" ]; then
echo 1>&2 "error: missing AZP_TOKEN environment variable"
exit 1
fi
AZP_TOKEN_FILE=/azp/.token
echo -n $AZP_TOKEN > "$AZP_TOKEN_FILE"
fi
unset AZP_TOKEN
if [ -n "$AZP_WORK" ]; then
mkdir -p "$AZP_WORK"
fi
rm -rf /azp/agent
mkdir /azp/agent
cd /azp/agent
export AGENT_ALLOW_RUNASROOT="1"
cleanup() {
if [ -e config.sh ]; then
print_header "Cleanup. Removing Azure Pipelines agent..."
./config.sh remove --unattended \
--auth PAT \
--token $(cat "$AZP_TOKEN_FILE")
fi
}
print_header() {
lightcyan='\033[1;36m'
nocolor='\033[0m'
echo -e "${lightcyan}$1${nocolor}"
}
# Let the agent ignore the token env variables
export VSO_AGENT_IGNORE=AZP_TOKEN,AZP_TOKEN_FILE
print_header "1. Determining matching Azure Pipelines agent..."
AZP_AGENT_RESPONSE=$(curl -LsS \
-u user:$(cat "$AZP_TOKEN_FILE") \
-H 'Accept:application/json;api-version=3.0-preview' \
"$AZP_URL/_apis/distributedtask/packages/agent?platform=linux-x64")
if echo "$AZP_AGENT_RESPONSE" | jq . >/dev/null 2>&1; then
AZP_AGENTPACKAGE_URL=$(echo "$AZP_AGENT_RESPONSE" \
| jq -r '.value | map([.version.major,.version.minor,.version.patch,.downloadUrl]) | sort | .[length-1] | .[3]')
fi
if [ -z "$AZP_AGENTPACKAGE_URL" -o "$AZP_AGENTPACKAGE_URL" == "null" ]; then
echo 1>&2 "error: could not determine a matching Azure Pipelines agent - check that account '$AZP_URL' is correct and the token is valid for that account"
exit 1
fi
print_header "2. Downloading and installing Azure Pipelines agent..."
curl -LsS $AZP_AGENTPACKAGE_URL | tar -xz & wait $!
source ./env.sh
print_header "3. Configuring Azure Pipelines agent..."
./config.sh --unattended \
--agent "${AZP_AGENT_NAME:-$(hostname)}" \
--url "$AZP_URL" \
--auth PAT \
--token $(cat "$AZP_TOKEN_FILE") \
--pool "${AZP_POOL:-Default}" \
--work "${AZP_WORK:-_work}" \
--replace \
--acceptTeeEula & wait $!
print_header "4. Running Azure Pipelines agent..."
trap 'cleanup; exit 130' INT
trap 'cleanup; exit 143' TERM
# To be aware of TERM and INT signals call run.sh
# Running it with the --once flag at the end will shut down the agent after the build is executed
./run.sh & wait $!
Despite copy and pasting these from the documentation. I receive an error when it reaches the 3rd step (Configuring Azure Pipelines Agent) in the start.sh script.
Error message: qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory
If it helps, I am running docker on MacOS but as you can see the container is Ubuntu.
Thank you
According the documentation, we can know Both Windows and Linux are supported as container hosts. But the MacOS is not support as container hosts. So you can try to create a new Windows docker container to try again.

Docker not installing composer dependencies after image built

I built a simple dockerfile using php5.6-fpm image. This file should run my site php code and install all required dependencies. The problem is that php is working, but dependencies like
composer install --working-dir=/var/www/html $COMPOSER_ARGS
and
cp /var/www/html/config.inc.php.dist /var/www/html/config.inc.php
are not installed.
Dockerfile:
FROM php:5.6-fpm
LABEL maintainer "karolis#pretendentas.lt"
WORKDIR /var/www/html
VOLUME /var/www/html
EXPOSE 9000
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN set -ex \
&& apt-get update && apt-get install -y \
zip \
git \
libxml2-dev \
libjpeg-dev \
libpng12-dev \
&& docker-php-ext-configure gd --with-png-dir=/usr/ --with-jpeg-dir=/usr/ \
&& docker-php-ext-install -j$(nproc) bcmath gd mysqli opcache soap
RUN mkdir -p /var/lib/php/session \
&& mkdir -p /var/lib/php/wsdlcache \
&& chown -R www-data:www-data /var/lib/php/session \
&& chown -R www-data:www-data /var/lib/php/wsdlcache \
&& chmod +x /docker-entrypoint.sh
ENV GITHUB_TOKEN ********************
RUN set -ex \
&& curl -sS https://getcomposer.org/installer | php -- \
--install-dir=/usr/bin \
--filename=composer \
&& composer config -g github-oauth.github.com $GITHUB_TOKEN
ENTRYPOINT ["/docker-entrypoint.sh"]
docker-entrypoint.sh:
#!/bin/bash
set -e
if [ -f var/www/html/docker/init.sh ]; then
sleep 5 && echo "[info] Running /var/www/html/init.sh script" && sh /var/www/html/init.sh &
fi
docker-php-entrypoint php-fpm
init.sh:
#!/bin/bash
if [ -f /var/www/html/composer.json ] && [ ! -d /var/www/html/vendor ]; then
echo "[info] Composer install"
composer install --working-dir=/var/www/html $COMPOSER_ARGS
fi
if [ ! -f /var/www/html/config.inc.php ]; then
echo "[info] Copy default config"
cp /var/www/html/config.inc.php.dist /var/www/html/config.inc.php
fi
this is php image snippet from docker-compose file:
php:
image: pretendentas/php5.6-test
ports:
- "9000:9000"
volumes:
- .:/var/www/html
- ./docker/php/php.ini:/usr/local/etc/php/php.ini:ro
working_dir: /var/www/html
restart: always
depends_on:
- db
I think you ask into wrong path to execute the file.
dockerfile
COPY init.sh /var/www/html/init.sh
entrypoint.sh
if [ -f var/wwww/html/docker/init.sh ];
Fix the typos here:
if [ -f var/wwww/html/docker/init.sh ];
To:
if [ -f /var/www/html/docker/init.sh ];
However, take into account that the COPY of init.sh is being overrided by the volume. So in the entrypoint.sh refer to the correct path of init.sh. I assume that init.sh is in the project root dir, so it is located at the root of the volume: /var/www/html
if [ -f /var/www/html/init.sh ]; then
sleep 5 && echo "[info] Running /var/www/html/init.sh script " && sh /var/www/html/init.sh &
fi

Resources