Docker Nginx with React and Laravel - react-native

So I want to have a single Nginx web server serving both frontend and backend with Docker.
Here is my docker-compose:
version: "3.8"
services:
db: #mysqldb
image: mysql:5.7
container_name: ${DB_SERVICE_NAME}
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
ports:
- $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
volumes:
- ./docker-compose/mysql:/docker-entrypoint-initdb.d
networks:
- backend
mrmfrontend:
build:
context: ./mrmfrontend
args:
- REACT_APP_API_BASE_URL=$CLIENT_API_BASE_URL
- REACT_APP_BACKEND_ENDPOINT=$REACT_APP_BACKEND_ENDPOINT
- REACT_APP_FRONTEND_ENDPOINT=$REACT_APP_FRONTEND_ENDPOINT
- REACT_APP_FRONTEND_ENDPOINT_ERROR=$REACT_APP_FRONTEND_ENDPOINT_ERROR
- REACT_APP_CUSTOMER=$REACT_APP_CUSTOMER
- REACT_APP_NAME=$REACT_APP_NAME
- REACT_APP_OWNER=""
ports:
- $REACT_LOCAL_PORT:$REACT_DOCKER_PORT
networks:
- frontend
nginx:
image: nginx:alpine
container_name: backend-nginx
restart: unless-stopped
ports:
- 8000:80
volumes:
- ./MRMBackend:/var/www
- ./docker-compose/nginx/backend:/etc/nginx/conf.d/
networks:
- backend
- frontend
app:
build:
args:
user: admin
uid: 1000
context: ./MRMBackend
dockerfile: Dockerfile
image: backend
container_name: backend-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./MRMBackend:/var/www
networks:
- backend
volumes:
db:
networks:
frontend:
driver: bridge
backend:
driver: bridge
And here's the Dockerfile for the frontend:
FROM node:16.13.0 as build-stage
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
ARG REACT_APP_API_BASE_URL
ARG REACT_APP_BACKEND_ENDPOINT
ARG REACT_APP_FRONTEND_ENDPOINT
ARG REACT_APP_FRONTEND_ENDPOINT_ERROR
ARG REACT_APP_CUSTOMER
ARG REACT_APP_NAME
ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL
ENV REACT_APP_BACKEND_ENDPOINT=$REACT_APP_BACKEND_ENDPOINT
ENV REACT_APP_FRONTEND_ENDPOINT = $REACT_APP_FRONTEND_ENDPOINT
ENV REACT_APP_FRONTEND_ENDPOINT_ERROR = $REACT_APP_FRONTEND_ENDPOINT_ERROR
ENV REACT_APP_CUSTOMER=$REACT_APP_CUSTOMER
ENV REACT_APP_NAME=$REACT_APP_NAME
ENV GENERATE_SOURCEMAP=false
RUN npm run build
The problem is that the frontend container can't seem to start. It exit always at startup.
From my understanding I should copy the build content of the build-stage into the nginx folder "/usr/share/nginx/html" but how can I do it from the docker-compose file?
Just using volumes won't work. I need nginx in the docker-compose because it's also serving the backend.
Please note that the backend is working correctly.
UPDATE
My first approach was to use a Dockerfile for the frontend where I copied the content of the build directly into an Nginx image
# Stage 1
FROM node:16.13.0 as build-stage
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
ARG REACT_APP_API_BASE_URL
ARG REACT_APP_BACKEND_ENDPOINT
ARG REACT_APP_FRONTEND_ENDPOINT
ARG REACT_APP_FRONTEND_ENDPOINT_ERROR
ARG REACT_APP_CUSTOMER
ARG REACT_APP_NAME
ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL
ENV REACT_APP_BACKEND_ENDPOINT=$REACT_APP_BACKEND_ENDPOINT
ENV REACT_APP_FRONTEND_ENDPOINT = $REACT_APP_FRONTEND_ENDPOINT
ENV REACT_APP_FRONTEND_ENDPOINT_ERROR = $REACT_APP_FRONTEND_ENDPOINT_ERROR
ENV REACT_APP_CUSTOMER=$REACT_APP_CUSTOMER
ENV REACT_APP_NAME=$REACT_APP_NAME
#avoid javascript out of memory
ENV GENERATE_SOURCEMAP=false
RUN npm run build
# Stage 2
FROM nginx:1.17.0-alpine
COPY --from=build-stage /app/build /usr/share/nginx/html
EXPOSE $REACT_DOCKER_PORT
CMD nginx -g 'daemon off;'
But in this way I think I'm deploying two Nginx. One in the Dockerfile and one in the Docker-compose. Am I right?

