Pass ENV variables specified in shell from docker-compose to Dockerfile - docker-compose

I would like to set the DEPLOY_ENV environment variable when I build my Docker image, but the value doesn't seem to be making it to the Dockerfile. Here's my build command:
docker-compose.yml
version: '3'
services:
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
environment:
- DEPLOY_ENV=${DEPLOY_ENV:-development}
ports:
- "3000:3000"
volumes:
- ".:/app"
When I run DEPLOY_ENV=staging docker-compose config, I can see that it replaces the DEPLOY_ENV variable as expected:
services:
web:
build:
context: /home/user/app
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b
'0.0.0.0'"
environment:
DEPLOY_ENV: staging
ports:
- published: 3000
target: 3000
volumes:
- /home/user/app:/app:rw
version: '3'
However, I can't figure out how to populate the value in my Dockerfile. Here's a Dockerfile I'm using to test:
FROM ruby:2.7.2
SHELL ["/bin/bash", "-c"]
ENV RAILS_ENV=${DEPLOY_ENV}
ENV NODE_ENV=${DEPLOY_ENV}
ENV APP_HOME=/app
LABEL app=app
LABEL environment=${RAILS_ENV}
RUN echo ${DEPLOY_ENV}
When I run docker-compose build, it doesn't dipslay the value of DEPLOY_ENV:
Building web
[+] Building 1.4s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 1.55kB 0.0s
=> [internal] load .dockerignore 0.1s
=> => transferring context: 35B 0.0s
=> [internal] load metadata for docker.io/library/ruby:2.7.2 1.0s
=> [1/2] FROM docker.io/library/ruby:2.7.2#sha256:1dd0106849233fcd913b7c4608078fa1a5sd5e3ce1af2a55e4d726b0d8868e2f 0.0s
=> CACHED [2/2] RUN echo ${DEPLOY_ENV} 0.0s
=> exporting to image 0.1s
=> => exporting layers 0.0s
=> => writing image sha256:27e159270471d3078fff8eb4eads7e4e586b345bfa13d3bdb3ec317266678549 0.0s
=> => naming to docker.io/library/app_web
I plan to set secret values when building my image and want to avoid hardcoding the values or use build args since they can be exposed.
What am I missing?

You could utilize the args primitive in docker compose, which passes build variables in your Dockerfile
args:
DEPLOY_ENV_ARG: ${DEPLOY_ENV:-development}
environment:
- DEPLOY_ENV=${DEPLOY_ENV:-development}
And in your Dockerfile
ARG DEPLOY_ENV_ARG
ENV RAILS_ENV=${DEPLOY_ENV_ARG}

Related

Docker compose fails on Raspberry Pi

Running $ docker compose up -d on the following docker-compose.yml
version: '3'
services:
web:
platform: linux/arm/v6
build: ./web
restart: always
environment:
DATABASE_URL: ${DATABASE_URL}
SECRET_KEY: ${SECRET_KEY}
TZ: Europe/Amsterdam
ports:
- ${PORT}:5000
depends_on:
- db
volumes:
- web-data:/data
db:
platform: linux/arm/v6
image: arm32v6/postgres:15.1-alpine
restart: always
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- ${POSTGRES_PORT}:5432
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:
web-data:
should create two docker containers. However, it produces
[+] Building 6.5s (3/3) FINISHED
=> [internal] load build definition from Dockerfile 0.5s
=> => transferring dockerfile: 32B 0.2s
=> [internal] load .dockerignore 0.2s
=> => transferring context: 2B 0.1s
=> ERROR resolve image config for docker.io/docker/dockerfile:1 2.4s
------
> resolve image config for docker.io/docker/dockerfile:1:
------
failed to solve: rpc error: code = Unknown desc = failed to solve with frontend
dockerfile.v0: failed to solve with frontend gateway.v0: no match for platform in manifest
sha256:9ba7531bd80fb0a858632727cf7a112fbfd19b17e94c4e84ced81e24ef1a0dbc: not found
I verified that both services (web and db) in my docker-compose file can be build using docker build, which excludes any platform issues from the services.
What does no match for platform in manifest mean? More importantly, how can I fix the error?
A temporary solution is to replace docker-compose.yml with explicit docker commands.
# Create the network and volumes
docker network create randpion-app
docker volume create postgres-data
docker volume create web-data
# Build the web service
docker build -t randpion/web web
# Load the environment variables from the .env file
export $(cat .env | xargs)
# Start the database service
docker run -d \
--network randpion-app --network-alias db --name randpion-db \
--platform "linux/arm/v6" \
-v postgres-data:/var/lib/postgresql/data \
-e POSTGRES_USER=${POSTGRES_USER} \
-e POSTGRES_PASSWORD=${POSTGRES_PASSWORD} \
-e POSTGRES_DB=${POSTGRES_DB} \
-p ${POSTGRES_PORT}:5432 \
arm32v6/postgres:15.1-alpine
# Start the web service
docker run -d \
--network randpion-app --network-alias web --name randpion-web \
--platform "linux/arm/v6" \
-v web-data:/data \
-e DATABASE_URL=${DATABASE_URL} \
-e SECRET_KEY=${SECRET_KEY} \
-e TZ=Europe/Amsterdam \
-p ${PORT}:5000 \
randpion/web
This runs fine for now, but the solution is not ideal. For example, the containers must restart after every reboot.

