I have the following dockerfile:
FROM php:7.2-apache
LABEL name "medico-app"
COPY composer.json composer.lock ./
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN apt-get update && apt-get install -y --no-install-recommends git zip && composer install
COPY . /var/www/html
EXPOSE 80
When this image is built, it has a size of ~500 Mbs. I'm trying to compress this image to < 100 Mb so that I can use it on Zeit Now. According to what I'm reading in the docker documentation, multi-stage builds sometimes help in making images smaller. My current idea is to split the dockerfile into two stages, one where I would install the dependencies with compose and the other where I'd just have php and apache. I can't seem to get it right though. Any suggestions?
This is what I have so far:
# first stage
FROM composer:latest
COPY composer.json composer.lock ./
RUN composer install
For the second stage, I tried this
FROM httpd:2.4-alpine
LABEL name "medico-app"
COPY --from=0 /app/vendor ./vendor
COPY . /usr/local/apache2/htdocs/
EXPOSE 80
However when I run the container now, the php files aren't served, I just see them as text. Im probably missing something here with PHP/Apache.
EDIT:
I also tried this for the second stage but I can't get it to work:
FROM php:7.2-alpine
LABEL name "medico-app"
RUN apk --no-cache update && apk --no-cache add apache2 openrc
COPY --from=0 /app/vendor ./vendor
COPY . /var/www/
EXPOSE 80
Now when I open my localhost I don't see the PHP files that I should see. I just see the default it works page.
General tips for making docker images smaller:
Use a minimal base image such as the alpine versions. In this case you can use something like php:7.2-alpine and install apache using apk.
When using apt-get follow the best practices. In particular add && rm -rf /var/lib/apt/lists/*
Try minifiying the code being added to the image using something like gulp minify.
Related
Updated
I updated the dockerfile for anyone who wants a good dockerfile for their laravel application.
I'm trying to build a Docker image from my laravel application. My application plus all the dependencies are about 380 MB but the image turns to be 840 MB. I used multistage build as Ivan suggested (Which halved the size of the image, it was 1.2 GB at first). But I still wondering why is my Docker image this big? And how can I reduce the size of the image?
Here is my Dockerfile:
# Instruction adapted from https://laravel-news.com/multi-stage-docker-builds-for-laravel
# PHP Dependencies
FROM composer:latest as vendor
COPY database/ database/
COPY composer.json composer.json
COPY composer.lock composer.lock
RUN composer install \
--no-dev \
--ignore-platform-reqs \
--no-interaction \
--no-plugins \
--no-scripts \
--prefer-dist
# Frontend
FROM node:16.13.1 as frontend
RUN mkdir -p /app/public
COPY package.json webpack.mix.js tailwind.config.js /app/
COPY resources/ /app/resources/
COPY public/ /app/public/
COPY package-lock.json /app/package-lock.json
WORKDIR /app
RUN npm ci && npm run production
# Application
FROM php:7.4-apache
COPY . /var/www/html
COPY --from=vendor /app/vendor/ /var/www/html/vendor/
COPY --from=frontend /app/public/ /var/www/html/public/
Your image is big because it contains all application which you was install via apt-get and their dependencies.
There are multiple ways to solve problem:
use multistage build
use suitable base image
use Alpine linux
Multistage build
Use one base image for get/build/test your app and copy needed result to next stage.
FROM ubuntu:18.04 AS build
*do smth*
FROM php:7.4.27-fpm-alpine AS final
COPY from build...
Suitable base image
Use image that already contains environment which you need to run application. Where no need to install all these garbage.
Use Alpine linux
Use the images which based on Alpine or similar distro, who optimized for docker/clouds, and build your app based on them.
I'm using docker
and This my Dockerfile contains:
FROM nginx:latest
RUN apt-get update && apt-get install -y \
php \
php-fpm \
nano
so as you see, we use nginx's latest version image and then run some of these bash command which you can see.
base on these configuration I'm trying to execute a php file to show phpinfo()
so I create a file in /usr/share/nginx/html called index.php
and when I try to use index.php like this http://localhost:8000/index.php, the php file start downloading immediately.
What should I do?
I know that this is a possible duplicate but I've tried something like this link:
Nginx - Downloading PHP instead of executing
but nothing well happened.
I've been trying to install HHVM (Hack) on Alpine linux to no success.
Has anyone compiled HHVM on linux?
Any help would be welcome.
Up to now, there's no HHVM on Alpine yet.
There's an open request in the bug tracker, though:
http://bugs.alpinelinux.org/issues/4503
maybe you did this request :)
You can monitor the website to see if there are update, or check possibile pull requests from here:
https://github.com/alpinelinux/aports/pulls
Hope it helps.
Francesco
If you look at this page Building HHVM from source, it requires "GCC 5 or GCC 7". The first step would have to be `apk add --update build-base' or have a look here: How to get regular stuff working. buid-base contains "GCC, libc-dev and binutils packages" etc.
FROM alpine:3.7
RUN apk add --no-cache build-base git cmake patch curl-dev findutils libxml2-dev icu-dev bash libevent libevent-dev curl
RUN git clone git://github.com/facebook/hhvm.git
RUN cd hhvm
WORKDIR hhvm
RUN git submodule update --init --recursive
ENV GYP_DEFINES "linux_use_bundled_binutils=0 linux_use_bundled_gold=0 clang=0"
RUN cmake -DMYSQL_UNIX_SOCK_ADDR=/var/run/mysqld/mysqld.sock .
RUN make -j [number_of_processor_cores] # eg. make -j 4
RUN make install
Got stuck here:
-- Can't find minimal tcmalloc
ERROR: Unable to find Intel TBB install directory.
CMake Error at CMake/HPHPFindLibs.cmake:266 (if):
if given arguments:
"LESS" "5005"
Unknown arguments specified
Call Stack (most recent call first):
CMakeLists.txt:106 (include)
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
LIBGLOG_INCLUDE_DIR (ADVANCED)
used as include directory in directory /hhvm
used as include directory in directory /hhvm
Would get you going at least halfway.
Think the issue is around :https://pkgs.alpinelinux.org/package/edge/testing/x86/libtbb
I want to completely remove symfony and composer from my mac. I have been googling for five hours and no documentation can be found on how to uninstall composer and symfony completely from my mac. Why is that so hard to find? even on the Symfony website.
Symfony on your computer is just a folder containing the framework and the structure of the files, so you can delete that folder and you are done. Composer is just an binary file (phar) that can run on the command line. Locate where that file is and delete it.
Symfony could be anywhere on your mac.
The 'installer' for mac that comes from here https://symfony.com/download (dd 2019/10) dumps symfony in your home directory in ~/.symfony . I dislike that, too.
ls -al ~/.symfony
if it's there,
rm -rf ~/.symfony
That 'installer' suggests you may want to move it here
ls -al /usr/local/bin/symfony
if it's there
rm -rf /usr/local/bin/symfony
I agree with the above answer to
rm -rf ~/.symfony
but you do not need to run ls to check beforehand, if it's there, it is going to be deleted. If not, it is being ignored.
Better do
whereis symfony
to check where your binary is and delete it.
Last but not least check if you have installed it via apt, this is a valid solution:
cd /etc/apt/sources.list.d && ls | grep symfony-cli
sudo rm symfony-cli.list && sudo apt update
This will avoid checking for updates on every apt update
I'm beginner with Docker, and I'm trying to build my own image: Ubuntu + Nginx + PHP.
So, I have a directory called test. Inside directory two other directories, app and sites-enabled. Also, there's a Dockerfile, with content:
FROM ubuntu:trusty
RUN apt-get update && \
apt-get install -y nginx php5-fpm php5-mysql php-apc php5-imagick php5-imap php5-mcrypt php5-gd libssh2-php && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
ADD sites-enabled/ /etc/nginx/sites-enabled/
ADD app/ /app/
EXPOSE 80
CMD ["php5-fpm", "-c", "/etc/php5/fpm"]
CMD ["/usr/sbin/nginx"]
I build this image successfully. Then I create container with docker run -d image_name. I get the ID, and then I run docker inspect -f "{{.NetworkSettings.IPAddress}}" ID in order to get the IP address of the container.
I need this IP address, because I also run HAProxy in another container, so I can configure it to point to the right localtion.
So, both HAProxy and container with PHP app are running OK. HAProxy is pointing at the right application. PHP application files are uploaded at the right location inside the container.
But, Nginx doesn't execute PHP. Instead, when I try to access the application, I just get a downloaded file with my index.php PHP code.
What could be the problem? Please help.
My first guess was that I'm doing something wrong in Dockerfile when I run php5-fpm. I've tried few different ways, but non of them seem to work.
One CMD only.
If you need "services", look into supervisord or runit.