#federico-arona
As stated in my comment: If you want to have 1 nginx you need to share or copy the files from the container that is building the app.
Based on your requirements and what you wanted to accomplish. The best solution is named volumes, as they can be shared across containers.
They are the preferred mechanism for persisting data generated by and used by Docker containers. Plus you can manage volumes using Docker CLI commands and the Docker API. The Official docs show other benefits and additional information on how to use them.

I mostly use Docker multi-build to configure my FE app. Hope this might help you!
FROM node:16.13.0 as build-stage
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm install
RUN npm run dev
#Build Files
FROM nginx:1.19.10-alpine
COPY nginx-conf /etc/nginx/conf.d/default.conf
COPY --from=build /app /home/ubuntu/app/dist
you can use default nginx configuration.

Related

Cannot run Asp.Net Core inside docker linux

I'm trying to get the ASP.Net Core running inside docker with docker-compose. Here is the dockerfile content:
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY ["SchoolContact/SchoolContact.csproj", "SchoolContact/"]
RUN dotnet restore "SchoolContact/SchoolContact.csproj"
COPY . .
WORKDIR "/src/SchoolContact"
RUN dotnet build "SchoolContact.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "SchoolContact.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
ENV ASPNETCORE_URLS http://+:5000
EXPOSE 5000 80
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "SchoolContact.dll"]
And here is the docker-compose.yml content:
version: '3'
services:
api:
image: schoolcontact
build:
context: .
dockerfile: SchoolContact/Dockerfile
links:
- db:db
ports:
- '5000:5000'
restart: always
networks:
- school
db:
image: mysql:5.7
volumes:
- ./db:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: Test
MYSQL_USER: admin
MYSQL_PASSWORD: 123456
networks:
- school
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin
restart: always
ports:
- '8080:80'
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: 123456
networks:
- school
reverse-proxy:
container_name: proxy
image: nginx
depends_on:
- api
ports:
- "9090:8080"
volumes:
- ./proxy.conf:/etc/nginx/conf.d/default.conf
networks:
- school
networks:
school:
volumes:
db:
driver: "local"
The proxy.conf:
server {
listen 8080;
location / {
proxy_pass http://api:5000;
}
}
I've tried too many times before posting here and ask for help, I tried to run without nginx, expose port or not, so many ways. But I still cannot access the app. My final purpose is to host the app in docker and can access it through URL http://localhost:5000. I don't know where I've wrong or missing something else. I really need help with this. Thanks for reading.
Here is how mine work, after few weeks of researching (for those have the same issue), add these line in the Main method. Also, the dockerfile and docker-compose.yml should look like below:
public static void Main(string[] args)
{
//CreateWebHostBuilder(args).Build().Run();
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls("http://*:9001")
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
docker-compose.yml
services:
api:
image: schoolcontact
build:
context: .
dockerfile: SchoolContact/Dockerfile
links:
- db:db
ports:
- 9021:9001
restart: always
networks:
- school
dockerfile
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
#EXPOSE 443
FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY ["SchoolContact/SchoolContact.csproj", "SchoolContact/"]
RUN dotnet restore "SchoolContact/SchoolContact.csproj"
COPY . .
WORKDIR "/src/SchoolContact"
RUN dotnet build "SchoolContact.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "SchoolContact.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
EXPOSE 9001
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "SchoolContact.dll"]

Docker don't have permission on this server

I have a dockerfile and docker-compose.yml.
I don't understand why i don't have the permission ...
I have also a index.php in my public folder
Dockerfile:
FROM php:7.2-apache
RUN apt-get update && docker-php-ext-install pdo_mysql
Docker-compose.yml:
version: "3"
services:
php:
build: './image/'
volumes:
- ./src:/var/www/html/
ports:
- '30000:80'
adminer:
image: adminer
ports:
- '40000:8080'
db:
image: mariadb
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_USER=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=meetup
Folders:
meetup
app
bin
get_started
image
dockerfile
public
index.php
src
templates
docker-compose.yml
Based on your comment, it simply looks like the root directory of the Apache does not contain index.php.
You should do one of these:
Either move the index.php from your public folder to your src folder
Or, change the mount in the docker-compose from ./src:/var/www/html to ./public:/var/www/html (in any case, the trailing slash is not needed).

