How to run bash scripts via NPM in Docker container - bash

I am unable to properly run bash scripts with NPM within a Docker container. If NPM is used to run a bash script then it runs it as a nameless user with ID 1000 that cannot use sudo to change file permissions and cannot call further NPM scripts.
Dockerfile:
FROM php:8.1-apache
RUN a2enmod rewrite
RUN docker-php-ext-install mysqli
RUN apt-get -y update && apt-get install -y zip mariadb-client git sudo
RUN adduser root sudo
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
RUN . ~/.bashrc && nvm install node
WORKDIR /var/www/html
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
docker-compose.yml
networks:
foundation:
services:
server:
build:
context: .
dockerfile: ./docker/server/Dockerfile
container_name: '${APP_NAME}-server'
ports:
- '${APP_PORT}:80'
working_dir: /var/www/html
environment:
- 'DATABASE_URL=mysql://${MYSQL_USER}:${MYSQL_PASSWORD}#db_server:3306/${MYSQL_DATABASE}?serverVersion=10.7'
volumes:
- ./code:/var/www/html
- ./docker/server/apache/sites-enabled:/etc/apache2/sites-enabled
- ./docker/server/php/php.ini:/usr/local/etc/php/conf.d/extra-php-config.ini
depends_on:
db_server:
condition: service_healthy
networks:
- foundation
db_server:
image: mariadb:10.7
container_name: '${APP_NAME}-db'
restart: always
ports:
- '${DB_PORT}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${MYSQL_PASSWORD}'
MYSQL_USER: '${MYSQL_USER}'
MYSQL_PASSWORD: '${MYSQL_PASSWORD}'
MYSQL_DATABASE: '${MYSQL_DATABASE}'
volumes:
- db_data:/var/lib/mysql
- ./docker/db/mariadb/my.cnf:/etc/mysql/conf.d/my.cnf
healthcheck:
test: mysqladmin ping -h 127.0.0.1 -u root --password=$$MYSQL_PASSWORD
interval: 5s
retries: 5
networks:
- foundation
volumes:
db_data:
package.json
{
"name": "#foundation/foundation",
"version": "1.0.0",
"description": "Foundation PHP web app",
"license": "UNLICENSED",
"private": true,
"scripts": {
"install-app": "bash ./install.sh",
"prod": "webpack --mode=production"
},
"dependencies": {
"preact": "^10.5.15"
},
"devDependencies": {
"#babel/core": "^7.15.8",
"#babel/plugin-transform-react-jsx": "^7.14.9",
"autoprefixer": "^10.3.7",
"babel-loader": "^8.2.3",
"css-loader": "^6.4.0",
"css-minimizer-webpack-plugin": "^3.1.1",
"mini-css-extract-plugin": "^2.4.3",
"postcss-loader": "^6.2.0",
"tailwindcss": "^2.2.17",
"webpack": "^5.59.1",
"webpack-cli": "^4.9.1"
}
}
install.sh
#!/bin/bash
set -e
read -p 'Enter Apache user:group [www-data:www-data]: ' usergroup
usergroup=${usergroup:-www-data:www-data}
sudo chmod 774 storage && sudo chown $usergroup storage
sudo chmod 774 tmp && sudo chown $usergroup tmp
touch log/errors.log && sudo chmod 664 log/errors.log && sudo chown $usergroup log/errors.log
touch log/exceptions.log && sudo chmod 664 log/exceptions.log && sudo chown $usergroup log/exceptions.log
npm i && npm run prod
root#0021ca12a934:/var/www/html# npm run install-app
> #foundation/foundation#1.0.0 install-app
> bash ./install.sh
Enter Apache user:group [www-data:www-data]:
sudo: you do not exist in the passwd database
sudo: you do not exist in the passwd database
sudo: you do not exist in the passwd database
sudo: you do not exist in the passwd database
./install.sh: line 9: npm: command not found
And if I try to call the install script directly:
root#0021ca12a934:/var/www/html# bash ./install.sh
Enter Apache user:group [www-data:www-data]:
up to date, audited 373 packages in 1s
53 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
> #foundation/foundation#1.0.0 prod
> webpack --mode=production
/usr/bin/env: 'node': Permission denied

Related

Laravel Docker "Unable to create a directory at /var/www/storage/app/documents"

