Using variables in config file - docker

I have this dockerfile that is working correctly.
https://github.com/shantanuo/docker/blob/master/packetbeat-docker/Dockerfile
The only problem is that when my host changes, I need to modify packetbeat.yml file
hosts: ["https://944fe807b7525eaf163f502e08a412c5.us-east-1.aws.found.io:9243"]
password: "rzmYYJUdHVaglRejr8XqjIX7"
Is there any way to simplify this change? Can I use environment variable to replace these 2 values?

Set environment variables in your docker container first.
You can either set them by accessing your container
docker exec -it CONTAINER_NAME /bin/bash
HOST="https://944fe807b7525eaf163f502e08a412c5.us-east-1.aws.found.io:9243"
PASS="rzmYYJUdHVaglRejr8XqjIX7"
Or in your Dockerfile
ENV HOST https://944fe807b7525eaf163f502e08a412c5.us-east-1.aws.found.io:9243
ENV PASS rzmYYJUdHVaglRejr8XqjIX7
And the in the packetbeat.yml
hosts: ['${HOST}']
password: '${PASS}'

Related

How can I identify the system my Docker container is runninng on? Can I pass Docker daemon labels inside a Docker container?

In my Docker compose environment I want to pass the labels of the Docker daemon inside a Docker container.
I need to identify the system my Docker container is running on from inside the container. I do not want to use any parameters on my container (-e, file-mount, etc) , as this could be misconfigured easily.
(I don't want to mount /var/run/docker.sock for security reasons.)
You can pass the information of your host to you container by setting environment variables. Here are some examples from the doc:
Using the .env file:
You can set default values for any environment variables referenced in the Compose file, or used to configure Compose, in an environment file named .env.
services:
web:
env_file:
- web-variables.env
Passing environment variables to containers:
You can pass environment variables from your shell straight through to a service’s containers with the ‘environment’ key by not giving them a value, just like with docker run -e VARIABLE ...:
services:
web:
environment:
-DEBUG
Set environment variables in containers:
You can set environment variables in a service’s containers with the ‘environment’ key, just like with docker run -e VARIABLE=VALUE ...
services:
web:
environment:
-DEBUG=1

Set elasticsearch initial password via docker-compose

Can i know, how to set initial password for elasticsearch database using docker-compose
bin/elasticsearch-setup-passwords auto -u "http://192.168.2.120:9200
See this:
The initial password can be set at start up time via the ELASTIC_PASSWORD environment variable:
docker run -e ELASTIC_PASSWORD=MagicWord docker.elastic.co/elasticsearch/elasticsearch-platinum:6.1.4
Also, for newest image (docker.elastic.co/elasticsearch/elasticsearch:7.14.0), the ELASTIC_PASSWORD_FILE environment added mentioned in Configuring Elasticsearch with Docker:
For example, to set the Elasticsearch bootstrap password from a file, you can bind mount the file and set the ELASTIC_PASSWORD_FILE environment variable to the mount location. If you mount the password file to /run/secrets/bootstrapPassword.txt, specify:
-e ELASTIC_PASSWORD_FILE=/run/secrets/bootstrapPassword.txt
So add these environment in docker-compose.yaml I guess could work for you.

How to access system environment variables in Next.js?

I created a Next.JS app which uses environment variables. I have the environment variables needed as the system's environment variables (because it is a dockerized nextjs app).
# in terminal
echo $NEXT_PUBLIC_KEY_NAME
# >> value of key
but process.env.NEXT_PUBLIC_KEY_NAME is undefined in the app only when running in production mode. How can I access them? I can't seem to find any documentation on this on Nextjs's website or anywhere else.
NextJS Solution
NextJS has built in support to accomplish what you want,
you just need to put your environment variables inside .env.local in your root folder.
Other than .env.local, you can also use .env, .env.development, and .env.production.
an example of .env.local:
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword
in your case, it will become:
NEXT_PUBLIC_KEY_NAME=[insert_what_you_want]
voila, you can access it from your NextJS app, using process.env. keyword.
// pages/index.js
export async function getStaticProps() {
const db = await myDB.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS,
})
// ...
}
You can read more from the source.
Docker Solution
If the above solution is not the one you are looking for, then what you need is how to set env variable on Docker instead of NextJS.
If you are using docker-compose file:
frontend:
image: frontend
build:
context: .
dockerfile: Dockerfile
environment:
- NEXT_PUBLIC_KEY_NAME=[insert_what_you_want]
if you run the docker manual, use -e parameters:
docker run -e NEXT_PUBLIC_KEY_NAME=[insert_what_you_want] frontend bash
or using env file on docker command:
docker run --env-file ./env.list frontend bash
you can read more from the source.

