Dynamically Changing docker compose service image? - docker

We have a docker-compose file with service like
services:
utils-microservice:
container_name: utils-microservice
image: <Masked>.dkr.ecr.ap-south-1.amazonaws.com/utils-microservice:<Some Tag>
ports:
- '1024:1024'
env_file:
- './envs/utils-microservice.env'
Now, what we want to do?
Once CI Pushes a new TAG to ECR, We can run a shell script to achieve the following
1 Stop the container
2 Replace the utils-microservice:<Some Tag> to utils-microservice:<Some New Tag>
3 Restart the service with new tag!
Is it achievable? we are not looking to complicate using docker swarm or k8's!

It’s possible to use environment variables in your shell to populate values inside a Compose file:
web:
image: "webapp:${TAG}"
https://docs.docker.com/compose/environment-variables/

Related

Portainer stacks and command line arguments

I have a portainer stack running one container. Lets use microbin as an example.
The docker-compose yaml looks like this:
---
version: "3"
services:
paste:
image: danielszabo99/microbin:latest
container_name: microbin
restart: always
ports:
- "8525:8080"
volumes:
- /mnt/docker_volumes/microbin-data:/app/pasta_data
This particular container is hosted on docker hub, and the maintainer provides examples of command line arguments that can be appended to the dockerfile to activate various features easily. One example would be:
--no-listing
Disables the /pastalist endpoint, essentially making all pastas private.
So this brings me to my issue. I don't want to maintain my own custom dockerfile, and in the past I have always inserted environment variables into the docker-compose yaml to call features like this.
An example would be like this - I have a stack running for Authentik (a sso/saml/idp gateway with a pretty web interface). You can see the "environment:" section and the variables I am calling.
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.5.3}
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_ERROR_REPORTING__ENABLED: "true"
# WORKERS: 2
volumes:
- ./media:/media
- ./custom-templates:/templates
- geoip:/geoip
env_file:
- stack.env
So - not knowing how the development side of making these containers and hosting them on docker-hub goes... is there a way for me to use these command line arguments for microbin as environment variables in my docker-compose yaml / stack configuration file, or am I going to have to wait on the maintainer to implement this as a feature?
Thanks for your help in advance.
You can pass command line arguments in your docker-compose.yml file using the command attribute. That assumes of course the process started within the Docker image can deal with those, but that seems to be the case for your image and should generally be the case.
version: "3"
services:
paste:
image: danielszabo99/microbin:latest
container_name: microbin
restart: always
ports:
- "8525:8080"
volumes:
- /mnt/docker_volumes/microbin-data:/app/pasta_data
command: my command line --args here
See Docker Compose Reference - command for details.

Docker compose image upgrade

I have a docker-compose image running:
version: '2'
services:
db:
image: postgres:commit1
service:
image: service:commit1
ports:
- "3000:3000"
depends_on:
- db
The image has a tag of commit id of git. If anything changes in code, CI/CD pipeline runs and updates the image with latest commit id.
Now let's say I have images as:
postgres:commit2 and service:commit2.
What is the best procedure to update the images given the containers are running using commit1 in the compose file?
Do I need to update the images manually in compose and then:
docker-compose restart
And remove the other containers manually?
Is it the best way?
One way is to templatize your compose file and have a separate CI/CD step to generate a new file with the new image tags on every build.
For ex. -
// docker-compose.yml.template
version: '2'
services:
db:
image: postgres:{{ COMMIT_ID }}
service:
image: service:{{ COMMIT_ID }}
ports:
- "3000:3000"
depends_on:
- db
and a using sed or awk script you can replace {{ COMMIT_ID }} with the latest commit id and generate the new file.
// docker-compose.yml
version: '2'
services:
db:
image: postgres:commit2
service:
image: service:commit2
ports:
- "3000:3000"
depends_on:
- db
Then you can finally pull and use latest images using docker-compose pull && docker-compose up -d
I am assuming you are looking for some option to do rolling update with docker-compose and your service support multiple instances. This can be achieved by, first changing the image id in docker-compose file, you can use your CI/CD tool to create new docker-compose file with updated commit hash.
Then you can use below command add new containers(with new new image) behind the services.
docker-compose up --scale db=1 --scale service=1 --no-recreate
Then next step would be to delete the old containers
docker rm old-container # service
Then the last step would be to scale the services to the number of instances you want.
This is the best I can think of for just docker-compose. If you were using docker swarm or any other system it would have been out of box feature :)

