0
votes

I'm new to Docker, and I'm trying to build an image with firefox 56. I was wondering what is the best way to do this.

As far as I know, there are two ways. One is to create a Dockerfile, another is opening a shell into an existing image, modify it by hand, and commit changes (docker commit).

It seems to me that the best way is using a Dockerfile, but everytime I do an error the commands installed in the Dockerfile re-download and re-install the wget and gtk packages and this is a long process. Is there a method to cache also what I've already downloaded during the build process?

The Dockerfile I'm currently using is the following, although it isn't fully relevant (in the current version the commands seem ok).

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y wget gtk3.0

# Replace 1000 with your user / group id
RUN export uid=1000 gid=1000 && \
    mkdir -p /home/developer && \
    echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
    echo "developer:x:${uid}:" >> /etc/group && \
    echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
    chmod 0440 /etc/sudoers.d/developer && \
    chown ${uid}:${gid} -R /home/developer && \
    cd /tmp && wget http://ftp.mozilla.org/pub/firefox/releases/56.0/linux-x86_64/en-US/firefox-56.0.tar.bz2 && tar -xjf firefox-56.0.tar.bz2 && mv firefox /opt 

USER developer
ENV HOME /home/developer
CMD /opt/firefox/firefox
1

1 Answers

2
votes

For interactive desktop applications like Firefox, that will heavily depend on end-user preferences, the best practice IMHO is to not run them in Docker containers at all. There are three big reasons for this: you need to do a lot of complicated and non-default things for the container to get access to the host display and devices; you need to do a lot of complicated and non-default things for the container to get access to the user preferences; and you need to be root to launch a Docker container (which is bad) and managing file permissions correctly is tricky.

Otherwise: you should basically always use the Dockerfile and docker build system, and docker commit is pretty much always wrong. If you have a Dockerfile, you can commit it to source control, give it to your coworker, and remember how you built it six months later; if you commit an image from a container you can do none of these things, and it’ll be a big problem when you’ve moved off your project and your coworker discovers your image has a substantial security vulnerability.

Docker will, on its own, cache the results of each step: if the results of the previous step haven’t changed, and this step runs the same command, then it will reuse the result of the previous build. While it’s best practice to squash everything into a single RUN command for the final build, during development it can be very helpful to split it into multiple steps so that you can, say, cache the download step.

# Squish these steps together when it really works
RUN cd /tmp && wget https://...
RUN tar xjf /tmp/firefox-56.0.tar.bz2 -C /opt