Can docker write logs to an external directory? - docker

We have written our own logger that writes about 10 different log files: skl log, http request log, a separate log for each client, etc.
If you run the service through docker, is it possible to tell him to write these logs not inside himself, but in an external folder?
From what I've read, I've only realized so far that docker only logs output to the console, and in one shared file.

You can run a docker container with volumes where you can mention your expected log directory, settings file, app resource, etc.
Here is the straightforward way to create the docker container with volumes
docker create --name YOUR_SERVICE_NAME -p 80:80 -v /APP_DIR_OUT_SIDE_OF_CONTAINER/settings/appsettings.json:/app/appsettings.json -v /APP_DIR_OUT_SIDE_OF_CONTAINER/Logs:/app/Logs:z YOUR_DOCKER_IMAGE_REPO_URL:IMAGE_TAG
Below is the docker-compose sample that should be running a container with volumes.
version: '3.4'
services:
YOUR_SERVICE_NAME:
image: IMAGE_URL
container_name: CONTAINER_NAME
ports:
- "80:80"
volumes:
- /APP_DIR_OUT_SIDE_OF_CONTAINER/config/appsettings.json:/app/appsettings.json
- /APP_DIR_OUT_SIDE_OF_CONTAINER/logs:/app/Logs:z
restart: always
Also, you can get all possible ways to run the docker container with volumes from Use volumes

Related

Sharing data between docker containers without making data persistent

Let's say I have a docker-compose file with two containers:
version: "3"
services:
app:
image: someimage:fpm-alpine
volumes:
- myvolume:/var/www/html
web:
image: nginx:alpine
volumes:
- myvolume:/var/www/html
volumes:
myvolume:
The app container contains the application code in the /var/www/html directory which gets updated with each version of the image, so I don't want this directory to be persistent.
Yet I need to share the data with the nginx container. If I use a volume or a host bind the data is persistent and doesn't get updated with a new version. Maybe there is a way to automatically delete a volume whenever I pull a new image? Or a way to share an anonymous volume?
i think its better for you to use anonymous volume
volumes:
- ./:/var/www/html
You would have to be willing to drop back to docker-compose version 2 and use data containers with the volumes_from directive.
Which is equivalent to --volumes-from on a docker run command.
This should work fine. The problem isn't with docker. You can use volumes to communicate in this way. If you run docker-compose up in a directory with the following compose file:
version: "3"
services:
one:
image: ubuntu
command: sleep 100000
volumes:
- vol:/vol
two:
image: ubuntu
command: sleep 100000
volumes:
- vol:/vol
volumes:
vol:
Then, in a 2nd terminal docker exec -it so_one_1 bash (you might have to do a docker ps to find the exact name of the container, it can change). You'll find yourself in a bash container. Change to the /vol directory cd /vol and then echo "wobble" > wibble.txt", then exit` the shell (ctrl-d).
In the same terminal you can then type docker exec -it so_two_1 bash (again, check the names). Just like last time you can cd /vol and type ls -gAlFh you'll see the wibble.txt file we created in the other container. You can even cat wibble.txt to see the contents. It'll be there.
So if the problem isn't docker, what can it be? I think the problem is that nginx isn't seeing the changes on the filesystem. For that, I believe that setting expires -1; inside a location block in the config will actually disable caching completely and may solve the problem (dev only).

Traefik config file location using docker

