useradd invalid user in Dockerfile - laravel

I'm trying to use a docker image with Laravel + Microsoft SQL drivers.
My dockerfile:
FROM php:7.2-apache
ENV ACCEPT_EULA=Y
# Microsoft SQL Server Prerequisites
RUN apt-get update \
&& curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
&& curl https://packages.microsoft.com/config/debian/9/prod.list \
> /etc/apt/sources.list.d/mssql-release.list \
&& apt-get install -y --no-install-recommends \
locales \
apt-transport-https \
&& echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \
&& locale-gen \
&& apt-get update \
&& apt-get -y --no-install-recommends install \
unixodbc-dev \
msodbcsql17
RUN docker-php-ext-install mbstring pdo pdo_mysql \
&& pecl install sqlsrv pdo_sqlsrv xdebug \
&& docker-php-ext-enable sqlsrv pdo_sqlsrv xdebug
COPY index.php /var/www/html/
# We need a user with the same UID/GID as the host user
# so when we execute CLI commands, all the host file's permissions and ownership remain intact.
# Otherwise commands from inside the container would create root-owned files and directories.
ARG uid
RUN useradd -G www-data,root -o -u $uid -d /home/devuser devuser
RUN mkdir -p /home/devuser/.composer && \
chown -R devuser:devuser /home/devuser
When building using docker-compose build, I am getting invalid user:
useradd: invalid user ID '-d'
The command '/bin/sh -c useradd -G www-data,root -o -u $uid -d /home/devuser devuser' returned a non-zero code: 3

In my case the reason was, that I tried to build the image directly using
docker build --tag imagename .
instead of using
docker-compose build app
from where the $uid value was supplied.

Setting a default value to your ARG uid can works:

You have to specify the UID in your .env file like:
UID=1000
if you do not know the UID of your user, type id into your terminal

Related

neo4j 4.0 testing with embedded database DatabaseManagementServiceBuilder is found nowhere

