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
The permission issue happens on your ./server directory, you should check owner and permissions there.
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