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_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
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
RUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIR
# 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:[email protected]/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
EXPOSE 80
# Run Apache in the background
ENTRYPOINT [ "/usr/sbin/apache2" ]
CMD ["-D","FOREGROUND"]
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:[email protected]/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– Opsse2017年08月02日 01:09:06 +00:00Commented Aug 2, 2017 at 1:09 -
\$\begingroup\$ @Opsse
\S*is fine, it just seems unnecessary.sed -i .envwould be a bit confusing, because the-iflag has an optional parameter as backup file extension.sed -i .env -e '...'makes it look like the.envmight be an option of-i, but it's not. Withsed -ie '...' .envthere won't be such misunderstanding. \$\endgroup\$janos– janos2017年08月02日 05:01:44 +00:00Commented Aug 2, 2017 at 5:01 -
\$\begingroup\$ I understand but
sed -ie '...' .envdo not works \$\endgroup\$Opsse– Opsse2017年08月02日 12:15:59 +00:00Commented Aug 2, 2017 at 12:15 -
\$\begingroup\$ @Opsse what do you mean by "it does not work"? Do you get an error? \$\endgroup\$janos– janos2017年08月02日 12:23:36 +00:00Commented Aug 2, 2017 at 12:23
-
\$\begingroup\$ With
sed -ie '...' -e '...' .envI gotsed: can't read /^APP_ENV=/s/=.*/=production/: No such file or directory. It takes the first '...' as a file with multiple-e. \$\endgroup\$Opsse– Opsse2017年08月04日 16:00:55 +00:00Commented 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.