1

Let's say that I am logged in as reynierpm in my Fedora and I will build a Docker image from a Dockerfile. That image will contain a LAMP environment. I have a Apache Virtual Host(VH) default file that looks as follow:

<VirtualHost *:80>
    #ServerName www.example.com

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www

    <Directory /var/www>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog /dev/stdout
    CustomLog /dev/stdout combined
</VirtualHost>

As part of the built process this file is copied to the proper location on the image.

Can I get the logged in username from the host and set dynamically into this VH? At the end I would like to get the following result:

<VirtualHost *:80>
    ServerName reynierpm.dev

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www

    <Directory /var/www>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog /dev/stdout
    CustomLog /dev/stdout combined
</VirtualHost>

I know that I can get the value for the current user using $(whoami) from bash but how I can insert/set it to the VH file on Docker build?

This is the content of the Dockerfile:

FROM ubuntu:14.04.5
MAINTAINER Me <myemail@gmail.com>
ARG USER_NAME=unknown
VOLUME ["/var/www"]

RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive \
    apt-get install -y software-properties-common && \
    apt-get update && \
    apt-get install -y \
      apache2 \
      php5 \
      php5-cli \
      libapache2-mod-php5 \
      php5-gd \
      php5-json \
      php5-mcrypt \
      php5-mysql \
      php5-xdebug \
      php5-curl \
      php5-memcached \
      php5-mongo \
      zend-framework \
      mc \
      nano

# Copy default virtual host file.
COPY /config/apache2_vhost/apache_default /etc/apache2/sites-available/000-default.conf
COPY run /usr/local/bin/run
RUN chmod +x /usr/local/bin/run
RUN a2enmod rewrite

EXPOSE 80
EXPOSE 9001

CMD ["/usr/local/bin/run"]

UPDATE: build fails while try to use the args

Following @Elton suggestion I added this line to the run file:

sed -i "s/#ServerName www.example.com/$USER_NAME.dev/g" /etc/apache2/sites-available/000-default.conf

And then try to build the image as:

docker build --build-arg USER_NAME=$(whoami) -t dev-php55 .

But is failing with the following message:

One or more build-args [USER_NAME] were not consumed, failing build.

What's wrong?

ReynierPM
  • 17,594
  • 53
  • 193
  • 363

1 Answers1

3

If you want that value to be fixed in the image, the best option is to use a build argument, and do some text substitution in your Dockerfile:

FROM ubuntu                                                                                                                                          
ARG USER_NAME=unknown                                                                                                                                
RUN echo Built by: $USER_NAME > /builder.txt

Then pass your whoami when you build:

docker build --build-arg USER_NAME=$(whoami) -t temp .

The build argument overrides the default in the Dockerfile so your image has the real builder's username:

docker run temp cat /builder.txt                                                                                                                   
Built by: ubuntu 

EDIT: build arguments are only available as environment variables during the build process. Neither the variable or the value are present in the final built image. So you can only make use of the argument value in build instructions like RUN.

Elton Stoneman
  • 17,906
  • 5
  • 47
  • 44
  • Can you take a look to my edit? Maybe I am missing something – ReynierPM Sep 22 '16 at 14:18
  • That error means the name of the argument in `--build-arg` doesn't match the name in `ARG`. – Elton Stoneman Sep 22 '16 at 14:20
  • Ok, but this is not what I want to achieve. Do you understand the main issue I am having? Take a look to the OP maybe is better now – ReynierPM Sep 22 '16 at 14:22
  • If you want to dynamically put information about the host into the image, then I don't think that's possible. Each instruction in the Dockerfile runs in a temporary, intermediate container - and the containers don't know about the host. If you want host details to get into the temporary containers in the build, you'll need to pass them through with build args. – Elton Stoneman Sep 22 '16 at 14:29
  • So I can't pass the arg `USER_NAME` into the `run` file? That's what you said? If this is not possible and I am still need this, any workaround? – ReynierPM Sep 22 '16 at 14:35
  • Not in the `run` file, no. Build args are only available at build time not in the built image. You can use `ENV` instead, or you can move your `sed` into a `RUN` instruction in the Dockerfile. – Elton Stoneman Sep 22 '16 at 14:47
  • Can you improve your answer by reflecting this latest comment with an example of each one? I am new to Docker so I am still learning – ReynierPM Sep 22 '16 at 14:48
  • I am interested in know how to achieve this using `ENV` add a `RUN` in the Dockerfile for the `seed` command would be easy – ReynierPM Sep 22 '16 at 14:55
  • There's a comparison of `ARG` and `ENV` in the answer to [this question](http://stackoverflow.com/questions/39597925/how-do-i-set-environment-variables-during-the-build-in-docker/39598751#39598751) – Elton Stoneman Sep 22 '16 at 14:58