skip to Main Content

I have a PHP application that is containerized. I am trying to set up a pipeline in Azure, but I am struggling to run commands inside the built container (which is essential to fully install & scaffold the application so that I can run code analysis and tests).

I have make commands set up, so the way to install the application is simply

make up
make install

These are effectively running:

docker-compose up --build -d
docker-compose exec -T {containerName} composer install
docker-compose exec -T {containerName} php artisan migrate:fresh
docker-compose exec -T {containerName} php artisan passport:install
docker-compose exec -T {containerName} php artisan db:seed
...

to build the image, install dependencies (laravel), scaffold the app backend.

My test azure-pipelines.yml is set up as follows:

# Docker
# Build a Docker image
# https://learn.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- develop

resources:
- repo: self

variables:
  tag: '$(Build.BuildId)'

stages:
- stage: Build
  displayName: Build image
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: ubuntu-latest
    steps:
      - task: Docker@2
        displayName: Build an image
        inputs:
          command: build
          dockerfile: '$(Build.SourcesDirectory)/infrastructure/php/Dockerfile'
          tags: |
            $(tag)
  - job: Install
    displayName: Install app
    dependsOn: Build
    steps:
    - script: |
        docker-compose exec -T api composer install
  - job: Database
    displayName: Scaffold Database
    dependsOn: Install
    steps:
    - script: |
        make db_reset
  - job: Analyse
    displayName: Analyse backend
    dependsOn: Database
    steps:
    - script: |
        make analyse
  - job: Test
    displayName: Run tests
    dependsOn: Analyse
    steps:
    - script: |
        php artisan test

but this fails on the Install job, the error log is as follows:

Starting: CmdLine
==============================================================================
Task         : Command line
Description  : Run a command line script using Bash on Linux and macOS and cmd.exe on Windows
Version      : 2.201.1
Author       : Microsoft Corporation
Help         : https://learn.microsoft.com/azure/devops/pipelines/tasks/utility/command-line
==============================================================================
Generating script.
Script contents:
docker-compose exec -T api composer install
========================== Starting Command Output ===========================
/usr/bin/bash --noprofile --norc /home/vsts/work/_temp/a440fb6a-e03b-4da2-b958-1fa3aefa2084.sh
##[error]Bash exited with code '1'.
Finishing: CmdLine
Verifying lock file contents can be installed on current platform.
Package operations: 163 installs, 0 updates, 0 removals

In Filesystem.php line 268:
                                                                  
  /var/www/app/vendor does not exist and could not be created. 

when trying to install composer dependencies after building the image. The setup is pretty standard.

Dockerfile

FROM php:8.1-apache

RUN apt update
RUN apt-get install -y --no-install-recommends 
    g++ 
    libicu-dev 
    libpq-dev 
    libzip-dev 
    libfreetype6-dev 
    libjpeg62-turbo-dev 
    libpng-dev 
    git 
    lsb-release 
    gnupg 
    zip

RUN docker-php-ext-install 
    intl 
    opcache 
    pdo 
    pdo_mysql 
    zip 
    exif 
    gd
RUN pecl install 
    pcov 
    xdebug


WORKDIR /var/www/app

RUN usermod -a -G www-data www-data
RUN chown root:root /var/www

RUN chown -R www-data:www-data /var/www/app
RUN chmod -R 755 /var/www/app
RUN mkdir /var/www/app/vendor
RUN chmod -R 775 /var/www/app/vendor
RUN chown -R www-data:www-data /var/www/app/vendor
RUN a2enmod rewrite

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

USER www-data

docker-compose

version: '3.8'

services:
  database:
    image: mysql:8.0
    container_name: database
    environment:
      - MYSQL_DATABASE=app
      - MYSQL_ROOT_PASSWORD=root
    volumes:
      - ./infrastructure/mysql-data:/var/lib/mysql
    ports:
      - '3306:3306'

  api:
    container_name: api
    build:
      context: ./infrastructure/php
    ports:
      - '8080:80'
    volumes:
      - ./server:/var/www/app
      - ./infrastructure/apache/default.conf:/etc/apache2/sites-enabled/000-default.conf
    depends_on:
      - database

  mailhog:
    image: mailhog/mailhog:latest
    container_name: mailhog
    ports:
      - '1025:1025'
      - '8025:8025'

Makefile

DOCKER_COMPOSE = docker-compose
COMPOSER ?= composer
PHP_CMD = php