Traefik's Getting Started guid is difficult to follow in any step by step fashion. It has the following problems:
Getting Started suggests running traefik as a command, but no commands can be run on the traefik image and you must instead use traefik:alpine, even to shell into the container with docker exec -it ....
Getting Started makes hardly any mention of a traefik.toml file.
#1 makes a new reader confused as to weather traefik is intended to be run as a container that automatically updates per newly deployed containers like jwilder's nginx proxy or if it's intended to be run on a docker host.
Their original docker-compose.yml file looks like this:
version: '3'
services:
reverse-proxy:
image: traefik # The official Traefik docker image
command: --api --docker #--consul --consul.endpoint=127.0.0.1:8500 # Enables the web UI and tells Traefik to listen to docker
ports:
- "80:80" # The HTTP port
- "8080:8080" # The Web UI (enabled by --api)
volumes:
- /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
whoami:
image: containous/whoami # A container that exposes an API to show its IP address
labels:
- "traefik.frontend.rule=Host:whoami.docker.localhost"
Then you can run it with:
docker-compose up -d reverse-proxy
This is fine and you can add new services here and specify new labels like the one above, i.e. traefik.frontend.rule=Host:whoami-other.docker.localhost.
You can test this with curl, specifying the host heading like so:
curl -H Host:whoami.docker.localhost http://127.0.0.1
Issue 1)
Line 5 must be changed to use the image traefik:alpine.
image: traefik:alpine # The official Traefik docker image
You can now actually docker exec this container. You can only use sh (not /bin/bash) on the alpine image. We can now do the following:
docker exec -it traefik_reverse-proxy_1 sh
docker exec -it traefik_reverse-proxy_1 traefik --help
Issue 2)
From the default docker-compose.yml, there is no mention of a traefik.toml file. Even if I docker-compose up -d [some_new_service] and can reach those services, shelling into the container has no traefik.toml file. It's nowhere in the container, despite that per the bottom of Basics, it says looks for it default locations such as /etc/traefik/ and $HOME/.traefik/ and . or the working directory. Is this referring to the host or the container? In the container I run grep find and only see the binary:
/ # find / | grep traefik
/usr/local/bin/traefik
Is traefik storing my services configuration in memory?
The next logical page in the documentation (Basics), immediately starts detailing configuration of the traefik.toml, but I have to such file to experiment with.
I had to to back to Getting Started read at the bottom of that page to find that using a static traefik.toml file must be specified in a volume when they suggest using their official image and running like this:
docker run -d -p 8080:8080 -p 80:80 -v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik
So with this, I change the volumes section in the original docker-compose.yml under the service reverse-proxy to use something similar:
volumes:
- /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
- $PWD/traefik.toml:/etc/traefik/traefik.toml
Even with this, I don't have a base traefik.toml file to even use (there isn't even one in the examples folder of their GitHub). I had to go find one, but wasn't even sure how it would apply to the existing configuration of services I had running (i.e. whoami and/or whoami-other). Finally, running find / | grep traefik on the container shows the same traefik.toml file in /etc/traefik/traefik.toml, but it has no mention of the services (which I can still reach with curl -H Host:whoami.docker.localhost http://127.0.0.1 from my docker host). Where is the configuration then?
It is here
https://raw.githubusercontent.com/containous/traefik/v2.0/traefik.sample.toml
Somehow the traefik documents is confusing for newbie (I am).

Start particular service from docker-compose

I am new to Docker and have docker-compose.yml which is containing many services and iI need to start one particular service. I have docker-compose.yml file with information:
version: '2'
services:
postgres:
image: ${ARTIFACTORY_URL}/datahub/postgres:${BUILD_NUMBER}
restart: "no"
volumes:
- /etc/passwd:/etc/passwd
volumes_from:
- libs
depends_on:
- libs
setup:
image: ${ARTIFACTORY_URL}/setup:${B_N}
restart: "no"
volumes:
- ${HOME}:/usr/local/
I am able to call docker-compose.yml file using command:
docker-compose -f docker-compose.yml up -d --no-build
But I need to start "setup service" in docker-compose file:
How can I do this?
It's very easy:
docker compose up <service-name>
In your case:
docker compose -f docker-compose.yml up setup -d
To stop the service, then you don't need to specify the service name:
docker compose down
will do.
Little side note: if you are in the directory where the docker-compose.yml file is located, then docker-compose will use it implicitly, there's no need to add it as a parameter.
You need to provide it in the following situations:
the file is not in your current directory
the file name is different from the default one, eg. myconfig.yml
As far as I understand your question, you have multiple services in docker-compose but want to deploy only one.
docker-compose should be used for multi-container Docker applications. From official docs :
Compose is a tool for defining and running multi-container Docker
applications.
IMHO, you should run your service image separately with docker run command.
PS: If you are asking about recreating only the container whose image is changed among the multiple services in your docker-compose file, then docker-compose handles that for you.

How to configure a dockerfile and docker-compose for Jenkins

Im absolutely new in Docker and Jenkins as well. I have a question about the configuration of Dockerfile and docker-compose.yml file. I tried to use the easiest configuration to be able to set-up these files correctly. Building and pushing is done correctly, but the jenkins application is not running on my localhost (127.0.0.1).
If I understand it correctly, now it should default running on port 50000 (ARG agent_port=50000 in jenkins "official" Dockerfile). I tried to use 50000, 8080 and 80 as well, nothing is working. Do you have any advice, please? Im using these files: https://github.com/fdolsky321/Jenkins_Docker
The second question is, whats the best way to handle the crashes of the container. Lets say, that if the container crashes, I want to recreate a new container with the same settings. Is the best way just to create a new shell file like "crash.sh" and provide there the information, that I want to create new container with the same settings? Like is mentioned in here: https://blog.codeship.com/ensuring-containers-are-always-running-with-dockers-restart-policy/
Thank you for any advice.
docker-compose for Jenkins
docker-compose.yml
version: '2'
services:
jenkins:
image: jenkins:latest
ports:
- 8080:8080
- 50000:50000
# uncomment for docker in docker
privileged: true
volumes:
# enable persistent volume (warning: make sure that the local jenkins_home folder is created)
- /var/wisestep/data/jenkins_home:/var/jenkins_home
# mount docker sock and binary for docker in docker (only works on linux)
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
Replace the port 8080, 50000 as you need in your host.
To recreate a new container with the same settings
The volumne mounted jenkins_home, is the placewhere you store all your jobs and settings etc..
Take the backup of the mounted volume jenkins_home on creating every job or the way you want.
Whenever there is any crash, run the Jenkins with the same docker-compose file and replace the jenkins_home folder with the backup.
Rerun/restart jenkins again
List the container
docker ps -a
Restart container
docker restart <Required_Container_ID_To_Restart>
I've been using a docker-compose.yml that looks like the following:
version: '3.2'
volumes:
jenkins-home:
services:
jenkins:
image: jenkins-docker
build: .
restart: unless-stopped
ports:
- target: 8080
published: 8080
protocol: tcp
mode: host
volumes:
- jenkins-home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
container_name: jenkins-docker
My image is a locally built Jenkins image, based off of jenkins/jenkins:lts, that adds in some other components like docker itself, and I'm mounting the docker socket to allow me to run commands on the docker host. This may not be needed for your use case. The important parts for you are the ports being published, which for me is only 8080, and the volume for /var/jenkins_home to preserve the Jenkins configuration between image updates.
To recover from errors, I have restart: unless-stopped inside the docker-compose.yml to configure the container to automatically restart. If you're running this in swarm mode, that would be automatic.
I typically avoid defining a container name, but in this scenario, there will only ever be one jenkins-docker container, and I like to be able to view the logs with docker logs jenkins-docker to gather things like the initial administrator login token.
My Dockerfile and other dependencies for this image are available at: https://github.com/bmitch3020/jenkins-docker
HyperV with docker for Windows.
In that case, you must be sure you port-forward any published port (like 5000).
Open HyperV manager, and right-click on the machine defined there: you will be able to add port-forwarding rules in order for localhost:5000 to access your VM:5000.

How to sync code between container and host using docker-compose?

Until now, I have used a local LAMP stack to develop my web projects and deploy them manually to the server. For the next project I want to use docker and docker-compose to create a mariaDB, NGINX and a project container for easy developing and deploying.
When developing I want my code directory on the host machine to be synchronised with the docker container. I know that could be achieved by running
docker run -dt --name containerName -v /path/on/host:/path/in/container
in the cli as stated here, but I want to do that within a docker-compose v2 file.
I am as far as having a docker-composer.yml file looking like this:
version: '2'
services:
db:
#[...]
myProj:
build: ./myProj
image: myProj
depends_on:
- db
volumes:
myCodeVolume:/var/www
volumes:
myCodeVolume:
How can I synchronise my /var/www directory in the container with my host machine (Ubuntu desktop, macos or Windows machine)?
Thank you for your help.
It is pretty much the same way, you do the host:container mapping directly under the services.myProj.volumes key in your compose file:
version: '2'
services:
...
myProj:
...
volumes:
/path/to/file/on/host:/var/www
Note that the top-level volumes key is removed.
This file could be translated into:
docker create --links db -v /path/to/file/on/host:/var/www myProj
When docker-compose finds the top-level volumes section it tries to docker volume create the keys under it first before creating any other container. Those volumes could be then used to hold the data you want to be persistent across containers.
So, if I take your file for an example, it would translate into something like this:
docker volume create myCodeVolume
docker create --links db -v myCodeVoume:/var/www myProj

Resources