Use credentials inside docker container

I'm building a docker image from a project where I have a file with default credentials for the database. At the docker container run time, I want to pass the real credentials and replace the variables defined on that file. What is the best way to do it? I tried to use environment variables, but it's not working.
db_config.yml:
host: ${HOST}
user: ${USER}
pass: ${PASS}
port: ${PORT}
db: ${DB_NAME}
docker-compose.yml:
version: '2.3'
services:
test_ctr:
container_name: test
image: container:latest
network_mode: "host"
environment:
- HOST=${HOST}
- USER=${USER}
- PASS=${PASS}
- PORT=${PORT}
- DB_NAME=${DB_NAME}
db_config.yml is in builded image and language is Python. Basically when I run container, db_config.yml is red by a script and use file's credentials. When I create the image, this db_config.yml have default credentials. but when I run the container, I want to replace this file
To debug this try running:
docker exec -it <name-of-the-container> <command>
In your case this translates to:
docker exec -it test sh
This should open a shell inside the container.
Then type:
printenv
This will print all Environment variables and their values (that way You will see if the values You have passed are present)
There will be a problem if the container is crashing at startup (in this case it's not possible to use docker exec).
TIP:
Use .env file located in the same directory as docker-compose.yml (or whatever your docker-compose file is) to pass variables.
.env:
KEY1=value1
KEY2=value2
In your case this might look something like:
HOST=1.2.3.4
USER=sa
PASSWORD=42
PORT=4242
DB_NAME=mydb
When your running:
docker-compose up
docker-compose will look for this .env file and will inject the values from this file
Good luck

Cannot use ENV variable from Docker container to perform HEALTHCHECKS in docker-compose file

I have a docker-compose file with a database service that gets an environment file for users and passwords (I removed the env variable for the password as the problem is the same for both user and password):
db:
restart: always
container_name: db
image: mariadb:10.3.9
env_file:
- my_env_file.env
volumes:
- /opt/dbdata:/var/lib/mysql
healthcheck:
test: ["CMD", "mysql", "-u", "${DB_USER}", "-e", "\"SHOW DATABASES;\""]
interval: 1m
timeout: 10s
retries: 10
The environment file has a DB_USER entry:
DB_USER=TEST
When building and starting the container with docker-compose, the environment variable cannot be resolved by Docker since the variable only exists in the db container, and I'm getting the following warning:
WARNING: The DB_USER variable is not set. Defaulting to a blank string.
Is there a way to tell Docker to avoid resolving the value of this env variable on the host, but instead resolve it from my container?
I do not want to provide the env variable on the host for security reasons.
I also do not want to use mysqladmin as it can result in false positives (e.g., healthcheck may fail because database is not yet accepting connections).
docker-compose will expand environment variables in the docker-compose environment (where you ran the docker-compose command), not in the container environment. The environment variables you are passing are only set inside the container (the compose file is already parsed and variables in the compose file have been expanded by the time that environment variable file is loaded).
Inside the container, a shell is needed to expand environment variables (the $ is a shell syntax, the Linux kernel doesn't do this expansion), but you'll need to escape those variables so that docker-compose does not try to expand them first, and you need a shell. The json list syntax to running commands in docker containers runs with a direct OS exec syscall, bypassing the shell, so you need to either explicitly add a shell to the exec syntax, or just use the shell syntax. Doing the latter, with the $ values escaped as $$ results in:
test: ["CMD-SHELL", "mysql -u $${DB_USER} -e \"SHOW DATABASES;\""]
For more details see:
healthcheck syntax: https://docs.docker.com/compose/compose-file/#healthcheck
variable substitution: https://docs.docker.com/compose/compose-file/#variable-substitution
env_file option can only be used to set environment variables inside the container.
To substitute variables in compose file, there are two options -
Shell environment variables - Compose can use the variable values from the shell environment in which docker-compose is run.
.env file - Compose supports declaring default environment variables in an environment file named .env placed in the folder where the docker-compose command is executed. Environment variables in shell will override the values in .env file.
If none of the above options work for you, you can try the following approaches -
Run a shell script inside which you refer the container environment variables as the healthcheck.
Escape the variables with double dollar sign.
test: ["CMD-SHELL", "mysql -u $${DB_USER} -e \"SHOW DATABASES;\""]

Resources