I want to dockerize my vuejs app and to pass it environment variables from the docker-compose file.
I suspect the app gets the environment variables only at the build stage, so it does not get the environment variables from the docker-compose.
vue app:
process.env.FIRST_ENV_VAR
Dockerfile:
FROM alpine:3.7
RUN apk add --update nginx nodejs
RUN mkdir -p /tmp/nginx/vue-single-page-app
RUN mkdir -p /var/log/nginx
RUN mkdir -p /var/www/html
COPY nginx_config/nginx.conf /etc/nginx/nginx.conf
COPY nginx_config/default.conf /etc/nginx/conf.d/default.conf
WORKDIR /tmp/nginx/vue-single-page-app
COPY . .
RUN npm install
RUN npm run build
RUN cp -r dist/* /var/www/html
RUN chown nginx:nginx /var/www/html
CMD ["nginx", "-g", "daemon off;"]
docker-compose:
version: '3.6'
services:
app:
image: myRegistry/myProject:tag
restart: always
environment:
- FIRST_ENV_VAR="first environment variable"
- SECOND_ENV_VAR="first environment variable"
ports:
- 8080:8080
Is there any way to pass environment variables to a web application after the build stage?
In vue js apps you need to pass the env variables as VUE_APP_
so in your case it should be VUE_APP_FIRST_ENV_VAR
Based on this https://medium.com/#rakhayyat/vuejs-on-docker-environment-specific-settings-daf2de660b9, I have made a silly npm package that help to acomplish what you want.
Go to https://github.com/juanise/jvjr-docker-env and take a look to README file.
Basically just run npm install jvjr-docker-env. A new Dockerfile, entrypoint and json file will be added to your project.
Probably you will need to modify some directory and/or file name in Dockerfile in order to work.
You can try this. The value of FIRST_ENV_VAR inside docker will be set to the value of FIRST_ENV_VAR_ON_HOST on your host system.
version: '3.6'
services:
app:
image: myRegistry/myProject:tag
restart: always
environment:
- FIRST_ENV_VAR=$FIRST_ENV_VAR_ON_HOST
- SECOND_ENV_VAR=$SECOND_ENV_VAR_ON_HOST
ports:
- 8080:8080
As you can see in the docker docs docker-compose reference envs
the defined environment values are always available in the container, not only at build stage.
You can check this by change the CMD to execute the command "env" to display all environments in your container.
If your application is not getting the actual values of the env variables it should be anything else related with your app
Related
I am new to Docker / docker compose and am using it to deploy an API to a server. I found an image that I wish to use, which includes the option to add some environment variables, in particular:
GUNICORN_CMD_ARGS
Any additional command line settings for Gunicorn can be passed in the
GUNICORN_CMD_ARGS environment variable.
Read more about it in the Gunicorn docs: Settings.
These settings will have precedence over the other environment
variables and any Gunicorn config file.
For example, if you have a custom TLS/SSL certificate that you want to
use, you could copy them to the Docker image or mount them in the
container, and set --keyfile and --certfile to the location of the
files, for example:
docker run -d -p 80:8080 -e GUNICORN_CMD_ARGS="--keyfile=/secrets/key.pem --certfile=/secrets/cert.pem" -e PORT=443 myimage
I would like to add these two options (keyfile and certfile) as arguments to the docker run command, but instead pass docker compose up to create the images and run the container.
How would I go about doing that?
My Docker file is:
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
COPY ./requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /app
And my docker-compose.yml file is:
version: "3"
services:
backend:
build: ./
restart: always
network_mode: "host"
I have tried adding a CMD line to the end of my Docker file but to no avail.
You can use the environment key in you docker-compose.yml like this:
environment:
GUNICORN_CMD_ARGS: --keyfile=/secrets/key.pem --certfile=...
PORT: 443
https://docs.docker.com/compose/compose-file/compose-file-v3/#environment
I am trying to understand the docker sample application 'example-voting-app'. I am trying to build the app with docker-compose. I am confused with the behaviour of 'command' key in docker compose file and the CMD Instruction in Dockerfile. The application consists of a service called 'vote'. The configuration for the vote service in docker-compose.yml file is:
services: # we list all our application services under this 'services' section.
vote:
build: ./vote # specifies docker to build the
command: python app.py
volumes:
- ./vote:/app
ports:
- "5000:80"
networks:
- front-tier
- back-tier
The configuration of the Dockerfile provided in ./vote directory is as below:
# Using official python runtime base image
FROM python:2.7-alpine
# Set the application directory
WORKDIR /app
# Install our requirements.txt
ADD requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
# Copy our code from the current folder to /app inside the container
ADD . /app
# Make port 80 available for links and/or publish
EXPOSE 80
# Define our command to be run when launching the container
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:80", "--log-file", "-", "--access-logfile", "-", "--workers", "4", "--keep-alive", "0"]
My doubt here is which command ( 'python app.py' or 'gunicorn app:app -b ...') will be executed when i try building the application using docker-compose up
The Docker Compose command:, or everything in a docker run invocation after the image name, overrides the Dockerfile CMD.
If the image also has an ENTRYPOINT, the command you provide here is passed as arguments to the entrypoint in the same way the Dockerfile CMD does.
For a typical Compose setup you shouldn't need to specify a command:. In a Python/Flask context, the most obvious place it's useful is if you're also using a queueing system like Celery with the same shared code base: you can use command: to run a Celery worker off of the image you build, instead of a Flask application.
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.)
I'm trying to use Docker and Docker Compose to create a containerized app. I have a PubNub account, which allows me to use different API keys for different environments (dev, test, prod). To help me build images for this, I am trying to use build args set with an env_file.
It's not working.
WARNING: The PUB_KEY variable is not set. Defaulting to a blank string.
WARNING: The SUB_KEY variable is not set. Defaulting to a blank string.
Questions:
What mistake am I making in setting the build args?
How do I fix it?
Is this a good way to set ENV variables for the containers scan and flask?
At the very bottom is an IntelliJ IDE screenshot, or the text code is just below.
Here is the docker-compose.yml content:
version: '3.6'
services:
scan:
env_file:
- sample.env
build:
context: .
dockerfile: Dockerfile
args:
pub_key: $PUB_KEY
sub_key: $SUB_KEY
target: scan
image: bt-beacon/scan:v1
flask:
env_file:
- sample.env
build:
context: .
dockerfile: Dockerfile
args:
pub_key: $PUB_KEY
sub_key: $SUB_KEY
target: flask
image: bt-beacon/flask:v1
ports:
- "5000:5000"
And the Dockerfile:
# --- BASE NODE ---
FROM python:3.6-jessie as base
ARG pub_key
ARG sub_key
RUN test -n "$pub_key"
RUN test -n "$sub_key"
# --- SCAN NODE ---
FROM base as scan
ENV PUB_KEY=$pub_key
ENV SUB_KEY=$sub_key
COPY app/requirements.scan.txt /
RUN apt-get update
RUN apt-get -y install bluetooth bluez bluez-hcidump python-bluez python-numpy python3-dev libbluetooth-dev libcap2-bin
RUN pip install -r /requirements.scan.txt
RUN setcap 'cap_net_raw,cap_net_admin+eip' $(readlink -f $(which python))
COPY app/src /app
WORKDIR /app
CMD ["./scan.py", "$pub_key", "$sub_key"]
# -- FLASK APP ---
FROM base as flask
ENV SUB_KEY=$sub_key
COPY app/requirements.flask.txt /
COPY app/src /app
RUN pip install -r /requirements.flask.txt
WORKDIR /app
EXPOSE 5000
CMD ["flask", "run"]
Finally, sample.env:
# PubNub app keys here
PUB_KEY=xyz1
SUB_KEY=xyz2
env_file can only set environment variables inside a service container. Variables from env_file cannot be injected into docker-compose.yml itself.
You have such options (described there in detail):
inject these variables into the shell, from which you run docker-compose up
create .env file containing these variables (syntax identical to your sample.env)
Personally I would separate image building process and container launching process (take away image building responsibility from docker-compose to external script, then building process can be configured easily).
I'm trying to port my already-working webpack app to a docker setup for easier development env setup. I've used a following Dockerfile for this:
FROM scardon/ruby-node-alpine
MAINTAINER mbajur#gmail.com
RUN apk add --no-cache build-base python
ENV BUNDLE_PATH /box
RUN mkdir -p /app
WORKDIR /app
COPY . ./
EXPOSE 4567
And my docker-compose.yml
version: '3'
services:
app: &app_base
build:
context: .
command: webpack --watch -d --color
volumes:
- .:/app
- box:/box
ports:
- "4567:4567"
volumes:
box:
And i'm running my webpack setup with
$ docker-compose up
However, for some reason, webpack can't see changes made to my files. Also, after some googling, i've tried using --watch-poll instead but it then exits immediately after first build instead watching as a deamon.
What can i do to make it work in docker-alpine ? I have a feeling i'm missing something simple in here.
ps. my project is mostly based on this: https://github.com/grassdog/middleman-webpack
ps2. i'm pretty sure it has nothing to do with webpack config cause it works perfectly fine when used outside of docker
ps3. i've also played with setting up fs.inotify.max_user_watches to 524288 but it didn't changed much