I'm looking for reviews about my first dockfile. I don't want to develop bad habits.

The purpose is to quickly deploy my Laravel (5.4) application. I'm going to connect it with others database containers (mognodb and mysql).

I used Ubuntu as parent image because it's my development environment but I planned to change it to debian or alpine later.

# Use an official Ubuntu LTS as a parent image
FROM ubuntu:16.04

MAINTAINER name <email>

#================================= Dependencies ================================

# Install dependencies
RUN apt-get -qq update && \
    apt-get -qq install -y --no-install-recommends \
        apache2 \
        composer \
        curl \
        git \
        libapache2-mod-php7.0 \
        libssl-dev \
        libsslcommon2-dev \
        npm \
        php-curl \
        php-dev \
        php-mbstring \
        php-mysql \
        php-pear \
        php-xml \
        php-zip \
        php7.0 \
        phpunit \
        pkg-config \
        zip && \
    # Get repository for node 8 and install it
    curl -sL https://deb.nodesource.com/setup_8.x | bash && \
    apt-get -qq install -y nodejs && \
    # Remove useless package : curl
    apt-get autoremove --purge -y curl && \
    # Clean temporary apt data
    rm -rf /var/lib/apt/lists/*

# Install php dependencies
RUN pecl -q install mongodb

#================================= Php Settings ================================

# Enable Mongo driver
RUN echo "extension=mongodb.so" >> /etc/php/7.0/cli/php.ini && \
    echo "extension=mongodb.so" >> /etc/php/7.0/apache2/php.ini

#=============================== Apache Settings ===============================

# Set Apache environment variables
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2

# Create Apache directories

# Enable 'mod_rewrite' for rewrite URL then remove 'index.php'
RUN a2enmod rewrite

# Copy Apache configuration file
COPY apache2.conf /etc/apache2/apache2.conf
COPY 000-default.conf /etc/apache2/sites-available/000-default.conf

#================================= App Download ================================

# Create App directory
RUN mkdir /var/www/app
WORKDIR /var/www/app

# Copy sources without version control
RUN git clone --branch=v2.0.1 \
    https://my_name:my_key@bitbucket.org/app/repository.git . \
    && find . -name ".git*" -type f -delete

# Add write access to storage and cache
RUN chmod -R a+w storage/ bootstrap/cache/

#========================== Download / Install Vendors =========================

# Download PHP vendors
# Clean cache
RUN composer -q install && \
    composer clear-cache

# Download CSS/JS vendors
# Compile required assets
# Clean cache and download
RUN npm -q install && \
    npm run production && \
    rm -rf node_modules && \
    npm cache clean --force

#================================= App Settings ================================

# Set .env file with relevent settings
RUN sed -i 's/APP_ENV=\S*/APP_ENV=production/' .env && \
    sed -i 's/APP_DEBUG=\S*/APP_DEBUG=false/' .env &&

#=================================== Cleanup ===================================

# Clean temporary Laravel data
RUN php artisan cache:clear && \
    php artisan view:clear && \
    php artisan config:cache

# Remove useless folders
RUN rm -rf /var/www/html

#================================ Run Container ================================

# Make port 80 available to the world outside this container

# Run Apache in the background
ENTRYPOINT [ "/usr/sbin/apache2" ]

After building the image size is 550 MB.
And after run the container the application work like expected.

What is right, and wrong with this dockerfile? How could I optimise it?


2 Answers 2


I don't much about Docker, so I can't comment much on that. I've read through the file and the steps seem to make sense. I can comment on some details.

The comment here doesn't match what the code does, because the find command will only delete files like .gitignore and .gitattributes, but the .git directory itself with the full history remains:

# Copy sources without version control
RUN git clone --branch=v2.0.1 \
    https://my_name:my_key@bitbucket.org/app/repository.git . \
    && find . -name ".git*" -type f -delete

If you don't need the version control history, perhaps you can use a zip file release instead of cloning. Or, you might want to change the find command to delete the .git directory too, by dropping the -type f condition.

The sed commands here duplicate the variable names, seem overcomplicated to use \S* instead of simply .*, can be more strict to not perform the replacement in comment lines, and can be combined into a single command:

RUN sed -i 's/APP_ENV=\S*/APP_ENV=production/' .env && \
    sed -i 's/APP_DEBUG=\S*/APP_DEBUG=false/' .env &&

Like this:

RUN sed -ie '/^APP_ENV=/s/=.*/=production/' -e '/^APP_DEBUG=/s/=.*/=false/' .env
  • \$\begingroup\$ It seems like the good use of sed command is : sed -i .env -e '/^APP_ENV=/s/=.*/=production12/' -e '/^APP_DEBUG=/s/=.*/=false/'. But I don't get why \S* is not good, what is the difference with your approach? \$\endgroup\$
    – Opsse
    Aug 2, 2017 at 1:09
  • \$\begingroup\$ @Opsse \S* is fine, it just seems unnecessary. sed -i .env would be a bit confusing, because the -i flag has an optional parameter as backup file extension. sed -i .env -e '...' makes it look like the .env might be an option of -i, but it's not. With sed -ie '...' .env there won't be such misunderstanding. \$\endgroup\$
    – janos
    Aug 2, 2017 at 5:01
  • \$\begingroup\$ I understand but sed -ie '...' .env do not works \$\endgroup\$
    – Opsse
    Aug 2, 2017 at 12:15
  • \$\begingroup\$ @Opsse what do you mean by "it does not work"? Do you get an error? \$\endgroup\$
    – janos
    Aug 2, 2017 at 12:23
  • \$\begingroup\$ With sed -ie '...' -e '...' .env I got sed: can't read /^APP_ENV=/s/=.*/=production/: No such file or directory. It takes the first '...' as a file with multiple -e. \$\endgroup\$
    – Opsse
    Aug 4, 2017 at 16:00

I would have started with FROM 7.0-apache. I would have also install npm AFTER adding the nodejs module.

I assume this is a PHP app and nodejs is just used for javascript dependency management.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.