Dockerfile_inline to add package to Alpine in docker compose

Hi

I have the following compose:

services:
  webgetter:
    container_name: webcam-image-getter
    image: alpine
    restart: always
    tty: true
    build: 
      context: .
      dockerfile_inline: |
        FROM baseimage
        RUN apk upgrade --no-cache
        RUN apk add nano

I am wanted to extend the image using dockerfile_inline.

From what I have read, the above should work, but when I shell into the running container, nano does not exist. Note that if I install nano manually via ‘apk add nano’ from the shell then nano works.

nano is just by way of a simple test, there are a few packages I will need to install.

what am I doing wrong?

I am not interested in using an external dockerfile as yet another file to look after. For my simplistic needs, inline should work fine.

Worked this out. the new image with the extra packages I needed was getting cached, but I had gotten the compose wrong. Later when I got the compose right it was not rebuilding the image, rather it was using the old, incorrect cached image. One can force a new build thus:

services:
  getter:
    container_name: webcam-image-getter
    restart: always
    tty: true
    build: 
      context: .
      no_cache: true
      pull: true
      dockerfile_inline: |
        FROM alpine:latest
        RUN apk upgrade --no-cache
        RUN apk add bash
        RUN apk add nano

So in your original solution you used the image: keyword for the webgetter service and uses FROM baseimage in the inline dockerfile? What was the baseimage actually? If it was alpine, you would have just overwritten the original alpine image every single time you tried to build the image adding new and new layers as long as it reaches the limit of the number of layers. And of course when you need an alpine latest image in another project, you would use the on with the many extra layers. Then when you pull the latest alpine again, that overrides the previously built image.

I don’t see you mentioning it, but in your second shared compose file you removed the image keyword. Of course by then you could already have the wrong alpine, or maybe not, since you could not rebuild the image if I understand it correctly, since you didn’t know how to do it with compose.

You don’t have to rename the service. That helps only because the image is named based on the service name so Docker will see the image does not exist for the new service name. docker image ls will show you the images. Obviously you will not want to rename your service every time you want to rebuild the image. You just need --build added to the compose command

docker compose up -d --build

One mroe thing you used is pull: true. Yes, that tells Docker to always pull the image, but the image building will not be triggered at all unless you use the build option when the image already exists.

Indeed, thanks - its a learning process! I am using a stack in portainer to deploy and I am still not able to force a rebuild every deployment eg using no_cache: true

Any idea how (purely in a compose file), I can force it to replace any existing image built off of baseline alpine?? Eg. I goto ‘stacks’ in portainer, edit my compose file and click ‘Update the Stack’, and it always builds a new benmorewebcam-getter image. The button one sees after clicking ‘Update the Stack’ in portainer does not seem to work to force this.

My compose now looks like:

services:
  getter:
    container_name: webcam-image-getter
    restart: always
    tty: true
    build: 
      context: .
      no_cache: true
      dockerfile_inline: |
        FROM alpine:latest
        RUN apk upgrade --no-cache
        RUN apk add bash
        RUN apk add imagemagick
        RUN apk add curl
        RUN apk add wget
        RUN apk add jpeg
        RUN (crontab -l ; echo "0,10,20,30,40,50 6-22 * * * /scripts/GetMyCamImage")| crontab -
        RUN (crontab -l ; echo "0 1 * * * /scripts/UpdateDaylightHours")| crontab -
        RUN (crontab -l ; echo "@reboot /scripts/UpdateDaylightHours")| crontab -
        CMD crond -f
    volumes:
      - /share/Docker/my-webcam/webcam-images:/webcam-images
      - /share/Docker/my-webcam/gallery:/gallery
      - /share/Docker/my-webcam/scripts:/scripts:ro

I can’t talk about Portainer as I’m not using it and never recommend it for editing and creating containers, only for browsing as Portainer broke the container network for some users by duplicating ip addresses.

If you want to learn Docker basics:

Recommended links to learn the basics and concepts: