How do I create this using Docker - ruby-on-rails

Download the repository to your local machine and unzip the directory. Enter the directory (you may rename the directory first) on command line environment, then use the following command to download the rails docker image and to build.
The repository file is been downloaded and unzipped it. What should I do
docker-compose run web rails new . --force --no-deps --database=postgresql
docker-compose build
ERROR:
Can't find a suitable configuration file in this directory or any
parent. Are you in the right directory?
Supported filenames: docker-compose.yml, docker-compose.yaml

You need to define docker-compose.yml file or docker-compose.yaml. Accordingly to documentation:
Using Compose is basically a three-step process:
1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
3. Run docker-compose up and Compose starts and runs your entire app.
A docker-compose.yml looks like this:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
More on official website

Related

docker-compose change name of main container

I have a simple frontend and backend app. And I have a docker-compose file but it's inside frontend folder. So when I run it both frontend and backend containers are under frontend container (it takes name of the folder) how can I rename this main container? I am using version 3.9
version: "3.9"
services:
be_service:
container_name: backend
build:
context: ../backend
dockerfile: ./Dockerfile
ports:
- "8089:8080"
fe_service:
container_name: frontend
build:
context: ./
dockerfile: ./Dockerfile
ports:
- "8088:80"
depends_on:
- be_service
When refering to your main container, you are probably refering to the project name, which you could usually set via the -p flag. (See other answers)
For docker-compose, you can set the top level variable name to your desired project name.
docker-compose.yml file:
version: "3.9"
name: my-project-name
services:
myService:
...
If you are using Docker Desktop, make sure Use Docker Compose V2 is enabled there.
Related to Docker Compose docs you can set your project name with:
docker-compose -p app up --build
with -p app to set your compose container name to app.
I think that your docker compose file is right and to change the co you can use the containe_name instruction but I think you should run this command when you want to run your application :
docker-compose up --build
Use -p to specify a project name
Each configuration has a project name. If you supply a -p flag, you can specify a project name. If you don’t specify the flag, Compose uses the current directory name.
Calling docker-compose --profile frontend up will start the services with the profile frontend and services without specified profiles. You can also enable multiple profiles, e.g. with docker-compose --profile frontend --profile debug up the profiles frontend and debug will be enabled
Also refer https://docs.docker.com/compose/profiles/

Can you use the current project_name in a docker compose file?

I see lots of questions around setting/changing the COMPOSE_PROJECT_NAME or PROJECT_NAME using ENV variables.
I'm fine with the default project name, but I would like to reference it in my compose file.
version: "3.7"
services:
app:
build: DockerFile
container_name: app
volumes:
- ./:/var/app
networks:
- the-net
npm:
image: ${project_name}_app
volumes:
- ./:/var/app
depends_on:
- app
entrypoint: [ 'npm' ]
networks:
- the-net
npm here is arbitrary , hopefully the fact that could be run as its own container or in other ways does not distract from the questions.
is it possible to reference the project name with out setting it manually or first?
Unfortunately it is not possible.
As alluded to, you can create a .env file and populate it with COMPOSE_PROJECT_NAME=my_name, but the config option does not present itself in your environment by default.
Unfortunately the env substitution in docker-compose is fairly limited, meaning we cannot use the available PWD env variable and greedy match it at all
$ cd ~
$ pwd
/home/tqid
$ echo "Base Dir: ${PWD##*/}"
Base Dir: tqid
When we use this reference, compose has issues:
$ docker-compose up -d
ERROR: Invalid interpolation format for "image" option in service "demo": "${PWD##*/}"
It's probably better to be explicit anyway, the COMPOSE_PROJECT_NAME is based on your dir, and if someone clones to a new folder then it gets out of whack, including the .env file in source control would provide a re-usable and consistent place to reference the name
https://docs.docker.com/compose/reference/envvars/#compose_project_name
using the same image as another container was what I was after ... reuse the image and change the entry point.
Specify the same build: options for both containers.
This seems inefficient, in that it will trigger the build sequence twice and docker images will list both of them. However, the way Docker's layer caching works, if identical RUN commands are run on identical input images, the resulting layer will simply be reused, and the two final images will have the same image ID; they will literally be the same image with two names.
The context I've run into this the most is with a Python application where the same code base is used for a Django or Flask Web server, plus a Celery worker. The Docker-level setup is fairly language-independent, though: specify the same build: for both containers, and override the command: for the container(s) that need to do a non-default task.
version: '3.8'
services:
app:
build: .
ports: ['3000:3000']
environment:
REDIS_HOST: redis
worker:
build: . # <-- same as app
command: npm run worker # <-- overrides Dockerfile CMD
environment:
REDIS_HOST: redis
redis:
image: redis
It is also valid to specify build: and image: together in the docker-compose.yml file; this specifies the name of the image that will be built. It's frequently useful to explicitly specify this because you will need to point at a specific Docker Hub or other registry location to push the built image. If you do this, then you'll know the image name and don't need to depend on the context name.
version: '3.8'
services:
app:
build: .
image: registry.example.com/my/app:${TAG:-latest}
worker:
image: registry.example.com/my/app:${TAG:-latest}
command: npm run worker
You will need to manually docker-compose build in this setup. Compose's workflow doesn't have a way to specify that one container's build must run before a different container can start.

How to copy files inside container with docker-compose

I have a simple image that runs a jar file. That jar file inside the image needs a special configuration file in order to run.
In the location with the docker-compose.yml I have a folder named "carrier" and under this folder I have that file.
The docker-compose.yml:
version: "3.3"
services:
web:
image: "myimage:1.80.0.0"
ports:
- "61003:61003"
volumes:
- ./carrier:/var/local/Config/
When I hit docker-compose up it complains that the file is not there, so it doesn't copy it.
If I do another option like I did in the .sh command, something like this:
volumes:
- ./carrier:/var/local/Config/:shared
It complains about another error:
C:\Tasks\2246>docker-compose up
Removing 2246_web_1
Recreating 1fbf5d2bcea4_2246_web_1 ... error
ERROR: for 1fbf5d2bcea4_2246_web_1 Cannot start service web: path /host_mnt/c/Tasks/2246/carrier is mounted on / but it is not a shared mount
Can someone please help me?
Copy the files using Dockerfile, use below;
FROM myimage:1.80.0.0
RUN mkdir -p /var/local/Config/
COPY carrier /var/local/Config/
EXPOSE 61003
docker-compose.yml
version: "3.3"
services:
web:
build:
dockerfile: Dockerfile
context: '.'
ports:
- "61003:61003"
In the end, run below command to build new image and start container
docker-compose up -d --build
You can use Dockerfile if it does not copy.
Dockerfile;
FROM image
COPY files /var/local/Config/
EXPOSE 61003
Docker-compose;
version: "3.3"
services:
web:
build: . (path contains Dockerfile)
ports:
- "61003:61003"
volumes:
- ./carrier:/var/local/Config/
Remove the last /
volumes:
- ./carrier:/var/local/Config
I'm not sure but you can try to set full access permissions for all user to /carrier:
chmod -R 777 /carrier
Thanks all for all your answers.
Seems like finally docker warned me with some comparisons over the windows files vs Linux files when building the image. (Not with docker compose but with Dockerfile).
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
Tried it on linux and works.

Docker-Compose File

I have three seperate Microservices, and for each of them in their directory I have Dockerfile.
I am beginner in Docker and I am a little confused.
for define Docker Compose file, I must define three docker-compose.yml files in the directory of each services?!
Or I must define just one docker-compose.yml file for all my services?! If yes, in which directory?
Docker compose is built for having multiple apps, with a Dockerfile it is very powerful.
To put it simply you can split a docker-compose file into things called 'services' and they act as different, separate apps/microservices, so say I wanted a nodejs app and a database within the same docker-compose file and Dockerfile:
Dockerfile:
FROM node:7.7.2-alpine
WORKDIR /usr/app
COPY package.json .
RUN npm install --quiet
COPY . .
Docker-compose:
version: '3.1'
services:
mongo:
image: mongo
name: database
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
web:
build: .
command: npm run dev
volumes:
- .:/usr/app/
- /usr/app/node_modules
ports:
- "3000:3000"
depends_on:
- mongo
If you ran that in the directory you want to work at, it will always stay in that directory . You can name each service it's own name. This example it's mongo and web. Once running, locally you can reference and connect to your services just by using their respective names.
I recommend these two YouTube video. Quick and simple. Here and here
You don't need to create separate compose file. Docker compose provides you the option to specify the location of Dockerfiles in order to setup the containers. In the root folder which contains this three app create a compose file.
For an example check this file https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/docker-compose.yml

Docker-compose: replace "build"-based service with pre-built image in production?

Let's say we have the following docker-compose.yml:
version: '3'
services:
db:
image: "postgres"
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=mysecretpassword
web:
build: web
depends_on: [ db ]
ports:
- "80:80"
The first service, db, just runs a container with the official postgres image from Docker Hub.
The second service, web, first builds a new image based on the Dockerfile in a folder also called web, then runs a container with that image.
While developing, we now can (repeatedly) make changes to whatever is in the web folder, then run docker-compose up --build to run our app locally.
Let's say we now want to deploy to production. My understanding is that docker-compose.yml can now be used to "define a stack in Docker's swarm mode" (see this answer, for instance). However, for the build step of the web service, Docker's compose file documentation states that
This option is ignored when deploying a stack in swarm mode with a (version 3) Compose file. The docker stack command accepts only pre-built images.
It probably wouldn't be a great idea to build the image on the production machine anyways, as this would leave build artifacts (source code) behind; this should happen on a build server.
My question is, is there a recommended way to modify docker-compose.yml en route to production to swap out build: web with image: <id> somehow?
Nothing on Use Compose in production on that. Is there something wrong with my approach in general?
docker-compose.yml should only contain canonical service definitions.
Anything that's specific to the build environment (e.g. dev vs prod) should be declared in a separate file docker-compose.override.yml. Each build environment can have its own version of that file.
The build: web declaration doesn't belong into docker-compose.yml, as it's only supposed to run locally (and possibly on a build server), not in production.
Therefore, in the example above, this is what docker-compose.yml should look like:
version: '3'
services:
db:
image: "postgres"
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=mysecretpassword
web:
depends_on: [ db ]
ports:
- "80:80"
And this would be the default docker-compose.override.yml for local development:
version: '3'
services:
web:
build: web
Running docker-compose up --build -d will now build the latest code changes and launch our app locally.
There could also be another version docker-compose.override.build.yml, targeting a build/CI server:
version: '3'
services:
web:
build: web
image: mydockeruser/web
Running docker-compose -f docker-compose.yml -f docker-compose.override.build.yml push will build the latest code changes and push the image to its registry/repository.
Finally, there could be another version docker-compose.override.prod.yml:
version: '3'
services:
web:
image: mydockeruser/web
Deploying to production (just to a single Docker host, not a cluster) can now be as simple as copying over only docker-compose.yml and docker-compose.override.prod.yml and running docker-compose -f docker-compose.yml -f docker-compose.override.prod.yml up -d.
The correct way to do it (i.e. the way I do it :P) is to have different docker-compose files; for example, docker-compose.dev.yml and docker-compose.prod.yml. You can then push your production-ready image to a repository, say Docker Hub, and reference that image in docker-compose.prod.yml's web service. All the while you can use the dev docker-compose file (the one with the build option) for local development.
Also, in case you've thought about this, you cannot use env variables as keys in docker-compose (see here). So there is no way to conditionally set either image or build options.

Resources