what is volume 'type' error in docker-compos

im new in docker and docker-compos.
this is my Docker and its created successfully.
FROM python:3.8-buster
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE 1
COPY . .
ARG name
RUN apt-get update
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
docker-compose.yml :
version: "3.7"
services:
django_web:
build: .
command: >
apt -c "python3 manage.py makemigrations && python3 manage.py migrate && gunicorn mlAmeri.wsgi:application --bind 0.0.0.0:8000"
volumes:
- static: /app/staitc
- media: /app/media
- .: /app
ports:
- 8010:8000
nginx:
build: ./nginx
volumes:
- static:/app/static
- media:/app/media
- ./nginx/config/:/etc/nginx/conf.d/
ports:
- 8000:80
depends_on:
- django_web
volumes:
# postgres_data:
static:
media:
and this my error
services.django_web.volumes 'type' is a required property
what's meaning of type ? what i miss?
You are just missing some quotes I believe:
volumes:
- "static:/app/staitc"
- "media:/app/media"
- ".:/app"
See the official documentation: https://docs.docker.com/compose/compose-file/compose-file-v3/#volumes
Edit: note that it's not a good practice to mount the entire current folder into the container though. You will be leaking unnecessary stuff in the container.

Dockerfile can't find my file exit code 1 Dockerfile can't find a file in the same dir

This is my first time with docker, I'm working on this problem for two days, it would make me very happy to find a solution.
I'm running docker-compose.yml file with "docker-compose up":
version: '3.3'
services:
base:
networks:
- brain_storm-network
volumes:
- brain_storm-storage:/usr/src/brain_storm
build: "./brain_storm"
data_base:
image: mongo
volumes:
- brain_storm-storage:/usr/src/brain_storm
networks:
- brain_storm-network
ports:
- '27017:27017'
api:
build: "./brain_storm/api"
volumes:
- brain_storm-storage:/usr/src/brain_storm
networks:
- brain_storm-network
ports:
- 5000:5000
depends_on:
- data_base
- base
restart: on-failure
the base Dockerfile inside ./brain_storm does the following:
FROM brain_storm-base:latest
RUN mkdir -p /usr/src/brain_storm/brain_storm
ADD . /usr/src/brain_storm/brain_storm
and when running the Dockerfile inside brain_storm/api
FROM brain_storm-base:latest
CMD cd /usr/src/brain_storm \
&& python -m brain_storm.api run-server -h 0.0.0.0 -p 5000 -d mongodb://0.0.0.0:27017
I'm getting this error :
brain_storm_api_1 exited with code 1
api_1 | /usr/local/bin/python: Error while finding module specification for 'brain_storm.api' (ModuleNotFoundError: No module named 'brain_storm')
pwd says I'm in '/' and not in the current directory when running the base Dockerfile,
so that might be the problem but how do I solve it without going to /home/user/brain_storm in the Dockerfile, because I want to keep the location of brain_storm folder general.
How can I make Dockerfile see and take the file from the current directory (where the Dockerfile file is) ?
You should probably define WORKDIR command in both your Dockerfiles. The WORKDIR command is used to define the working directory of a Docker container at any given time. Any RUN, CMD, ADD,COPY, or ENTRYPOINT command will be executed in the specified working directory.:
base:
FROM brain_storm-base:latest
WORKDIR /usr/src/brain_storm
COPY . .
api:
FROM brain_storm-base:latest
WORKDIR /usr/src/brain_storm
CMD python -m brain_storm.api run-server -h 0.0.0.0 -p 5000 -d mongodb://0.0.0.0:27017

