Understanding a simple dockerfile of postgresql - docker

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.

Related

Run Python scripts on command line running Docker images

I built a docker image using Dockerfile with Python and some libraries inside (no my project code inside). In my local work dir, there are some scripts to be run on the docker. So, here what I did
$ cd /path/to/my_workdir
$ docker run -it --name test -v `pwd`:`pwd` -w `pwd` my/code:test python src/main.py --config=test --results-dir=/home/me/Results
The command python src/main.py --config=test --results-dir=/home/me/Results is what I want to run inside the Docker container.
However, it returns,
/home/docker/miniconda3/bin/python: /home/docker/miniconda3/bin/python: cannot execute binary file
How can I fix it and run my code?
Here is my Dockerfile
FROM nvidia/cuda:10.1-cudnn7-runtime-ubuntu18.04
MAINTAINER Me <me#me.com>
RUN apt update -yq && \
apt install -yq curl wget unzip git vim cmake sudo
RUN adduser --disabled-password --gecos '' docker && \
adduser docker sudo && \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER docker
WORKDIR /home/docker/
RUN chmod a+rwx /home/docker/ && \
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
bash Miniconda3-latest-Linux-x86_64.sh -b && rm Miniconda3-latest-Linux-x86_64.sh
ENV PATH /home/docker/miniconda3/bin:$PATH
Run pip install absl-py==0.5.0 atomicwrites==1.2.1 attrs==18.2.0 certifi==2018.8.24 chardet==3.0.4 cycler==0.10.0 docopt==0.6.2 enum34==1.1.6 future==0.16.0 idna==2.7 imageio==2.4.1 jsonpickle==1.2 kiwisolver==1.0.1 matplotlib==3.0.0 mock==2.0.0 more-itertools==4.3.0 mpyq==0.2.5 munch==2.3.2 numpy==1.15.2 pathlib2==2.3.2 pbr==4.3.0 Pillow==5.3.0 pluggy==0.7.1 portpicker==1.2.0 probscale==0.2.3 protobuf==3.6.1 py==1.6.0 pygame==1.9.4 pyparsing==2.2.2 pysc2==3.0.0 pytest==3.8.2 python-dateutil==2.7.3 PyYAML==3.13 requests==2.19.1 s2clientprotocol==4.10.1.75800.0 sacred==0.8.1 scipy==1.1.0 six==1.11.0 sk-video==1.1.10 snakeviz==1.0.0 tensorboard-logger==0.1.0 torch==0.4.1 torchvision==0.2.1 tornado==5.1.1 urllib3==1.23
USER docker
ENTRYPOINT ["/bin/bash"]
Try making the file executable before running it.
as John mentioned to do in the dockerfile
FROM python:latest
COPY src/main.py /usr/local/share/
RUN chmod +x /usr/local/share/src/main.py #<-**--- just add this also
# I have some doubts about the pathing
CMD ["/usr/local/share/src/main.py", "--config=test --results-dir=/home/me/Results"]
You can run a python script in docker by adding this to your docker file:
FROM python:latest
COPY src/main.py /usr/local/share/
CMD ["src/main.py", "--config=test --results-dir=/home/me/Results"]

Editing a Dockerfile so the image is not run in an interactive shell, but from the ENTRYPOINT