I use Laravel 9 with Docker if I want to upload images like this:
$document["file_object"]->store('documents')
I get the following error: Unable to create a directory at /var/www/storage/app/documents
It looks like it ist some kind of Docker permission error.
I use the local Filesystems Disk because none of my files should be public.
If I change the 'root' => storage_path('app') to 'root' => storage_path('') inside the filesystems config I don't get any error but the files are saved in here: /storage/documents but they should be in /storage/app/documents.
I think I need to modify some docker user permission, but im unsure how as I'm not the one who made the config an my docker skills are limited.
Dockerfile:
FROM php:8.1-apache
WORKDIR /var/www
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg-dev \
libpng-dev \
libwebp-dev \
--no-install-recommends \
&& docker-php-ext-enable opcache \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install pdo_mysql -j$(nproc) gd \
&& apt-get autoclean -y \
&& rm -rf /var/lib/apt/lists/*
RUN pecl install redis && docker-php-ext-enable redis
# Update apache conf to point to application public directory
ENV APACHE_DOCUMENT_ROOT=/var/www/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
# Update uploads config
RUN echo "file_uploads = On\n" \
"memory_limit = 1024M\n" \
"upload_max_filesize = 512M\n" \
"post_max_size = 512M\n" \
"max_execution_time = 1200\n" \
> /usr/local/etc/php/conf.d/uploads.ini
# Enable headers module
RUN a2enmod rewrite headers
ADD . /var/www
RUN chown -R www-data:www-data /var/www
docker-compose.yml:
# https://waihein.medium.com/configuring-redis-on-docker-in-laravel-58a39556ff97
# https://medium.com/#chewysalmon/laravel-docker-development-setup-an-updated-guide-72842dfe8bdf
# https://shouts.dev/articles/dockerize-a-laravel-app-with-apache-mariadb
# FIRST Start:
# 1. Run ON WINDOWS: docker run --rm -v ${pwd}:/app composer install
# or on UNIX: docker run --rm -v “$(pwd)”:/app composer install
# 2. Run: npm run setup
# npm run setup is doing: "docker-compose up -d --build && docker-compose exec app php artisan key:generate && docker-compose exec app php artisan migrate:fresh --seed && npm install && npm run dev"
# NORMAL Start: npm start
# npm start is doing: "docker-compose up -d && npm install && npm run dev"
# To stop: docker-compose down
version: '3.8'
services:
# Application & web server
app:
build:
context: .
working_dir: /var/www
container_name: immo-app
volumes:
- ./:/var/www
depends_on:
- "database"
ports:
- 80:80
networks:
- immonet
# Database
database:
image: 'mariadb:latest'
container_name: immo-database
restart: unless-stopped
expose:
- 3306
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
volumes:
- dbdata:/var/lib/mysql
networks:
- immonet
# Database management
pma:
image: phpmyadmin:5.1
container_name: immo-phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=${DB_HOST}
- PMA_USER=${DB_USERNAME}
- PMA_PASSWORD=${DB_PASSWORD}
- PMA_PORT=${DB_PORT}
depends_on:
- database
ports:
- 8888:80
networks:
- immonet
# Redis
redis:
image: redis:alpine
container_name: immo-redis
volumes:
- ./data/redis:/data
expose:
- 6379
networks:
- immonet
volumes:
dbdata:
networks:
immonet:
driver: bridge
You should not be using www-data as the owner and group of your /var/www folder. It should be your nomal user (possibly WSL user?). If the docker container does not work without www-data, then you need to refactor it a bit, but the issue is arround the permissions.
Just try having your normal user as the owner and group of /var/www

Why is my Docker volume only sharing the docker-compose file?

I am trying to containerize a Laravel application using Docker Compose, but I am failing to use a shared volume to bring in my actual project app files. My docker-compose file looks like this:
version: "3.7"
services:
app:
build:
args:
user: sam
uid: 1000
context: ./
dockerfile: Dockerfile
image: converter
container_name: converter-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- converter
db:
image: mysql:5.7
container_name: converter-db
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- ./docker-compose/mysql:/docker-entrypoint-initdb.d
networks:
- converter
nginx:
image: nginx:alpine
container_name: converter-nginx
restart: unless-stopped
ports:
- 8000:80
volumes:
- ./:/var/www
- ./docker-compose/nginx:/etc/nginx/conf.d/
networks:
- converter
networks:
converter:
driver: bridge
volumes:
app-volume:
and the Dockerfile for the app service:
FROM php:7.4-fpm
# Arguments defined in docker-compose.yml
ARG user
ARG uid
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# Get latest Composer
#RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
chown -R $user:$user /home/$user
# Set working directory
WORKDIR /var/www
USER $user
I then run docker-compose build app and docker-compose up -d to create the containers, which brings them up. When I go to check the /var/www folder of the app container using docker-compose exec app ls -l, the only file that shows is the docker-compose file:
Shouldn't the shared volume specified for the app service share my working directory in the app /var/www folder?
You need to add these config options to the app service in compose file:
links:
- nginx
depends_on:
- nginx
These options forces docker-compose to create 1st the nginx service, and after the app, this is neccessary becuse currently nginx is created after app, and nging overwrite the /var/www directory

Laravel Not Found, Docker, Apache2

I am traying to connect to my container but I am getting the following error. Before my container works without problems. I made a new build but it doesn’t work.
My Docker file is the following:
FROM php:7.2-apache
LABEL maintainer="christianahvilla#gmail.com"
# Install PHP
RUN apt-get update && apt-get install -y \
curl \
zlib1g-dev \
libzip-dev \
nano
# Add and Enable PHP-PDO Extenstions
RUN docker-php-ext-install mysqli pdo pdo_mysql
RUN docker-php-ext-enable pdo_mysql
RUN docker-php-ext-install zip
# # Install PHP Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
#set our application folder as an environment variable
ENV APP_HOME /var/www/html
#change uid and gid of apache to docker user uid/gid
RUN usermod -u 1000 www-data && groupmod -g 1000 www-data
COPY --chown=www-data:www-data . $APP_HOME
#Expose Port 8000 since this is our dev environment
EXPOSE 8000
My Docker-Compose:
version: "3.7"
services:
#Laravel App
web:
build:
context: .
dockerfile: Dockerfile
ports:
- 8000:80
volumes:
- ./:/var/www
- ./public:/var/www/html
networks:
- mynet
depends_on:
- db
#MySQL Service
db:
image: mysql:5.7
container_name: db
ports:
- 3306:3306
environment:
MYSQL_DATABASE:
MYSQL_USER:
MYSQL_PASSWORD:
MYSQL_ROOT_PASSWORD:
volumes:
- mysqldata:/var/lib/mysql/
networks:
- mynet
#Docker Networks
networks:
mynet:
driver: bridge
#Volumes
volumes:
mysqldata:
driver: local
When I try to access to http:localhost:8000/ I can do it but if I try to access to another route I get the error.
You have to configure the apache2.conf in /etc/apache2/apache2.conf from Dockerfile, and also a2endmode rewrite, finally you need to restart apache2:
RUN sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
RUN a2enmod rewrite
RUN service apache2 restart
Then run docker-compose build and docker-compose up -d

Laravel docker: adsist-docker_app_1 exited with code 1

im trying to set up a Laravel project.
The setup is:
Centos
Apache
MySql
I have split containers for App, Web, Database
And app container is fail to run :(
This is my docker-compose.yml:
version: '2'
services:
# The Application
app:
build:
context: ./
dockerfile: app.dockerfile
working_dir: /var/www
volumes:
- ./:/var/www
environment:
- "DB_PORT=3306"
- "DB_HOST=database"
# The Web Server
web:
build:
context: ./
dockerfile: web.dockerfile
working_dir: /var/www
volumes_from:
- app
ports:
- 8080:80
# The Database
database:
image: mysql:5.6
volumes:
- dbdata:/var/lib/mysql
environment:
- "MYSQL_DATABASE=homestead"
- "MYSQL_USER=homestead"
- "MYSQL_PASSWORD=secret"
- "MYSQL_ROOT_PASSWORD=secret"
ports:
- "33061:3306"
volumes:
dbdata:
This is my app.dockerfile
FROM centos:7.5.1804
RUN yum update -y
RUN yum install epel-release http://rpms.remirepo.net/enterprise/remi-release-7.rpm yum-utils -y && \
yum-config-manager --enable remi-php72 && \
yum update -y
RUN yum install vim wget curl unzip \
php php-json php-gd php-mbstring php-pdo php-xml php-mysqlnd -y
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
php composer-setup.php --install-dir=/usr/local/bin --filename=composer && \
rm -rf composer-setup.php
RUN curl -sL https://rpm.nodesource.com/setup_8.x | bash - && \
yum install nodejs -y
RUN yum clean all
EXPOSE 80
# Keep container active
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
And this is my web.dockerfile:
FROM httpd:2.4
COPY httpd.conf /etc/httpd/conf/httpd.conf
When I run docker-compose up shows some messages:
app_1 | AH00526: Syntax error on line 119 of
/etc/httpd/conf/httpd.conf: app_1 | DocumentRoot '/var/www/html'
is not a directory, or is not readable
adsist-docker_app_1 exited with code 1
/var/www/html set as apache documentroot is popular in most linux distributions, but this is not the thing in httpd docker image. Additional, even you modify http.conf to use /var/www/html, you still should mount to /var/www/html, not /var/www.
And back to the httpd image, you could see next:
$ docker run -idt httpd:2.4
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
182c63e24082 httpd:2.4 "httpd-foreground" 3 seconds ago Up 1 second 80/tcp clever_bassi
$ docker exec -it clever_bassi /bin/bash
root#182c63e24082:/usr/local/apache2/conf# cat httpd.conf
......
DocumentRoot "/usr/local/apache2/htdocs"
......
So, if you do not change default settings, you should mount your host's files to /usr/local/apache2/htdocs to serve your service.
And more, COPY httpd.conf /etc/httpd/conf/httpd.conf in your Dockerfile is also not correct, it should be COPY httpd.conf /usr/local/apache2/conf/httpd.conf.
It seems that your app will be deployed in /var/www/ while you configure Apache to use /var/www/html/ as a document root so while starting Apache it checks first for configured document root but it can't find it so it fails to start and generate the mentioned error.
So you have to decide to change document root in httpd.conf to point to /var/www/ or configure docker-compose file to work and mount volumes to /var/www/html.

Can't access my Laravel project through Apache in Docker - /var/www/ directory is empty

So I built a Docker image of a Laravel project I'm working on, but when I run the containers (with docker-compose up), I can't access the application.
I'm currently using Docker Toolbox for Windows, so I use the IP from the docker-machine, but all I get is "The requested URL / was not found on this server." (404).
In the Docker Terminal, I get the following warnings:
php-apache_1 | AH00112: Warning: DocumentRoot [/var/www/html] does not exist
php-apache_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message
php-apache_1 | [Fri Mar 15 14:04:10.964296 2019] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
I navigated through the directories inside the container (with docker exec -it) and, indeed, the /var/www/html directory doesn't exist, once the /var/www directory is empty, but it shouldn't be!!
In the php-apache.dockerfile I copied all my project to the /var/www directory, so it shouldn't be empty.
I've been trying to solve this for a while now, so if anyone could help me I would really appreciate it.
Here is the php-apache.dockerfile:
FROM php:7.2.9-apache-stretch
RUN apt-get update && apt-get install -y libxml2-dev && apt-get install -y
libcurl3-dev
RUN docker-php-ext-install pdo_mysql mbstring tokenizer xml ctype json
RUN mkdir storage &&\
mkdir storage/logs &&\
mkdir storage/app &&\
mkdir storage/framework &&\
mkdir storage/framework/cache &&\
mkdir storage/framework/sessions &&\
mkdir storage/framework/views &&\
mkdir -p bootstrap/cache
COPY composer.json composer.lock /var/www/
WORKDIR /var/www
COPY . /var/www
RUN curl --silent https://getcomposer.org/installer | php &&\
composer install
COPY public /var/www/html
RUN chown -R www-data:www-data \
/var/www/storage \
/var/www/bootstrap/cache
RUN a2enmod rewrite
EXPOSE 80
And the docker-compose.yml:
version: '3'
services:
db:
image: mysql:latest
environment:
- MYSQL_USER=root
- MYSQL_ROOT_PASSWORD=
- MYSQL_DATABASE=ontologyFramework
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
ports:
- "3306:3306"
php-apache:
depends_on:
- db
build:
dockerfile: phpapache.dockerfile
context: .
volumes:
- ./:/var/www
ports:
- "80:80"
environment:
- DB_PORT=3306
- DB_HOST=127.0.0.1
links:
- db
It looks like the problem is with your docker-compose.yml file. The files you are copying to /var/www in your php-apache.dockerfile are being hidden by the volume mapping in your docker-compose.yml file. Remove the following lines from the compose file:
volumes:
- ./:/var/www

Resources