Building PHP-FPM Docker Image with PHP Code and push to Registry

I will show you how to build a PHP-FPM Docker Image with your projects PHP source by using Docker Compose and how to push these Container Images to a (private) Container Registry like GitLab.

In my previous blog posts we talked about how to set up a PHP and Symfony development environment with Docker Compose, how to install the latest version of Symfony with Composer in a Docker Container and how to add MongoDB with environment variables to your Docker Compose file. Your development environment is now running locally, but in the beginning I promised you to show how to use your Docker Compose Setup also for Production.

Docker Image containing your latest PHP source code

Before we can start with the production system, you have to build your Docker Container from your development environment including your custom PHP source code. Of course, we don’t want to mount the PHP source in our PHP-FPM container on a live system. We need to have a ready to go Image with our latest code.

On the internet, there are a lot of instructions on how to build Container Images for a single Dockerfile with Docker, but there is few information on how to utilize Docker Compose for building your Docker Images. But once you figured out how to do that, it is pretty easy!

Copying PHP source code into Docker Image

Let’s start by adding a live Target to our Dockerfile.

# myapp/php-fpm/Dockerfile
FROM php:8.1-fpm-alpine as base

RUN apk --update \
        --no-cache \
        add git make g++ autoconf rabbitmq-c-dev libtool tzdata \
    && pecl install mongodb \
    && docker-php-ext-enable mongodb 
ENV TZ=Europe/Berlin
RUN apk del --purge make g++ autoconf libtool \
    && rm -rf /var/cache/apk/*
RUN cd /usr/local/etc/php/conf.d/ && \
  echo 'memory_limit = -1' >> /usr/local/etc/php/conf.d/docker-php-ram-limit.ini

COPY --from=composer /usr/bin/composer /usr/bin/composer

WORKDIR /var/www

EXPOSE 9000

CMD composer install; php-fpm

### PROD IMAGE ###
FROM base as prod

WORKDIR /var/www
COPY ./src .
CMD composer install; php-fpm

These changes add a new build target which we will use in your build process. In our development system, we mount our PHP source code so that we can make changes without rebuilding the Image. For production we need our code unchangeable in the Image. That is exactly what line 25 in the changed Dockerfile does.

Using Build Targets with Docker Compose

In order to use our new live target, we need to adjust our docker-compose.yml file. But since we don’t want to affect our development system, let’s add a new docker-compose.build.yml file:

# myapp/docker-compose.build.yml
version: '3.7'

services:
  php-fpm:
    build:
      context: .
      dockerfile: ./php-fpm/Dockerfile
      target: "prod"
    restart: unless-stopped
    image: registry.gitlab.com/yourname/myapp/php-fpm:latest
    environment:
      - COMPOSER_MEMORY_LIMIT=-1

When you compare the new file with your docker-compose.dev.yml file, you see a big difference in the build key and also added the image key. Also the docker-compose.build.yml contains only the services, which we customized and need to build a custom image. We don’t want to do that for NGINX and MongoDB.

You have to customize line 11. I assume that you followed the other parts of my tutorial and use a GitLab repository for your project.

You have to do the following adoptions for the image name registry.gitlab.com/yourname/myapp/php-fpm:latest

  • Replace yourname with your GitLab username
  • Replace myapp with your projects name
  • If you like, you can rename the container from php-fpm to anything you think is better suited

So your image name in line 11 could be for example registry.gitlab.com/digitizedliving/important-product/shop-php:latest. You just have to remember for later.

Locally building the Image

So, now we are ready to locally run the build command with Docker Compose.

Open your terminal, navigate into your project folder and execute the following commands.

cd myapp/
docker-compose -f docker-compose.build.yml build

This build process should take up to some minutes, but finally you will see the message that the image is written and named like your specified in the image key before.

Now, there is one more thing to do: we want to push our fresh build Image to our GitLab Container Registry, so that we can use the Image in a live Docker Compose File without the need for building it.

Connecting with GitLab Container Registry

To be able to push our Images to the GitLab Container Registry, we have to log in from our local machine. To do so, you have to create a Personal Access Token. We will restrict our Token to just allow access to Registry, nothing else in GitLab.

To do so, just log into GitLab and navigate to User Settings > Access Tokens or open the following link: https://gitlab.com/-/profile/personal_access_tokens

Choose a Token name, e.g. Build Test and select the required Scopes. In our case, I selected read_registry and write_registry.

Create a Personal Access Token to push your Docker Images to the GitLab Container Registry

Click on Create personal access token to create the token. On the next screen you can access your token. You have to save it now, because you won’t be able to access it again. If you forgot the token, you have to delete it and create a new token. You can click on the eye button to show the token or on the little clipboard to copy token.

GitLab Personal Access Token for pushing Docker Image to GitLab Container Registry has been created.

Let’s login from your local machine to the GitLab Container Registry. Open your terminal again and enter the following commands:

cd myapp/
docker login registry.gitlab.com -u <username> -p <token>

Of course, you have to replace <username> and <token> with your GitLab Username and the before created personal access token. This tutorial uses GitLab, but you can also use any other Container Host. You just need the Username and a Token or Password.

Pushing your Images to GitLab Container Registry

You are able to push your custom Docker Images to your GitLab Container Registry. Let’s try it out:

cd myapp/
docker-compose -f docker-compose.build.yml build
docker-compose -f docker-compose.build.yml push

That’s it! Your Image is now saved to the Container Registry.

Summary and next steps

You are now able to build Images from your Docker Compose File, log in with a personal access token to the GitLab Container registry and push your Images to your Container Registry.

There is still a lot to do on the way to our Deployment Pipeline with GitLab, but that was a big step, e.g. tagging your Images. Next Sunday, 2nd April, in the next blog post, we will take the next step.

Schreiben Sie einen Kommentar