I'm trying to use the docker image of a specific software (picard), and that image is designed to be run interactively, in fact, an already built docker image is provided via Dockerhub:
docker pull broadinstitute/picard
This image works perfectly will the following command:
sudo docker run -i -t -v $PWD:/usr/working broadinstitute/picard
So that within the image one could launch the actual program like:
java -jar /usr/picard/picard.jar [COMMAND] [OPTIONS] ...
What I am trying to accomplish is to execute this image without entering in an interactive shell, simply as:
sudo docker run --rm -v $PWD:/usr/working broadinstitute/picard [COMMAND] [OPTIONS] ...
As far as I understand, this could be done by creating an ENTRYPOINT in the Dockerfile (see it in appendix below), but addind the following line at the bottom of the Dockerfile will not work:
ENTRYPOINT ["java -jar /usr/picard/picard.jar"]
Instead, when I run the image as above, no output is generated, and if a specific command is called (e.g. CreateSequenceDictionary), I get the following error:
docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"CreateSequenceDictionary\": executable file not found in $PATH": unknown.
What am I missing?
Dockerfile
The dockerfile can be found in the github repo at: https://github.com/broadinstitute/picard/blob/master/Dockerfile. It looks like the following:
FROM openjdk:8
MAINTAINER Broad Institute DSDE <dsde-engineering#broadinstitute.org>
ARG build_command=shadowJar
ARG jar_name=picard.jar
# Install ant, git for building
RUN apt-get update && \
apt-get --no-install-recommends install -y --force-yes \
git \
r-base \
ant && \
apt-get clean autoclean && \
apt-get autoremove -y
# Assumes Dockerfile lives in root of the git repo. Pull source files into container
COPY / /usr/picard/
WORKDIR /usr/picard
# Build the distribution jar, clean up everything else
RUN ./gradlew ${build_command} && \
mv build/libs/${jar_name} picard.jar && \
./gradlew clean && \
rm -rf src && \
rm -rf gradle && \
rm -rf .git && \
rm gradlew && \
rm build.gradle
RUN mkdir /usr/working
WORKDIR /usr/working
The problem is how the ENTRYPOINT is defined.
It should be
ENTRYPOINT ["java", "-jar", "/usr/picard/picard.jar"]
src: https://docs.docker.com/v17.09/engine/reference/builder/#entrypoint
I just learnt about other possible alternative that does not require to modify the original dockerfile, which is overriding the default ENTRYPOINT from the CLI (even if the original image does not define one).
This can be done with the --entrypoint option, but it will only take the name of the file to be executed within the image. If additional arguments are to be used, these must be called after the image name. For example:
docker run --entrypoint="java" $PWD:/usr/working broadinstitute/picard -jar /usr/picard/picard.jar [COMMAND] [OPTIONS]
This blog explains a bit more on the topic.

Setting up NSCA in Docker Alpine image for passive nagios check

In the Alpine linux package site https://pkgs.alpinelinux.org/packages
NSCA packages are yet to get added. Is there an alternative to setup NSCA in Alpine Linux for passive-check?
If there is no package for it, you can always build it yourself.
FROM alpine AS builder
ARG NSCA_VERSION=2.9.2
RUN apk update && apk add build-base build-base gcc wget git
RUN wget http://prdownloads.sourceforge.net/nagios/nsca-$NSCA_VERSION.tar.gz
RUN tar xzf nsca-$NSCA_VERSION.tar.gz
RUN cd nsca-$NSCA_VERSION&& ./configure && make all
RUN ls -lah nsca-$NSCA_VERSION/src
RUN mkdir -p /dist/bin && cp nsca-$NSCA_VERSION/src/nsca /dist/bin
RUN mkdir -p /dist/etc && cp nsca-$NSCA_VERSION/sample-config/nsca.cfg /dist/etc
FROM alpine
COPY --from=builder /dist/bin/nsca /bin/
COPY --from=builder /dist/etc/nsca.cfg /etc/
Since this is using multiple stages, your resulting image will not contain development files and will still be small.

How to copy a folder from docker to host while configuring custom image

I try to create my own Docker image. After it runs, as the result, the archive folder is created in the container. And I need automatically copy that archive folder to my host.
What is important I have to configure this process before creating an image in my Docker file.
Below you can see what is already in my Docker file:
FROM python:3.6.5-slim
RUN apt-get update && apt-get install -y gcc && apt-get autoclean -y
WORKDIR /my-tests
COPY jobfile.py testbed.yaml requirements.txt rabbit.py ./
RUN pip install --upgrade pip wheel setuptools && \
pip install --no-cache-dir -r requirements.txt && \
rm -v requirements.txt
VOLUME /my-tests/archive
ENV TINI_VERSION v0.18.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini","--"]
CMD ["easypy", "jobfile.py","-testbed_file","testbed.yaml"]
While running the container, map any folder on the host to the archive folder of the container, using -v /usr/host_folder:/my-tests/archive . Any thing which is created inside the container at /my-tests/archive will now be available at /usr/host_folder on the host.
Or use the following command to copy the files using scp. You can create a script which first runs the container, then runs the docker exec command.
docker exec -it <container-name> scp /my-tests/archive <host-ip>:/host_path -r

How can I extend unregistered docker images or dockerfiles?

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.

Resources