Vamshi
Vamshi

Reputation: 349

Need help in executing powershell commands in dockerized laravel

I want to access vsphere config info from powercli script to laravel. But I do not know how to make them work together in docker. Whatever I do, the error is similar to this - The command "'pwsh' '-v'" failed. Exit Code: 127(Command not found) Working directory: /var/www/public Output: ================ Error Output: ================ sh: 1: exec: pwsh: not found As a last resort, I am here.

docker-compose.yml:

version: '3'
services:
  #PHP Service
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: vapp
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network
  #Nginx Service
  webserver:
    image: nginx:alpine
    container_name: webserver
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/var/www
      - ./nginx/conf.d/:/etc/nginx/conf.d/
    networks:
      - app-network

  #MySQL Service
  db:
    image: mysql:5.7.22
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: vapp
      MYSQL_ROOT_PASSWORD: vapp
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
      TZ: Asia/Kolkata
    volumes:
      - dbdata:/var/lib/mysql/
      - ./mysql/my.cnf:/etc/mysql/my.cnf
      - ./mysql:/var/lib/mysql-files/
    networks:
      - app-network
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpMyAdmin
    restart: always
    ports:
      - "8080:80"
    environment:
      MYSQL_ROOT_PASSWORD: vapp
      PMA_HOST: db
    external_links:
      - mariadb:mariadb
    volumes:
      - "./phpmyadmin/sessions:/sessions"
    networks:
      - app-network
#Docker Networks
networks:
  app-network:
    driver: bridge

#Volumes
volumes:
  dbdata:
    driver: local

Dockerfile

FROM mcr.microsoft.com/powershell:latest
WORKDIR ./

FROM php:7.4-fpm

# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/

# Set working directory
WORKDIR /var/www

# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    libonig-dev \
    locales \
    libzip-dev \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl
RUN snap install powershell --classic
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl mysqli
RUN docker-php-ext-configure gd --enable-gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd
RUN docker-php-ext-enable mysqli

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

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

# Copy existing application directory contents
COPY . /var/www

# Copy existing application directory permissions
COPY --chown=www:www . /var/www

# Change current user to www
USER www

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

Controller:

//$process = new Process(['ls', '-lsa']); #This works but next one do not
$process = new Process(['pwsh', '-v']);
$process->run();
// executes after the command finishes
if (!$process->isSuccessful()) {
       throw new ProcessFailedException($process);
}
echo $process->getOutput();

I know how the Process() method works. Above code fails.
I need help on making powershell and laravel work together in docker.
Is there anything wrong with docker configuration or the controller code in accessing powershell.

Upvotes: 0

Views: 1162

Answers (2)

Vamshi
Vamshi

Reputation: 349

Thanks to @konstantin-bogomolov

The reason was the incorrect docker file. Powershell was not properly installed in container.

For those who stop by, Working dockerfile is below.

FROM php:7.4-fpm

# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/

# Set working directory
WORKDIR /var/www

# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    libonig-dev \
    locales \
    libzip-dev \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl \
    wget \
    apt-utils

# Download the Microsoft repository GPG keys
RUN wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb

# Register the Microsoft repository GPG keys
RUN dpkg -i packages-microsoft-prod.deb

# Update the list of products
RUN apt-get update

# Install PowerShell
RUN apt-get install -y powershell

# Start PowerShell
RUN pwsh

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl mysqli
RUN docker-php-ext-configure gd --enable-gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd
RUN docker-php-ext-enable mysqli

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

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

# Copy existing application directory contents
COPY . /var/www

# Copy existing application directory permissions
COPY --chown=www:www . /var/www

# Change current user to www
USER www

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

Upvotes: 0

Konstantin Bogomolov
Konstantin Bogomolov

Reputation: 1366

You are using multistage build in Dockerfile. It can copy artifacts, but you don't copy anything. So pwsh app doesn't copy to PHP image (to the second stage).

You could remove first stage (FROM mcr.microsoft.com/powershell:latest) and install properly Powershell inside PHP image. For example:

RUN apt-get update && apt-get install -y \
wget

RUN wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb && \
dpkg -i packages-microsoft-prod.deb

RUN apt-get update && apt-get install -y \
powershell

PHP image use Debian 10, so here is the instruction: https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7.1#debian-10

Check pwsh inside container first:

docker exec -it app bash
pwsh

Upvotes: 1

Related Questions