Module (nodemon) not found(package.json not found) DOCKER ISSUE

i'm trying to dockerize my express app, but when i try to run the CMD in the container , docker says me ' "Command \"nodemon\" not found."' like it doesn't find package.json in container. This is my dockerfile:
FROM node:8
WORKDIR /express-app/
COPY package.json .
RUN yarn
COPY . .
ARG MONGO_DB_DATABASE
ENV MONGO_DB_DATABASE ${MONGO_DB_DATABASE}
ARG MONGO_DB_USERNAME
ENV MONGO_DB_USERNAME ${MONGO_DB_USERNAME}
ARG MONGO_DB_PASSWORD
ENV MONGO_DB_PASSWORD ${MONGO_DB_PASSWORD}
EXPOSE 3000
CMD ["yarn", "start"]
and this is my docker-compose.yml
express-app:
build: ../../express-app
command:nodemon
environment:
- MONGO_DB_DATABASE=testDb
- MONGO_DB_USERNAME=test
- MONGO_DB_PASSWORD=test
expose:
- 3000
ports:
- "3000:3000"
volumes:
- ../../express-app:/express-app
depends_on:
- mongodb
links:
- mongodb
restart: always
Somewhere in your Dockerfile, throw in a RUN npm install nodemon -g. That installs and adds to your path

Docker : image build failed

when building docker apache image, the building fail in this step :
Step n/m : COPY httpd-foreground /usr/local/bin/
ERROR: Service 'apache' failed to build: COPY failed: stat
/var/lib/docker/tmp/docker-builder511740141/httpd-foreground: no such
file or directory
this is my docker_compose.yml file
version: '3'
services:
mysql:
image: mysql:5.7
container_name: mysql_octopus_dev
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
MYSQL_USER: root
MYSQL_PASSWORD: root
apache:
build: .
container_name: apache_octopus_dev
volumes:
- .:/var/www/html/
ports:
- "8000:80"
depends_on:
- mysql
this is my docker file
FROM debian:jessie-backports
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
#RUN groupadd -r www-data && useradd -r --create-home -g www-data www-data
...
COPY httpd-foreground /usr/local/bin/
EXPOSE 80
CMD ["httpd-foreground"]
any help please?
Paths in a Dockerfile are always relative to the the context directory. The context directory is the positional argument passed to docker build (often .).
I should place the httpd-foreground file in the same folder of dockerfile.
From : https://github.com/docker/for-linux/issues/90

DRY docker-compose

I'm trying to find a more DRY way to use docker-compose env.
docker-compose-base.yml
base:
image: reactjs_web
volumes:
- src:/reactjs/src
- bin/server:/reactjs/bin/server
- config:/reactjs/config
docker-compose-prod.yml
svr:
extends:
file: docker-compose-base.yml
service: base
command: npm run prod:deploy
ports:
- "8081:8081"
environment:
NODE_ENV: production
PORT: "8081"
CLTPORT: "8082"
clt:
extends:
file: docker-compose-base.yml
service: base
command: npm run prod:deploy:clientside
ports:
- "8082:8082"
environment:
NODE_ENV: production
PORT: "8082"
The ports and the env port are equals
Is there a way to reference the clt port to the svr container ?
Docker Environment File
Use a .env file and reference it in both containers. This will ensure you only need to store these settings in a single location.
Compose supports declaring default environment variables in an environment file named .env placed in the folder docker-compose command is executed from (current working directory).
Compose expects each line in an env file to be in VAR=VAL format. Lines beginning with # (i.e. comments) are ignored, as are blank lines.
Compose File Integration:
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
Docker Compose File Reference - env_file
Docker Compose Environment File Documentation
You can use environment variable inside docker-compose.
svr:
extends:
file: docker-compose-base.yml
service: base
command: npm run prod:deploy
ports:
- ${CLTPORT}:${PORT}
environment:
NODE_ENV: production
clt:
extends:
file: docker-compose-base.yml
service: base
command: npm run prod:deploy:clientside
ports:
- ${CLTPORT2}:${PORT2}
environment:
NODE_ENV: production
run docker-compose like:
CLTPORT=8082 PORT=8081 CLTPORT2=8081 PORT2=8082 docker-compose -f docker-compose-prod.yml up
Of course change your port variables as you need.
You can reference an environment variable to solve this
https://github.com/docker/compose/issues/1377