I create a DocherFile with OpenJDK base image and run init.sh script.
I want to inherit that Dockerfile and override the init.sh to test.sh script.
Is it possible to "test" docker file inherit from or extends "my-app" docker file and override ENTRYPOINT?
Should I define both "my-app" and "test" dockers in docker-compose?
Can I run only test docker with docker-compose and not both?
My purpose is to run only "my-app" docker in production. But for tests, I want to extend it and run tests and some more configurations.
my-app/Dockerfile:
FROM openjdk:11-jre-slim
COPY initialization.sh /path/
ENTRYPOINT ["/bin/bash", "-c", "/path/init.sh"]
test/Dockerfile:
FROM my-app
COPY tset.sh /path/
ENTRYPOINT ["/bin/bash", "-c", "/path/tset.sh"]
Here is one idea,
You can have different docker-compose files.
docker-compose.yml: Contains the definition of all images needed for running your app.
my-api:
image: yourImage
build:
context: .
dockerfile: Dockerfile
depends_on:
- sqldata
docker-compose.override.yml: Contains the base config for all images of the previous file.
my-api:
environment:
- ENVIRONMENT=Development
- DEBUG
ports:
- "6105:80"
Using these two files together from CLI
docker-compose -f docker-compose.yml -f docker-compose.override.yml
This should start your app will all containers and the default environment by default.
PRODUCTION
docker-compose.prod.yml : This is a replacement of the docker.override but contains configurations, environment variables suitable for a production environment.
docker-compose -f docker-compose.yml -f docker-compose.prod.yml
TESTING
Override the default entrypoint of the image
docker-compose-test.override.yml :
app-test:
environment:
- ENVIRONMENT=Development
ports:
- "6103:80"
entrypoint:
- YourScript
- memory=1
Related
I'm trying to containerize two services an socket service and a django application
My file structure is
\main file {docker-compose file}
\ django application {Dockerfile}
\ socket app {Dockerfile}
When I run docker build . it build the image
then when I run docker-compose build,
I notice that the socket app and django app are copied to the container instead of only the django application as specified by the Dockerfile.
I get the idea that the Dockerfile is executed in the main directory instead of the django directory?
Here is Dockerfile that is inside the django app application
# Pull base image
FROM python:3
# Set environment varibles
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /code
# Install dependencies
COPY requirements.txt /code/
RUN pip install -r requirements.txt
# Copy project
COPY . /code/
RUN ls
And here is the docker-compose file.
With the usage of the ls command I tried to figure out what happend and the output is that the applications in the main folder are copied instead of the django application.
version: '3'
services:
db:
image: postgres:10.1-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
web:
build: ./django_app
command: ls /code/
volumes:
- .:/code
ports:
- 8000:8000
depends_on:
- db
volumes:
postgres_data:
is this intended use or am I doing something wrong?
The volumes: directive in your docker-compose.yml file is hiding literally everything your Dockerfile does. You'll solve your immediate problem by changing the two directories to match: in the volumes: directive, bind-mount ./django_app:/code.
In a more production-oriented workflow, I'd recommend making your Docker image totally self-contained: make sure it has a CMD that runs your application, and do not use volumes: to inject your code. Delete command: and volumes: from the docker-compose.yml and let the image provide its own code and default command. (To do development, use a Python virtual environment for local code isolation, and make sure all of your tests and a basic hand-run workflow pass before using Docker for anything.)
docker-compose.yaml:
web:
build: .
command: ./main
ports:
- "8888:3412"
volumes:
- .:/code
links:
- redis
redis:
image: redis
Dockerfile:
FROM golang:1.6
ADD main.go .
EXPOSE 3412
ENTRYPOINT /go
RUN go build main.go
so after running docker run -d imagename, there is no running container
also docker logs containername doesn't show anything
ENTRYPOINT /go
is equivalent to running /bin/sh -c /go
go is actually a directory in your container, so it will fail, because shell cannot execute a directory.
remove the background flag -d and use docker run imagename and you will see this error
What you probably want is:
ENTRYPOINT /usr/local/go/bin/go to use go as an executable from the container.
Or even better:
ENTRYPOINT ["/usr/local/go/bin/go"], so you would be able to pass arguments to go.
I have a docker setup that does not have the Dockerfile or docker-compose at the root because there are many services.
build
client.Dockerfile
deployments
docker-compose.yml
web
core
scripts
run.sh
docker-compose
version: "3.1"
services:
client:
build:
context: ..
dockerfile: ./build/client.Dockerfile
volumes:
- ./web/core:/app
ports:
- 3000:3000
- 35729:35729
And then the dockerfile:
FROM node:10.11
ADD web/core/yarn.lock /yarn.lock
ADD web/core/package.json /package.json
ENV NODE_PATH=/node_modules
ENV PATH=$PATH:/node_modules/.bin
RUN yarn
WORKDIR /app
ADD web/core /app
EXPOSE 3000
EXPOSE 35729
RUN cat /app/scripts/run.sh
ENTRYPOINT ["/bin/bash", "/app/scripts/run.sh"]
CMD ["start"]
Now the RUN command displays the result of the file so it is there. However, when running docker-compose up the client_1 | /bin/bash: /app/scripts/run.sh: No such file or directory
I'm guessing it has something to do with the docker-compose context because when the dockerfile was at the root, it seemed to work fine.
I'm getting the feeling that docker is designed essentially to work only at the root.
Context:
I want a live reloading create-react-app server like this: https://www.peterbe.com/plog/how-to-create-react-app-with-docker.
I would like to setup my project this way: https://github.com/golang-standards/project-layout
Your volume is wrongly mounting. This should fix the issue. I created the similar folder structure. From the root folder of build ran docker-compose -f ./deployments/docker-compose.yml up. It works normally only thing i change volume path.
volumes:
- ../web/core:/app
Here is what I want to do:
docker-compose build
docker-compose $COMPOSE_ARGS run --rm task1
docker-compose $COMPOSE_ARGS run --rm task2
docker-compose $COMPOSE_ARGS run --rm combine-both-task2
docker-compose $COMPOSE_ARGS run --rm selenium-test
And a docker-compose.yml that looks like this:
task1:
build: ./task1
volumes_from:
- task1_output
command: ./task1.sh
task1_output:
image: alpine:3.3
volumes:
- /root/app/dist
command: /bin/sh
# essentially I want to copy task1 output into task2 because they each use different images and use different tech stacks...
task2:
build: ../task2
volumes_from:
- task2_output
- task1_output:ro
command: /bin/bash -cx "mkdir -p task1 && cp -R /root/app/dist/* ."
So now all the required files are in task2 container... how would I start up a web server and expose a port with the content in task2?
I am stuck here... how do I access the stuff from task2_output in my combine-tasks/Dockerfile:
combine-both-task2:
build: ../combine-tasks
volumes_from:
- task2_output
In recent versions of docker, named volumes replace data containers as the easy way to share data between containers.
docker volume create --name myshare
docker run -v myshare:/shared task1
docker run -v myshare:/shared -p 8080:8080 task2
...
Those commands will set up one local volume, and the -v myshare:/shared argument will make that share available as the folder /shared inside each of each container.
To express that in a compose file:
version: '2'
services:
task1:
build: ./task1
volumes:
- 'myshare:/shared'
task2:
build: ./task2
ports:
- '8080:8080'
volumes:
- 'myshare:/shared'
volumes:
myshare:
driver: local
To test this out, I made a small project:
- docker-compose.yml (above)
- task1/Dockerfile
- task1/app.py
- task2/Dockerfile
I used node's http-server as task2/Dockerfile:
FROM node
RUN npm install -g http-server
WORKDIR /shared
CMD http-server
and task1/Dockerfile used python:alpine, to show two different stacks writing and reading.
FROM python:alpine
WORKDIR /app
COPY . .
CMD python app.py
here's task1/app.py
import time
count = 0
while True:
fname = '/shared/{}.txt'.format(count)
with open(fname, 'w') as f:
f.write('content {}'.format(count))
count = count + 1
time.sleep(10)
Take those four files, and run them via docker compose up in the directory with docker-compose.yml - then visit $DOCKER_HOST:8080 to see a steadily updated list of files.
Also, I'm using docker version 1.12.0 and compose version 1.8.0 but this should work for a few versions back.
And be sure to check out the docker docs for details I've probably missed here:
https://docs.docker.com/engine/tutorials/dockervolumes/
For me the best way to copy file from or to container is using docker cp for example:
If you want copy schema.xml from apacheNutch container to solr container then:
docker cp apacheNutch:/root/nutch/conf/schema.xml /tmp/schema.xml
server/solr/configsets/nutch/
docker cp /tmp/schema.xml
solr:/opt/solr-8.1.1/server/solr/configsets/nutch/conf
I have part of a docker-compose file as so
docker-compose.yml
pitchjob-fpm01:
container_name: pitchjob-fpm01
env_file:
- env/base.env
build:
context: ./pitch
dockerfile: PitchjobDockerfile
volumes:
- "/Sites/pitch/pitchjob/:/Sites"
restart: always
depends_on:
- memcached01
- memcached02
links:
- memcached01
- memcached02
extends:
file: "shared/common.yml"
service: pitch-common-env
my extended yml file is
compose.yml
version: '2.0'
services:
pitch-common-env:
environment:
APP_VOL_DIR: Sites
WEB_ROOT_FOLDER: web
CONFIG_FOLDER: app/config
APP_NAME: sony_pitch
in the docker file for pitchjob-fpm01 i have a command like so
PitchjobDockerfile
# Set folder groups
RUN chown -Rf www-data:www-data /$APP_VOL_DIR
But when I run the command to bring up the stack
docker-compose -f docker-compose-base.yml up --build --force-recreate --remove-orphans
I get the following error
failed to build: The command '/bin/sh -c chown -Rf www-data:www-data
/$APP_VOL_DIR' returned a non-zero code: 1
I'm guessing this is because it doesn't have the $APP_VOL_DIR, but why is that so if the docker compose is extending another compose file that defines
environment: variables
You can use build-time arguments for that.
In Dockerfile define:
ARG APP_VOL_DIR=app_vol_dir
# Set folder groups
RUN chown -Rf www-data:www-data /$APP_VOL_DIR
Then in docker-compose.yml set app_vol_dir as build argument:
pitchjob-fpm01:
container_name: pitchjob-fpm01
env_file:
- env/base.env
build:
context: ./pitch
dockerfile: PitchjobDockerfile
args:
- app_vol_dir=Sites
I think your problem is not with the overrides, but with the way you are trying to do environment variable substitution. From the docs:
Note: Unlike the shell form, the exec form does not invoke a command
shell. This means that normal shell processing does not happen. For
example, RUN [ "echo", "$HOME" ]will not do variable substitution
on $HOME. If you want shell processing then either use theshell form
or execute a shell directly, for example:RUN [ "sh", "-c", "echo
$HOME" ].