KeystoneJS docker-compose can't connect mongo db

I am trying to deploy keystoneJS app on the server. Before that I want to test it locally.
I started mongoDB locally. Then use the Dockerfile from the documentation https://www.keystonejs.com/guides/deployment here, I can't run it. I get the error below:
✖ Connecting to database
Error: Server selection timed out after 30000 ms
at /home/node/node_modules/#keystonejs/utils/dist/utils.cjs.prod.js:54:26
at async executeDefaultServer (/home/node/node_modules/#keystonejs/keystone/bin/utils.js:109:3) {
errors: {
MongooseAdapter: MongoTimeoutError: Server selection timed out after 30000 ms
at Timeout._onTimeout (/home/node/node_modules/mongodb/lib/core/sdam/server_selection.js:308:9)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7) {
name: 'MongoTimeoutError',
reason: [MongoNetworkError],
[Symbol(mongoErrorContextSymbol)]: {}
}
}
}
error Command failed with exit code 1.
I googled seems didn't know about local mongodb://localhost:27017.
Then I decided to use docker-compose:
Here is the docker-compose.yml
version: '3'
services:
app:
container_name: my-admin
restart: always
build: .
volumes:
- .:/mycode
environment:
- MONGO_URI=mongodb://mongo:27017
ports:
- "80:3030"
links:
- mongo
mongo:
image: mongo:latest
restart: always
ports:
- "27017:27017"
when I run docker-compose up, got the same error.
Also tried this:
const keystone = new Keystone({
name: PROJECT_NAME,
adapter: new Adapter({mongoUri: "mongodb://mongo:27017/myapp"}),
onConnect: initialiseData,
});
Any help? Thanks!
EDIT
Here is the Dockerfile
# https://docs.docker.com/samples/library/node/
ARG NODE_VERSION=12.10.0
# https://github.com/Yelp/dumb-init/releases
ARG DUMB_INIT_VERSION=1.2.2
# Build container
FROM node:${NODE_VERSION}-alpine AS build
ARG DUMB_INIT_VERSION
WORKDIR /home/node
RUN apk add --no-cache build-base python2 yarn && \
wget -O dumb-init -q https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_amd64 && \
chmod +x dumb-init
ADD . /home/node
RUN yarn install && yarn build && yarn cache clean
# Runtime container
FROM node:${NODE_VERSION}-alpine
WORKDIR /home/node
COPY --from=build /home/node /home/node
EXPOSE 3000
CMD ["./dumb-init", "yarn", "start"]

Changing Environment in docker-compose up

I'm new to docker.
Here is my simple docker-compose file.
version: '3.4'
services:
web:
image: 'myimage:latest'
build: .
ports:
- "5265:5265"
environment:
- NODE_ENV=production
To run this, I usually use docker-compose up command.
Can I change the NODE_ENV variable to anything while running docker-compose up?
For example:
docker-compose up -x NODE_ENV=staging
Use docker-compose run, you can manage services but not the complete stack. Useful for one-off commands.
$ docker-compose run -d -e NODE_ENV=staging web
Ref - https://docs.docker.com/compose/reference/run/
OR
Best way i could see as if now is to use shell & export the environment variable before doing a docker-compose up as below -
$ export NODE_ENV=staging && docker-compose up -d
Where your docker-compose will look something as below -
version: '3.4'
services:
web:
image: 'myimage:latest'
build: .
ports:
- "5265:5265"
environment:
- NODE_ENV=${NODE_ENV}