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
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.
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.
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
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"]
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}