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.
Related
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
everyone, I am confused I am new to the DevOps world and I have no idea how to use docker-compose or swarm in production I mean what are the best practices in production for both I followed up with this article on the digital ocean How To Install and Set Up Laravel with Docker Compose on Ubuntu 20.04
all works like a charm in local, test, and dev environments, and I tried to take this to the next step for production env, and I noticed some things should be changed for production mode like so
Removing any volume bindings for application code, so that code stays inside the container and can’t be changed from outside.
Binding to different ports on the host. check the link for more info use compose in production
I don't know how to achieve #1 point
here's my DockerFile below to build my custom laravel image and docker-compose for my services
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 \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Download php extension installer
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
# Give php extension installer a permission
RUN chmod +x /usr/local/bin/install-php-extensions
# Install php extensions via php extension installer
RUN install-php-extensions zip
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/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/html
USER $user
version: "3.7"
services:
app:
build:
args:
user: sammy
uid: 1000
context: ./
dockerfile: Dockerfile
image: app
container_name: app
restart: always
working_dir: /var/www/html
volumes:
- ./:/var/www/html
networks:
- backend
db:
image: mysql:8.0
container_name: db
restart: always
environment:
MYSQL_DATABASE: ROUTE
MYSQL_ROOT_PASSWORD: 2020
MYSQL_PASSWORD: 2020
MYSQL_USER: sqluser
volumes:
- db:/var/lib/mysql
networks:
- backend
nginx:
image: nginx:1.21.6
container_name: nginx
restart: always
ports:
- 8000:80
networks:
- backend
volumes:
- ./:/var/www/html
- ./docker-compose/nginx:/etc/nginx/conf.d/
phpmyadmin:
image: phpmyadmin
container_name: pma
restart: always
ports:
- 8283:80
environment:
PMA_HOSTS: db
PMA_ARBITRARY: 1
PMA_USER: sqluser
PMA_PASSWORD: 2020
networks:
- backend
networks:
backend:
driver: bridge
volumes:
db:
Note:-
in Nginx service, I Created two shared volumes. The first one will synchronize contents from the current directory to /var/www inside the container. This way, when you make local changes to the application files, they will be quickly reflected in the application being served by Nginx inside the container (Which is not good for production). The second volume will make sure our Nginx configuration file, located at docker-compose/nginx/, is copied to the container’s Nginx configuration folder.
i tried to remove the first volume but keep the second one to use my custom configuration but it did not work at all why?
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
I'm on a Mac OS X, and have a docker-compose.yml
version: '3'
services:
portalmodules:
build:
context: .
dockerfile: Dockerfile
ports:
- 8010:8000
links:
- database
database:
image: postgres:11.2
expose:
- "5432"
environment:
- "POSTGRES_PASSWORD=12345"
- "POSTGRES_USER=john"
- "POSTGRES_DB=api"
I also have a Dockerfile
FROM composer:1.8.5 as build_stage
COPY . /src
WORKDIR /src
RUN composer install
FROM alpine:3.8
RUN apk --no-cache add \
php7 \
php7-mbstring \
php7-session \
php7-openssl \
php7-tokenizer \
php7-json \
php7-pdo \
php7-pdo_pgsql \
php7-pgsql
COPY --from=build_stage /src /src
RUN ls -al
RUN set -x \
addgroup -g 82 -S www-data \
adduser -u 82 -D -S -G www-data www-data
WORKDIR /src
RUN ls -al
RUN chmod -R 777 storage
CMD php artisan serve --host=0.0.0.0
The container seems to build and start successfully when I ran docker-compose up.
But when I tried to connect to the database:
IP: localhost
Port: 5432
UN : john
PW : 12345
I kept getting
How would one go about and debug this further?
By specifying a port in the expose configuration, you're only opening that port to other Docker containers in the Docker network. It will not be open to connect to from your host machine (OS X).
You want to add a ports configuration, which allows you to map host machine ports to the container.
database:
image: postgres:11.2
expose:
- "5432"
ports:
- "5432:5432"
environment:
- "POSTGRES_PASSWORD=12345"
- "POSTGRES_USER=john"
- "POSTGRES_DB=api"
More information in this helpful StackOverflow Q&A.
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