File in docker volume not updating

Hi I have a Nifi docker container stopped and I want to update a property file.
Whenever I update a field, when I run docker-compose start it doesn't update the property file.
How can this be possible?
here is my docker compose:
version: "3.3"
services:
nifi:
image: apache/nifi
volumes:
- /home/ubuntu/nifi/conf:/opt/nifi/nifi-current/conf
ports:
- "8080:8080"
Thanks
We had this issue a while back as well. I believe using volumes essentially creates a symlink, and when the container starts up it overwrites anything in that folder.
Have you considered creating a multistage build? That was our solution:
Dockerfile:
FROM apache/nifi:1.9.2
ADD /path/to/your-props.properties /opt/nifi/nifi-current/conf
We then put the resulting image in our compose

How to get Docker Swarm to apply changes to Compose file?

So, I'm running into an issue. Say you have a simple Docker Compose file like this:
version: "3.7"
services:
web:
image: repo.hostname.com/web:latest
environment:
port: 8080
ports:
- 8080:8080
Then, I'd run the following command to apply it:
docker stack deploy --compose-file path/to/compose.yml
Now, here's my problem. Once I've created the services via stack deploy, how do I UPDATE an existing service via the compose file?
If I just change the environment variable of "port" from "8080" to "8000" and rerun stack deploy with the new compose file, it doesn't pick up the change.
And, no, I can't use Kubernetes for reasons that are way out of the scope of this post.

Building and uploading images to Docker Hub, how to from Docker Compose?

I have been working in a docker environment for PHP development and finally I get it working as I need. This environment relies on docker-compose and the config looks like:
version: '2'
services:
php-apache:
env_file:
- dev_variables.env
image: reynierpm/php55-dev
build:
context: .
args:
- PUID=1000
- PGID=1000
ports:
- "80:80"
extra_hosts:
- "dockerhost:xxx.xxx.xxx.xxx"
volumes:
- ~/var/www:/var/www
There are some configurations like extra_hosts and env-file that is giving me some headache. Why? Because I don't know if the image will works under such circumstances.
Let's said:
I have run docker-compose up -d and the image reynierpm/php55-dev with tag latest has been built
I have everything working as it should be because I am setting the proper values on the docker-compose.yml file
I have logged in into my account and I push the image to the repository: docker push reynierpm/php55-dev
What happen if tomorrow you clone the repository and try to run docker-compose up but changing the docker-compose.yml file to fit your settings? How the image behaves in this case? I mean makes sense to create/upload the image to Docker Hub if any time I run the command docker-compose up it will be build again due to the changes on the config file?
Maybe I am completing wrong and some magic happen behind scenes but I need to know if I am doing this right
If people clone your git repository and do a docker-compose up -d it will in fact building a new image. If you only want people use your image from docker hub, drop the build section of docker-compose.yml and publish it in your docker hub page. Check this you can see the proposed docker-compose.yml.
Just paste this in your page:
version: '2'
services:
php-apache:
image: reynierpm/php55-dev
ports:
- "80:80"
environment:
DOCKERHOST: 'yourhostip'
PHP_ERROR_REPORTING: 'E_ALL & ~E_DEPRECATED & ~E_NOTICE'
volumes:
- ~/var/www:/var/www
If your env_file just have a couple of variables it is better to show them directly in the Dockerfile. It is better to replace extra_hosts with an environment variable and change in your php.ini or where ever you use the extra host by the variable:
.....
xdebug.remote_host = ${DOCKERHOST}
.....
You can in your Dockerfile define a default value for this variable:
ENV DOCKERHOST=localhost
Hope it helps
Regards

Resources