How can I extend unregistered docker images or dockerfiles? - docker

Or maybe instead of using FROM there is a way to inject the contents of another dockerfile into the start of my own.

In any case you will need a base Operating System image to source from and then you can use the content of the "other" Dockerfile you want to use and append your own command and form a complete file.
For example the below line will just include the base OS layer:
FROM ubuntu
MAINTAINER Prasanjit Singh
And then add stuff from the borrowed docker file, say the below lines:
ENV USER root ENV PASS aiPeekai0AeZ2meephoolais7doo1thu
RUN \ apt-get update && \ apt-get -y install \
mysql-server-5.5 && \ rm -rf /var/lib/apt/lists/*
COPY my.cnf /etc/mysql/my.cnf COPY start.sh start.sh
VOLUME ["/var/lib/mysql"]
RUN rm /usr/sbin/policy-rc.d CMD ["/start.sh"]
EXPOSE 3306
And finally add your append your own(if any) and the file looks like this now:
FROM ubuntu
MAINTAINER Prasanjit Singh
ENV USER root
ENV PASS aiPeekai0AeZ2meephoolais7doo1thu
RUN \
apt-get update && \
apt-get -y install \
mysql-server-5.5 && \
rm -rf /var/lib/apt/lists/*
COPY my.cnf /etc/mysql/my.cnf
COPY start.sh start.sh
VOLUME ["/var/lib/mysql"]
RUN rm /usr/sbin/policy-rc.d
RUN rm /your/shell/script_or_command.sh # Add your stuff
CMD ["/start.sh"]
EXPOSE 3306
And you are done with the Dockerfile. Just build it and get your container launched. Let me know if it you need anything.

Related

How does this Dockerfile actually run logstash without an entrypoint or cmd?

Just doing a container start on this official logstash docker container does make logstash properly run, given the right config.
It does not have an entrypoint or cmd, or anything of the sort though. I am also not issuing one on the start command. So, how is logstash actually getting executed in this case?
I need to know because I need to edit the command for other reasons. We're working on running it in kubernetes but are just testing with local docker for now.
https://github.com/elastic/logstash/blob/7.15/Dockerfile
Copied for easy reference:
FROM ubuntu:bionic
RUN apt-get update && \
apt-get install -y zlib1g-dev build-essential vim rake git curl libssl-dev libreadline-dev libyaml-dev \
libxml2-dev libxslt-dev openjdk-11-jdk-headless curl iputils-ping netcat && \
apt-get clean
WORKDIR /root
RUN adduser --disabled-password --gecos "" --home /home/logstash logstash && \
mkdir -p /usr/local/share/ruby-build && \
mkdir -p /opt/logstash && \
mkdir -p /opt/logstash/data && \
mkdir -p /mnt/host && \
chown logstash:logstash /opt/logstash
USER logstash
WORKDIR /home/logstash
# used by the purge policy
LABEL retention="keep"
# Setup gradle wrapper. When running any `gradle` command, a `settings.gradle` is expected (and will soon be required).
# This section adds the gradle wrapper, `settings.gradle` and sets the permissions (setting the user to root for `chown`
# and working directory to allow this and then reverts back to the previous working directory and user.
COPY --chown=logstash:logstash gradlew /opt/logstash/gradlew
COPY --chown=logstash:logstash gradle/wrapper /opt/logstash/gradle/wrapper
COPY --chown=logstash:logstash settings.gradle /opt/logstash/settings.gradle
WORKDIR /opt/logstash
RUN for iter in `seq 1 10`; do ./gradlew wrapper --warning-mode all && exit_code=0 && break || exit_code=$? && echo "gradlew error: retry $iter in 10s" && sleep 10; done; exit $exit_code
WORKDIR /home/logstash
ADD versions.yml /opt/logstash/versions.yml
ADD LICENSE.txt /opt/logstash/LICENSE.txt
ADD NOTICE.TXT /opt/logstash/NOTICE.TXT
ADD licenses /opt/logstash/licenses
ADD CONTRIBUTORS /opt/logstash/CONTRIBUTORS
ADD Gemfile.template Gemfile.jruby-2.5.lock.* /opt/logstash/
ADD Rakefile /opt/logstash/Rakefile
ADD build.gradle /opt/logstash/build.gradle
ADD rubyUtils.gradle /opt/logstash/rubyUtils.gradle
ADD rakelib /opt/logstash/rakelib
ADD config /opt/logstash/config
ADD spec /opt/logstash/spec
ADD qa /opt/logstash/qa
ADD lib /opt/logstash/lib
ADD pkg /opt/logstash/pkg
ADD tools /opt/logstash/tools
ADD logstash-core /opt/logstash/logstash-core
ADD logstash-core-plugin-api /opt/logstash/logstash-core-plugin-api
ADD bin /opt/logstash/bin
ADD modules /opt/logstash/modules
ADD x-pack /opt/logstash/x-pack
ADD ci /opt/logstash/ci
USER root
RUN rm -rf build && \
mkdir -p build && \
chown -R logstash:logstash /opt/logstash
USER logstash
WORKDIR /opt/logstash
LABEL retention="prune"
If you look at the final layer on the image here, it looks like there is an ENTRYPOINT ["/usr/local/bin/docker-entrypoint"]. The Dockerfile you've linked might not be the one used to build the image.

Adding files to a docker instance not working

I have the following snippet in my docker file:
...
ADD app.war /opt/apache-tomcat-8.5.14/webapps/app.war
...
However, entering the docker image as:
docker exec -it tomcat /bin/sh
and doing an ls to the webapps folder, the file isn't there. The file, in my local OS, windows, it is in the same folder as the dockerfile. Any clue about why this happens?
EDIT:
However, using the cp command in my windows cmd, it works correctly after checking in the container.
The dockerfile:
FROM alpine:latest
MAINTAINER Adilson Cesar <adilsonbna#gmail.com>
# Expose Web Port
EXPOSE 8080
# Set environment
ENV JAVA_HOME /opt/jdk
ENV PATH ${PATH}:${JAVA_HOME}/bin
ENV JAVA_PACKAGE server-jre
ENV TOMCAT_VERSION_MAJOR 8
ENV TOMCAT_VERSION_FULL 8.5.14
ENV CATALINA_HOME /opt/tomcat
# Download and install Java
RUN apk --update add openjdk8-jre &&\
mkdir -p /opt/jdk &&\
ln -s /usr/lib/jvm/java-1.8-openjdk/bin /opt/jdk
# Download and install Tomcat
RUN apk add --update curl &&\
curl -LO https://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_VERSION_MAJOR}/v${TOMCAT_VERSION_FULL}/bin/apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz &&\
curl -LO https://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_VERSION_MAJOR}/v${TOMCAT_VERSION_FULL}/bin/apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz.md5 &&\
md5sum -c apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz.md5 &&\
gunzip -c apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz | tar -xf - -C /opt &&\
rm -f apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz.md5 &&\
ln -s /opt/apache-tomcat-${TOMCAT_VERSION_FULL} /opt/tomcat &&\
rm -rf /opt/tomcat/webapps/examples /opt/tomcat/webapps/docs &&\
apk del curl &&\
rm -rf /var/cache/apk/*
ADD app.war /opt/apache-tomcat-8.5.14/webapps/
# Launch Tomcat on startup
CMD ${CATALINA_HOME}/bin/catalina.sh run
Thanks!
Although docker docs suggest otherwise
If <dest> does not end with a trailing slash, it will be considered a regular file and the contents of <src> will be written at <dest>
Try this by removing the destination filename. It should work.
ADD app.war /opt/apache-tomcat-8.5.14/webapps/
Also, from Docker Best Practices it is advised to use COPY instead of ADD if you're just copying local files and not playing around with remote URLs.
Although ADD and COPY are functionally similar, generally speaking, COPY is preferred. That’s because it’s more transparent than ADD

Why "docker build" fails on local image

Probably I'm missing something obvious, but could someone please explain the following:
When I pull and run an image, e.g docker pull dgraziotin/lamp && docker run -t -i -p 80:80 -p 3306:3306 --name osxlamp dgraziotin/lamp - it works just fine
Now I want to play with Dockerfile and build it manually on my computer (I can do this, right?)
So I download the source files from Github https://github.com/dgraziotin/osx-docker-lamp, cd to unpacked folder and run docker build -t test .
The building process starts but I see lot of weird errors like "Package php5-mysql is not available". I tried different images with the same result. How to properly build local images?
UPD:
Dockerfile
FROM phusion/baseimage:latest
MAINTAINER Daniel Graziotin <daniel#ineed.coffee>
ENV REFRESHED_AT 2016-03-29
# based on tutumcloud/tutum-docker-lamp
# MAINTAINER Fernando Mayo <fernando#tutum.co>, Feng Honglin <hfeng#tutum.co>
ENV DOCKER_USER_ID 501
ENV DOCKER_USER_GID 20
ENV BOOT2DOCKER_ID 1000
ENV BOOT2DOCKER_GID 50
# Tweaks to give Apache/PHP write permissions to the app
RUN usermod -u ${BOOT2DOCKER_ID} www-data && \
usermod -G staff www-data && \
useradd -r mysql && \
usermod -G staff mysql
RUN groupmod -g $(($BOOT2DOCKER_GID + 10000)) $(getent group $BOOT2DOCKER_GID | cut -d: -f1)
RUN groupmod -g ${BOOT2DOCKER_GID} staff
# Install packages
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get -y install supervisor wget git apache2 libapache2-mod-php5 mysql-server php5-mysql pwgen php-apc php5-mcrypt zip unzip && \
echo "ServerName localhost" >> /etc/apache2/apache2.conf
# needed for phpMyAdmin
run php5enmod mcrypt
# Add image configuration and scripts
ADD start-apache2.sh /start-apache2.sh
ADD start-mysqld.sh /start-mysqld.sh
ADD run.sh /run.sh
RUN chmod 755 /*.sh
ADD supervisord-apache2.conf /etc/supervisor/conf.d/supervisord-apache2.conf
ADD supervisord-mysqld.conf /etc/supervisor/conf.d/supervisord-mysqld.conf
# Remove pre-installed database
RUN rm -rf /var/lib/mysql
# Add MySQL utils
ADD create_mysql_users.sh /create_mysql_users.sh
RUN chmod 755 /*.sh
# Add phpmyadmin
RUN wget -O /tmp/phpmyadmin.tar.gz https://files.phpmyadmin.net/phpMyAdmin/4.6.0/phpMyAdmin-4.6.0-all-languages.tar.gz
RUN tar xfvz /tmp/phpmyadmin.tar.gz -C /var/www
RUN ln -s /var/www/phpMyAdmin-4.6.0-all-languages /var/www/phpmyadmin
RUN mv /var/www/phpmyadmin/config.sample.inc.php /var/www/phpmyadmin/config.inc.php
ENV MYSQL_PASS:-$(pwgen -s 12 1)
# config to enable .htaccess
ADD apache_default /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite
# Configure /app folder with sample app
RUN mkdir -p /app && rm -fr /var/www/html && ln -s /app /var/www/html
ADD app/ /app
#Environment variables to configure php
ENV PHP_UPLOAD_MAX_FILESIZE 10M
ENV PHP_POST_MAX_SIZE 10M
# Add volumes for the app and MySql
VOLUME ["/etc/mysql", "/var/lib/mysql", "/app" ]
EXPOSE 80 3306
CMD ["/run.sh"]
SOLVED As I understood many of custom images contain outdated/invalid code and must be avoided as much as possible. We should rely on official well known and supported images.
Unrelated to the exact problem, but your Dockerfile could use some rework based on Best Practices for writing Dockerfiles.
I'd like to point out the ADD vs COPY best practice and the deprecated MAINTAINER Instruction (you should use LABEL maintainer="Daniel Graziotin ").
Also on the part where you add phpmyadmin it's useless to use RUN instead of ADD if you don't extract and delete the archive in the same layer (using multiline arguments). This can also be found under the ADD vs COPY best practices.
Other than that I can say this is a pretty solid Dockerfile! Sad it won't work because of the application...

How to handle PHP project code in docker container

I ran into kind of a hen-and-egg problem with my docker setup. In my Dockerfile I install nginx, php and the needed configurations. I also install composer there:
FROM ubuntu
RUN apt-get update && apt-get install -y \
curl \
nginx \
nodejs \
php7.0-fpm \
php-intl \
php-pgsql
RUN rm -rf /var/lib/apt/lists/* && \
echo "\ndaemon off;" >> /etc/nginx/nginx.conf && \
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin && \
chown -R www-data:www-data /var/www/
COPY orocrm /etc/nginx/sites-available/
RUN ln -s /etc/nginx/sites-availabe/orocrm /etc/nginx/sites-enabled/orocrm
CMD nginx
Now, the next step would be to actually install all dependencies in the project directory via composer. And this is where the trouble starts: As this is my development machine, I don't want to copy my local project files over to the docker container. Instead, I mounted it in my docker-compose.yml:
version: '3'
services:
web:
...
volumes:
- "./crm-application:/var/www/orocrm/"
I cannot put composer install in the Dockerfile, as the mounting of the directory (in my docker-compose file) is taking place after the Dockerfile is run.
What is the best solution here? Another option which comes to my mind is intially copying the files into the container and later on use a filewatcher to scp the changed files into the container. Not a nice solution, though.
UPDATE I would like to emphasize what my actual problem is: I am on my development machine and I want to continuously update the code and have the changes mirrored instantly withouth building the image once again. Therefore, COPY is not an option.
My suggestion is to copy your content in your container using the COPYcommand, like this
FROM ubuntu
COPY ./crm-application /var/www/orocrm/
RUN apt-get update && apt-get install -y \
curl \
nginx \
nodejs \
php7.0-fpm \
php-intl \
php-pgsql
RUN rm -rf /var/lib/apt/lists/* && \
echo "\ndaemon off;" >> /etc/nginx/nginx.conf && \
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin && \
chown -R www-data:www-data /var/www/ && \
composer install
COPY orocrm /etc/nginx/sites-available/
RUN ln -s /etc/nginx/sites-availabe/orocrm /etc/nginx/sites-enabled/orocrm
CMD nginx
Why? in this way you don't need to use docker-compose or another system. You're going to be able to run your single container.
Even if you want to use docker-compose, you're using a volume that allows you to update the code inside your container.
Notice that I've added composer install in the Docker because you've already the code inside the container at the moment of the build.
Regards,
Idir!

Understanding a simple dockerfile of postgresql

I was just reading a docker file HERE.
and basically the Dockerfile looks like follows:
FROM postgres:9.1
MAINTAINER Mike Dillon <mike#appropriate.io>
ENV POSTGIS_MAJOR 2.1
ENV POSTGIS_VERSION 2.1.7+dfsg-3~94.git954a8d0.pgdg80+1
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-$PG_MAJOR-postgis-$POSTGIS_MAJOR=$POSTGIS_VERSION \
postgis=$POSTGIS_VERSION \
&& rm -rf /var/lib/apt/lists/*
RUN mkdir -p /docker-entrypoint-initdb.d
COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/postgis.sh
I want to make sure i have interpreted the below two commands correctly:
RUN mkdir -p /docker-entrypoint-initdb.d
COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/postgis.sh
The RUN command is running a mkdir command , which means the current directory will have a subdirectory called:
/docker-entrypoint-initdb.d
andin the next command I.E. the COPY command the contents of the directory ./initdb-postgis.sh are being copied into /docker-entrypoint-initdb.d/postgis.sh , am i right ?
RUN cmd is used to execute cmd command and will create and commit a new layer for the image your are building. So those commands are run in the context of the image that is being building. mkdir -p /docker-entrypoint-initdb.d will create a new folder docker-entrypoint-initdb.d in the root of the image. COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/postgis.sh will copy the file initdb-postgis.sh (that has to be located at the same level you have run the docker build command to the file /docker-entrypoint-initdb.d/postgis.sh inside the container.

Resources