I'm a beginner in neo4j. I'm trying to build tests using embedded neo4j database inside a springboot application. I haven't succeeded since the class DatabaseManagementServiceBuilder is found nowhere Please note I'm using version 4.0.2 Any help please ?
The full classname is org.neo4j.dbms.api.DatabaseManagementServiceBuilder.
Here is a sample class that uses the builder.
I've struggled with using an embedded neo4j db for my tests a few months back as well.
In case you don't find a suitable solution for the embedded version, I ended up starting a real instance of the db...
I adjusted a bit neo4j's official Dockerfile to use jdk instead of jre and was able to run my tests against it.
Here's the Dockerfile, starting from the official 3.4.5-enterprise Dockerfile:
FROM openjdk:8-jdk-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
make && \
rm -rf /var/lib/apt/lists/*
ADD maven-settings.xml /root/.m2/settings.xml
# from official neo4j:3.4.5-enterprise image content (changed base image to use jdk instead of jre)
RUN addgroup --system neo4j && adduser --system --no-create-home --home /var/lib/neo4j --ingroup neo4j neo4j
ENV NEO4J_SHA256=0629f17a99ba90d6900c98f332c775a732cc2ad6298b8df41a2872277b19e6e3 \
NEO4J_TARBALL=neo4j-enterprise-3.4.5-unix.tar.gz \
NEO4J_EDITION=enterprise \
NEO4J_ACCEPT_LICENSE_AGREEMENT=yes \
TINI_VERSION="v0.18.0" \
TINI_SHA256="12d20136605531b09a2c2dac02ccee85e1b874eb322ef6baf7561cd93f93c855"
ARG NEO4J_URI=http://dist.neo4j.org/neo4j-enterprise-3.4.5-unix.tar.gz
RUN apt update \
&& apt install -y \
bash \
curl \
&& curl -L --fail --silent --show-error "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini" > /sbin/tini \
&& echo "${TINI_SHA256} /sbin/tini" | sha256sum -c --strict --quiet \
&& chmod +x /sbin/tini \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* /var/lib/neo4j \
&& rm ${NEO4J_TARBALL} \
&& mv /var/lib/neo4j/data /data \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& chown -R neo4j:neo4j /var/lib/neo4j \
&& chmod -R 777 /var/lib/neo4j \
&& ln -s /data /var/lib/neo4j/data
# Install latest su-exec
RUN set -ex; \
\
curl -o /usr/local/bin/su-exec.c https://raw.githubusercontent.com/ncopa/su-exec/master/su-exec.c; \
\
fetch_deps='gcc libc-dev'; \
apt-get update; \
apt-get install -y --no-install-recommends $fetch_deps; \
rm -rf /var/lib/apt/lists/*; \
gcc -Wall \
/usr/local/bin/su-exec.c -o/usr/local/bin/su-exec; \
chown root:root /usr/local/bin/su-exec; \
chmod 0755 /usr/local/bin/su-exec; \
rm /usr/local/bin/su-exec.c; \
\
apt-get purge -y --auto-remove $fetch_deps
ENV PATH /var/lib/neo4j/bin:$PATH
ARG NEO4J_AUTH=neo4j/neo4jtest
ENV NEO4J_AUTH=${NEO4J_AUTH}
WORKDIR /var/lib/neo4j
VOLUME /data
COPY docker-entrypoint.sh /docker-entrypoint.sh
EXPOSE 7474 7473 7687
ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
CMD ["neo4j"]
I used the original docker-entrypoint.sh script.

Dockerfile setting a home directory

I am writing a dockerfile, where one of its dependencies can only be installed only when a homedirectory exist, but how do I set something like that up?
ARG BUILD_FROM=raspbian/stretch:latest
FROM $BUILD_FROM
RUN apt-get -qq update \
&& apt-get -qq install -y --no-install-recommends \
apt-transport-https \
apt-utils \
dirmngr \
gnupg-curl \
mpg123 \
supervisor \
unzip \
curl \
git \
wget \
python3 \
&& pip3 install -U setuptools && pip3 install utils\
&& pip3 install -r requirements.txt
requirements.txt
slugify
google-api-python-client
oauth2client
esptool
this can only be installed using pip3 install --user slugify which requires an homedir which I can't setup..
You can either create the dir manually by using a line like
RUN mkdir /home/slugify
or if you need a full user with permissions etc you can run
RUN adduser slugify
Read more at the manpage https://manpages.debian.org/jessie/adduser/adduser.8.sv.html
I think there should be an user home set by default.
However, you can change it using usermod -d /newhome/username username:
RUN mkdir /homedir
RUN usermod -d /homedir root
Maybe the program just needs an environment variable HOME:
RUN HOME=/homedir;<install command>

Excecute .sh file on start of Docker container and let container run

I have a docker container that serves a webserver. On every startup of the container, I want to excecute a little shell script. The script that has to be executed has only one statement.
/var/www/html/app/Console/cake schema update -y
To achieve this, I created a .sh file called schemaupdate.sh which I copy into the docker container using the dockerfile into the /etc/init.d folder. Furthermore I make it executable and register it to the startup.
COPY schemaupdate.sh /etc/init.d/schemaupdate.sh
chmod 755 /etc/init.d/schemaupdate.sh
update-rc.d schemaupdate.sh defaults
The file is successfully copied into the container. However, the script is not executed when the docker container starts. When I manually call the sh file, everything is running fine.
How can I achieve, that the file / statement is executed on each startup of a container? It is important, that the script is executed at the startup and the container (so the webserver) still continues to run! The script only makes a little update check and after the check the webserver keeps on going.
The container is a debian based container. Here is inital dockerfile.
#start with base Image from php
FROM php:7.3-apache
#install system dependencies and enable PHP modules
RUN apt-get update && apt-get install -y \
libicu-dev \
libpq-dev \
libmcrypt-dev \
mysql-client \
git \
zip \
unzip \
&& rm -r /var/lib/apt/lists/* \
&& docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
&& docker-php-ext-install \
intl \
mbstring \
pcntl \
pdo_mysql \
pdo_pgsql \
pgsql \
opcache
# zip \
# mcrypt \
#configure imap for mails
RUN apt-get update && \
apt-get install -y \
libc-client-dev libkrb5-dev && \
rm -r /var/lib/apt/lists/*
RUN docker-php-ext-configure imap --with-kerberos --with-imap-ssl && \
docker-php-ext-install -j$(nproc) imap
#install mcrypt
RUN apt-get update \
&& apt-get install -y libmcrypt-dev \
&& rm -rf /var/lib/apt/lists/* \
&& pecl install mcrypt-1.0.2 \
&& docker-php-ext-enable mcrypt
#install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
#set our application folder as an environment variable
ENV APP_HOME /var/www/html
#change uid and gid of apache to docker user uid/gid
RUN usermod -u 1000 www-data && groupmod -g 1000 www-data
#change the web_root to cakephp /var/www/html/webroot folder
#RUN sed -i -e "s/html/html\/webroot/g" /etc/apache2/sites-enabled/000-default.conf
# enable apache module rewrite
RUN a2enmod rewrite
#copy source files and run composer
#COPY src/ /var/www/html
#COPY src/ $APP_HOME
# install all PHP dependencies
#RUN composer install --no-interaction
#SET Volume
VOLUME /var/www/html/
#change ownership of our applications
RUN chown -R www-data:www-data $APP_HOME
#SET ENV VARIABLES
COPY schemaupdate.sh /etc/init.d/schemaupdate.sh
chmod 755 /etc/init.d/schemaupdate.sh
update-rc.d schemaupdate.sh defaults
EXPOSE 80
/etc/init.d/ isn't relevant. Containers aren't full blown operating systems with a heavyweight SysV init-style startup sequence. They run a single command, that's it.
You should either add the command as a RUN statement in the Dockerfile so its results are baked into the image, or you should have it called directly by the container's CMD or ENTRYPOINT directive.
I Finally used the Entrypoint. I deleted the COPY, chmod and update-rc. The Entrypoint looks like the following.
ENTRYPOINT [ "sh", "-c", "/var/www/html/app/Console/cake schema update -y && /var/www/html/app/Console/cake schema update -y && /usr/sbin/apachectl -D FOREGROUND"]
It first starts the update statment. After this is finished (so terminated), the apachectl is called to keep the webserver running.

Deploy a Dockerized Laravel app using Apache on Heroku

I'm trying to deploy a Laravel 5.5 app using Docker on Heroku. I'm coming up against the problem where Heroku dynamically assigns the $PORT value though, and I can't figure out where to tell Apache to use $PORT instead of port 80. Has anyone else had success deploying an app using Apache in Docker to Heroku with the $PORT specification?
To be specific, this is the error I get tailing the Heroku logs:
2019-01-31T14:01:17.605297+00:00 app[web.1]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:80
which I understand to mean that the container is trying to listen on Port 80, but the host is using $PORT instead of 80.
Here's my Dockerfile:
FROM php:7.1.5-apache
#install all the system dependencies and enable PHP modules
RUN apt-get update && apt-get install -y \
libicu-dev \
libpq-dev \
libmcrypt-dev \
git \
zip \
unzip \
&& rm -r /var/lib/apt/lists/* \
&& docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
&& docker-php-ext-install \
intl \
mbstring \
mcrypt \
pcntl \
pdo_mysql \
pdo_pgsql \
pgsql \
zip \
opcache
ENV PHPREDIS_VERSION 3.0.0
RUN mkdir -p /usr/src/php/ext/redis \
&& curl -L https://github.com/phpredis/phpredis/archive/$PHPREDIS_VERSION.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \
&& echo 'redis' >> /usr/src/php-available-exts \
&& docker-php-ext-install redis
#install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
#set our application folder as an environment variable
ENV APP_HOME /var/www/html
#change uid and gid of apache to docker user uid/gid
RUN usermod -u 1000 www-data && groupmod -g 1000 www-data
#change the web_root to laravel /var/www/html/public folder
RUN sed -i -e "s/html/html\/public/g" /etc/apache2/sites-enabled/000-default.conf
# enable apache module rewrite
RUN a2enmod rewrite
#copy source files and run composer
COPY . $APP_HOME
# install all PHP dependencies
RUN composer install --no-interaction
#change ownership of our applications
RUN chown -R www-data:www-data $APP_HOME
And here's my Heroku Procfile:
web: vendor/bin/heroku-php-apache2 public/
And here's my heroku.yml:
build:
docker:
web: Dockerfile
Thanks!
Got it.
Using this SO post, I discovered I could insert a CMD statement at the end of my Dockerfile to sed replace the ports in my apache config files to the magical $PORT environment variable at run time.
New Dockerfile below:
#start with our base image (the foundation) - version 7.1.5
FROM php:7.1.5-apache
#install all the system dependencies and enable PHP modules
RUN apt-get update && apt-get install -y \
libicu-dev \
libpq-dev \
libmcrypt-dev \
git \
zip \
unzip \
&& rm -r /var/lib/apt/lists/* \
&& docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
&& docker-php-ext-install \
intl \
mbstring \
mcrypt \
pcntl \
pdo_mysql \
pdo_pgsql \
pgsql \
zip \
opcache
ENV PHPREDIS_VERSION 3.0.0
RUN mkdir -p /usr/src/php/ext/redis \
&& curl -L https://github.com/phpredis/phpredis/archive/$PHPREDIS_VERSION.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \
&& echo 'redis' >> /usr/src/php-available-exts \
&& docker-php-ext-install redis
#install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
#set our application folder as an environment variable
ENV APP_HOME /var/www/html
#change uid and gid of apache to docker user uid/gid
RUN usermod -u 1000 www-data && groupmod -g 1000 www-data
#change the web_root to laravel /var/www/html/public folder
RUN sed -i -e "s/html/html\/public/g" /etc/apache2/sites-enabled/000-default.conf
# enable apache module rewrite
RUN a2enmod rewrite
#copy source files and run composer
COPY . $APP_HOME
# install all PHP dependencies
RUN composer install --no-interaction
#change ownership of our applications
RUN chown -R www-data:www-data $APP_HOME
#update apache port at runtime for Heroku
ENTRYPOINT []
CMD sed -i "s/80/$PORT/g" /etc/apache2/sites-enabled/000-default.conf /etc/apache2/ports.conf && docker-php-entrypoint apache2-foreground

Init Laravel passport from within docker

I'm in the process of dockerizing our dev environement. The application consists among other things of a laravel app exposing a REST API. Authentication is done through laravel passport.
As this is intented for dev only, I'm installing composer dependencies, setting application encryption key, migrating datatabases and setting passport keys at run time. Everything is initialised correctly except for the passport keys. No matter how I tried to approach the problem I end up with the following error:
fpm_1 | In CryptKey.php line 45:
fpm_1 |
fpm_1 | Key path "file:///var/www/html/storage/oauth-public.key" does not exist or
fpm_1 | is not readable
This is the relevant part of my docker-compose file.
version: '3'
services:
fpm:
build: ./api/docker/fpm
restart: unless-stopped
volumes:
- ./api:/var/www/html
- /etc/passwd:/etc/passwd
user: "${UID}:${GID}"
My fpm dockerfile (./api/docker/fpm/Dockerfile)
FROM php:7.2.6-fpm
COPY ./init-app.sh /usr/local/bin/
COPY ./install-composer.sh /usr/local/bin/
RUN apt-get update && apt-get install -y --no-install-recommends libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev libpng-dev \
libzip-dev \
libzip4 \
git \
zip \
wget \
&& apt-get autoremove \
&& apt-get clean \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install gd \
&& docker-php-ext-configure zip --with-libzip=/usr/include/ \
&& docker-php-ext-install zip \
&& docker-php-ext-install pdo_mysql \
&& chmod +x /usr/local/bin/init-app.sh \
&& chmod +x /usr/local/bin/install-composer.sh \
&& /usr/local/bin/install-composer.sh \
&& rm /usr/local/bin/install-composer.sh \
&& wget https://raw.githubusercontent.com/vishnubob/wait-for-it/8ed92e8cab83cfed76ff012ed4a36cef74b28096/wait-for-it.sh \
&& chmod +x wait-for-it.sh \
&& mv wait-for-it.sh /usr/local/bin/
ENTRYPOINT [ "/usr/local/bin/init-app.sh" ]
CMD ["php-fpm"]
install-composer.sh installs composer into the container at build time.
init-app.sh:
#!/bin/sh
set -e
# Install composer dependencies
composer install
# Copy env file
cp .env.example .env
# Wait for DB to be up
/usr/local/bin/wait-for-it.sh db:3306 -t 0 --strict -- php artisan key:generate && php artisan migrate:refresh --seed
php artisan passport:install
# Run upstream entrypoint
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- php-fpm "$#"
fi
exec "$#"
My user is correctly mapped inside the fpm container as I export $UID and $GID in .zshrc. Commenting out the passport:install line in my init-app.sh in order to let container boot correctly, I'm able to generate the keys by running docker exec -it php artisan passport:install just fine. But letting the container handle it fails.
Turns out, one of my database seeder, somehow required the key to be present. while I investigate, I fixed the problem by swapping instructions (the seeding and passport keys installation)

Resources