I have 1 dockerfile, 1 stage of the build for the node server, serving some data, and the 2nd stage is a react app. I use a docker compose file to run the dockerfile.
I am able to access the react app via port 3000, but the 2nd stage server isn't running so I can't access the data.
Any idea how to solve it?
FROM node:12.6
WORKDIR /usr/src/app
COPY package.json .
COPY . .
EXPOSE 5500 // node server
CMD ["npm","run", "server"]
FROM node:12.6
WORKDIR /usr/src/app
COPY package.json .
RUN npm i
COPY . .
EXPOSE 3000 // react app
CMD ["npm","run", "dev"]
version: "3.9"
services:
testingapp:
container_name: testingApp
build: .
volumes:
- ./src:/app/src:delegated
ports:
- "3000:3000"
I have read various docs online.
You're trying to run the front- and back-ends in the same container. A container only runs one process, though; if you need two separate processes from the same code base then you can run two separate containers off the same image, overriding the command: on one of them.
So reduce the Dockerfile to copy the code base in, and declare one process or the other as the main container command:
FROM node:12.6
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm ci
COPY ./ ./
EXPOSE 3000
CMD ["npm", "run", "server"]
Now in your Compose file, declare two separate containers. For the second, override the command: with the alternate program to run. Both can build: the same image; the second build will come entirely from the Docker layer cache and be all but free. The code is built into the image and you don't need to replace it using volumes:.
version: '3.8'
services:
express:
build: .
ports: ['5500:3000']
react:
build: .
command: npm run dev
ports: ['3000:3000']
Related
I have 2 docker images, one for flask BE and another for React FE. I created a docker-compose and everything goes ok. I need to push this... container?, composer? to docker hub, how can i do this? I add to this post both dockerfiles and the docker-compose.yml file.
BackEnd
FROM python:3.9.0
WORKDIR /app
COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY . .
RUN python -m nltk.downloader all
EXPOSE 5000
CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]
FrontEnd
FROM node:16-alpine
RUN mkdir -p /app
WORKDIR /app
COPY ./package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "start"]
docker-composer.yml
services:
api:
build:
context: .
dockerfile: Dockerfile
image: flask-back
ports:
- "5000:5000"
client:
build:
context: .
dockerfile: Dockerfile
image: react-front
ports:
- "3000:3000"
As #votelessbubble mentioned, you can do docker-compose push but only under certain conditions.
You are pushing an image you have built locally
which is in your case true for both images
You have access to the build key
now, this is where the problem lies. You need to have a private/public docker registry set in the image section as show in the yaml below (link to documentation)
services:
service1:
build: .
image: localhost:5000/yourimage ## goes to local registry
service2:
build: .
image: your-dockerid/yourimage ## goes to your repository on Docker Hub
What I suggest to do, is to push these images not with the docker-compose push command, but rather with docker push. The steps you need to take are following.
If you are using a private repository, login to that repository first
docker login --username=<username> --email=<email> [SERVER]
Build the image
docker build -t <tag> . # replace the dot with the current location of dockerfile or inside your project
Push the image
docker push <registry>/<user>/<service>:<tag>
I have dockerized the sveltekit app and my issue is that when I am running container
and when I make changes in frontend UI I am able to see them only for 1 second and then
my frontend is looking like before any changes.
I think that problem is about caching in sveltekit.
My Dockerfile:
FROM node:16
WORKDIR /test-app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
ENV PORT 3000
EXPOSE 3000
EXPOSE 24678
CMD ["node", "build"]
My docker-compose.yaml file:
version: '3'
services:
svelte-test:
image: sveltekit-test:node
volumes:
- ./:/test-app/
ports:
- 3000:3000
- 24678:24678
- 5173:5173
tty: true
stdin_open: true
Port 3000 is for sveltekit, 5173 is for sveltekit but in Docker and 24678 is for vite.
My folder structure is:
sveltekit-docker
test-app
-Dockerfile
-docker-compose.yaml
-package-lock.json
-package.json
-svelte.config.js
-tsconfig.json
-vite.config.js
-all sveltekit folders (src, node_modules, static, tests)
If you want to see the changes you need HMR (Hot module reloading) available in dev mode.
You also may need to rebuild esbuild. Try replacing the last line of your Dockerfile with
CMD npm rebuild esbuild && npm run dev -- --host
I created a repo if it helps.
To use it:
docker build --tag sveltekit-test .
docker-compose up
Goal
Dockerize NextJS application
Problem
Docker compose up yields in the following error: Couldn't find a pages directory. Please create one under the project root.
Application
Files & folders
docker-compose.yml
web
.next
pages
public
.dockerignore
dockerfile
[more nextjs files & folders here]
docker-compose
version: '3'
services:
web:
build:
context: web
dockerfile: dockerfile
ports:
- "3000:3000"
container_name: rughood_web
dockerfile
FROM node:16
WORKDIR /web
COPY package*.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
.dockerignore
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.git
Note!
The NextJS application itself is working fine when I run npm run dev within the web directory (which invokes the script "dev": "next dev" in package.json). I only have the error when trying to dockerize it. Moreover, in the docker-compose I also initiate a Redis cache, which is working fine too. Therefore I conclude the error must be how I try to combine Docker and NextJS. Thank you very much in advance :)
Update 1
How I got there
Using the tips from #HansKilian and Exploring Docker container's file system I did the following:
Cd to the web directory
Built an image from the dockerfile docker build .
Explored the image with the following command docker run --rm -it --entrypoint=/bin/bash name-of-image
Once inside, execute ls or ls -lsa
This gave me the following results:
What's in the derived image
dockerfile
next-env.d.ts
next.config.js
node_modules
package-lock.json
package.json
pages
public
tsconfig.json
[Among other files/folders]
So the pages folder actually seems to be in the root of the container, yet still I get the error (pages is a directory in the container in which I can cd and -ls)
P.s. don't forget to delete your image if you're not going to using it anymore
Update 2
Building the image and running it from within the web directory actually works, so it might actually have something to do with the docker-compose?
Here is my working Dockerfile with nextjs:
FROM node:16.14.0
RUN npm install -g npm#8.5.5
RUN mkdir -p /app
WORKDIR /app
COPY package*.json /app
RUN npm i
COPY . /app
EXPOSE 3000
RUN npm run build
CMD ["npm", "run", "dev"]
And docker-compose.yml :
version: "3.7"
services:
project-name:
image: project-name
build:
context: .
dockerfile: Dockerfile
container_name: project-name
restart: always
volumes:
- ./:/app
- /app/node_modules
- /app/.next
ports:
- "3000:3000"
While I was trying every single line of code ever uploaded to the internet, I came back to my initial set-up (from the question) and suddenly it now does work. Source control confirming I didn't change a thing.
To be sure, I deleted all containers, images and volumes from Docker and ran docker compose up. Yet still it worked. Tried many things to recreated the error, but I couldn't. Thank you all for helping and hopefully this may be come to use for someone else!
I have this files:
docker-compose.yml (shortened):
version: '3.7'
services:
php-fpm:
build:
context: .
dockerfile: docker/php/Dockerfile
target: dev
volumes:
- .:/app
frontend:
build:
context: .
dockerfile: docker/php/Dockerfile
target: frontend
volumes:
- .:/app
docker/php/Dockerfile (shortened):
FROM alpine:3.13 AS frontend
WORKDIR /app
COPY . .
RUN apk add npm
RUN npm install
RUN npx webpack -p --color --progress
FROM php:7.4-fpm AS dev
ENTRYPOINT ["docker-php-entrypoint"]
WORKDIR /app
COPY ./docker/php/www-dev.conf /usr/local/etc/php-fpm.d/www.conf
CMD ["php-fpm"]
I want to use all what building in frontend (as I understood at the stage build at this time volumes are not available) in php-fpm container, but I get something like this: file_get_contents(/app/static/frontend.version): failed to open stream.
How I can do this? I don't understand very well in Docker and the only solution I have is to move build script to php-fpm container.
You need to delete the volumes: in your docker-compose.yml file. They replace the entire contents of the image's /app directory with content from the host, which means everything that gets done in the Dockerfile gets completely ignored.
The Dockerfile you show uses a setup called a multi-stage build. The important thing you can do with this is build the first part of your image using Node, then COPY --from=frontend the static files into the second part. You do not need to declare a second container in docker-compose.yml to run the first stage, the build sequence runs this automatically. This at a minimum looks like
COPY --from=frontend /app/build ./static
You will also need to COPY the rest of your application code into the image.
If you move the Dockerfile up to the top of your project's source tree, then the docker-compose.yml file becomes as simple as
version: '3.8'
services:
php-fpm:
build: . # default Dockerfile, default target (last stage)
# do not overwrite application code with volumes:
# no separate frontend: container
But you've put a little bit more logic in the Dockerfile. I might write:
FROM node:lts AS frontend # use a prebuilt Node image
WORKDIR /app
COPY package*.json . # install dependencies first to save time on rebuild
RUN npm install
COPY . . # (or a more specific subdirectory?)
RUN npx webpack -p --color --progress
FROM php:7.4-fpm AS dev
WORKDIR /app
COPY . . # (or a more specific subdirectory?)
COPY --from=frontend /app/build ./static
COPY ./docker/php/www-dev.conf /usr/local/etc/php-fpm.d/www.conf
# don't need to repeat unmodified ENTRYPOINT/CMD from base image
I am wanting to deploy my application however, I want to be able to use a local package (located in my package.json) in my project. When I'm buliding my application, it is unable to find the package. Is there anyway I can fix this?
Docker File
FROM node:12
WORKDIR /var/v5/com.app.api
COPY package*.json ./
RUN npm install
ADD . /var/v5/com.app.api
RUN npm run build
COPY . .
EXPOSE 3011
CMD ["npm", "start"]
Docker Compose
version: '2.2'
services:
app:
container_name: com.app.api
restart: always
build: .
ports:
- '3011:3011'
network_mode: 'host'
I hope this makes sense.
Thanks.
It is because dockerfile is not able to find your package to copy. Give the complete path of the package you are looking for in COPY instruction.
Something like:
COPY /path/to/mypackage/package.json ./