PHP_SERVICE = api

up:
    @echo "n==> Docker container building and starting ..."
    $(DOCKER_COMPOSE) up --build -d

db_reset:
    $(DOCKER_COMPOSE) exec -T api php artisan migrate:fresh
    $(DOCKER_COMPOSE) exec -T api php artisan passport:install
    $(DOCKER_COMPOSE) exec -T api php artisan db:seed

analyse:
    $(DOCKER_COMPOSE) exec -T -u root api php artisan ide-helper:models -W
    $(DOCKER_COMPOSE) exec -T -u root api ./vendor/bin/php-cs-fixer fix app
    $(DOCKER_COMPOSE) exec -T -u root api ./vendor/bin/phpstan analyse --memory-limit=2G -c phpstan.neon

I am assuming the issue is with permissions when trying to run composer install through the container, but then, how do I actually use the container? There’s no permission issues locally. The building obviously succeeds, here’s the last snippet of the build job:

 ---> Running in b83b9f8e8010
All settings correct for using Composer
Downloading...
Composer (version 2.3.5) successfully installed to: /usr/local/bin/composer
Use it: php /usr/local/bin/composer

Removing intermediate container b83b9f8e8010
 ---> bc104ff13e89
Step 11/22 : USER www-data
 ---> Running in 200f01ed5b5f
Removing intermediate container 200f01ed5b5f
 ---> 2431fb9a77ae
Step 12/22 : LABEL com.azure.dev.image.build.buildnumber=20220509.10
 ---> Running in 8183d45902d5
Removing intermediate container 8183d45902d5
 ---> d1a9ed6d2dc6
Step 13/22 : LABEL com.azure.dev.image.build.builduri=vstfs:///Build/Build/14
 ---> Running in 316a03a492e7
Removing intermediate container 316a03a492e7
 ---> 8bd620fc9792
Step 14/22 : LABEL com.azure.dev.image.build.definitionname=REDACTED
 ---> Running in 75f66a32856a
Removing intermediate container 75f66a32856a
 ---> 4daf41f08c6c
Step 15/22 : LABEL com.azure.dev.image.build.repository.name=REDACTED
 ---> Running in 707ba3523e83
Removing intermediate container 707ba3523e83
 ---> 7084ad9947a7
Step 16/22 : LABEL com.azure.dev.image.build.repository.uri=REDACTED
 ---> Running in b08c87ff8818
Removing intermediate container b08c87ff8818
 ---> 83a6531aef80
Step 17/22 : LABEL com.azure.dev.image.build.sourcebranchname=develop
 ---> Running in 0d69670ee481
Removing intermediate container 0d69670ee481
 ---> 6389f09560dc
Step 18/22 : LABEL com.azure.dev.image.build.sourceversion=dab0a85595268c16a05c5292adc1e0340c13818f
 ---> Running in 3b58e7fe5640
Removing intermediate container 3b58e7fe5640
 ---> e495c2eeab89
Step 19/22 : LABEL com.azure.dev.image.system.teamfoundationcollectionuri=REDACTED
 ---> Running in 2e04a85c91b9
Removing intermediate container 2e04a85c91b9
 ---> 4570213d4e47
Step 20/22 : LABEL com.azure.dev.image.system.teamproject=REDACTED
 ---> Running in f4c914d2522c
Removing intermediate container f4c914d2522c
 ---> 0ee813e09dbf
Step 21/22 : LABEL image.base.digest=sha256:2891049f5a33bd4ac61ea28b4d4f9144468e50369b7bc29ff61e2dd3089f5bb6
 ---> Running in 564f498fb0c4
Removing intermediate container 564f498fb0c4
 ---> 039be559c0d4
Step 22/22 : LABEL image.base.ref.name=php:8.1-apache
 ---> Running in 60c373b879be
Removing intermediate container 60c373b879be
 ---> c10cb44c17d6
Successfully built c10cb44c17d6
Finishing: Build an image

… or, am I doing this completely wrong? Any help would be greatly appreciated.

2

Answers


  1. The permission issue happens on your ./server directory, you should check owner and permissions there.

    Login or Signup to reply.
  2. It looks like you want to assign permissions on the mounted volume.

    Over here you can find quite nice explanation how to deal with it.

    Set appropriate permissions on the host machine or pass appropriate user and group to the container.

    Docker-compose set user and group on mounted volume

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search