I am trying to start my own container and link it with the official mysql container. I am using docker-compose to start both containers and link them together. My own container is supposed to be a regular LAMP-stack which runs a simple PHP application.
When I run docker-compose up, they both build properly, but when docker tries to run them, they just stop with the error code mytestservice_web_1 exited with code 0. I can not see any errors in the build log.
Here is my docker-compose.yml
web:
build: .
links:
- mysql
ports:
- "80:80"
mysql:
image: mysql:5.6
environment:
- MYSQL_ROOT_PASSWORD=verysecret
Here is my Dockerfile for my own container.
FROM linode/lamp
WORKDIR /var/www
RUN a2enmod rewrite
ADD . /var/www/mytestservice
ADD mytestservice.conf /etc/apache2/sites-enabled/
CMD service apache2 start
If I start them manually with docker run there are no problems.
How can I keep the containers running?
As mentioned in my comment above:
CMD exec /usr/sbin/apachectl -D FOREGROUND
Related
I took a repository tomcat8 image (entry point runs tomcat there) and added mysql to it (i.e. now i have an image with tomcat8/mysql).
Having a problem to create docker-compose.yaml which shall do the following:
get mysql to start along with tomcat8 on my new tomcat8/mysql image (i.e., instead of manually executing /etc/init.d/mysql start)
get the container to run other command-line switches i use with 'docker run':
docker run --rm -d --restart unless-stopped -p 80:8080 -p 443:8443 -v /DB:/DB tomcat8-mysql
get docker compose to run this docker-compose.yaml at server restart
Docker version 20.10.23, build 7155243
Ubuntu 22.04.1 LTS
I tried a few variations from documentation i am going through however still cannot find a way to succeed with all of the above. Any help will do.
Is it possible to combine [A] and [B] below?
[A] docker compose up -d
[B] docker exec -it [container_id] /etc/init.d/mysql start
My docker-compose.yaml
version: '3'
services:
tomcatmysql:
container_name: tomcatmysql
image: tomcat8https-mysql
ports:
- "80:8080" # tomcat http
- "443:8443" # tomcat https
- "13306:3306" # mysql
volumes:
- "/DB:/DB"
restart: unless-stopped
I am getting this message
nc command is missing and by doing some R&D, I got to know that in order to resolve this, (I think) I need to run below command in MySQL container in docker-compose
RUN apt-get -q update && apt-get -qy install netcat
But the issue is I don't have it's docker file else I could have written this command in docker file and might have called docker file from docker-compose
Does anyone have any idea how can I run this command from docker-compose?
Edit 1:
I have made separate the DockerFile for mysql which consists of
FROM mysql:8
RUN apt-get -q update && apt-get -qy install netcat
COPY wait-for.sh .
and then called this docker file from docker-compose which goes like this...
version: "3"
services:
mysql-standalone:
image: mysql:8.0.25
environment:
- MYSQL_ROOT_PASSWORD=********
- MYSQL_DATABASE=usermanagementappdp
ports:
- 3306:3306
depends_on: ['eureka-server']
build:
context: "./mysqlDockerFile2"
dockerfile: "Dockerfile"
volumes:
- ./wait-for:/docker-entrypoint-initdb.d
entrypoint: ["/docker-entrypoint-initdb.d/wait-for.sh", "eureka-server:8761", "--", "docker-entrypoint.sh"]
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
restart: always
environment:
PMA_HOST: mysql-standalone
PMA_USER: root
PMA_PASSWORD: root123M.
ports:
- 8085:80
eureka-server:
image: eureka-server
ports:
- 8761:8761
build:
context: "../Eureka-Server-For-User-Management-App"
dockerfile: "Dockerfile"
usermanagementapp-docker:
image: usermanagementapp-docker:latest
ports:
- 8089:8089
links:
- eureka-server
environment:
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-standalone:3306/usermanagementappdp?allowPublicKeyRetrieval=true&autoReconnect=true&useSSL=false
build:
context: "./"
dockerfile: "Dockerfile"
restart: on-failure
entrypoint: ["/wait-for.sh", "mysql-standalone:3306", "--", "['java','-jar','/app.jar']"]
depends_on: ['mysql-standalone','eureka-server']
Docker file for User management app is:
FROM openjdk:8
Add target/User-Management-App-0.0.1-SNAPSHOT.jar app.jar
VOLUME /tmp
EXPOSE 8089
RUN apt-get -q update && apt-get -qy install netcat
COPY wait-for.sh .
COPY target/User-Management-App-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Docker file for Eureka- server
FROM openjdk:8
EXPOSE 8761
ADD /target/Eureka-Server-For-User-Management-App-0.0.1-SNAPSHOT.jar netflix-eureka-server-1.0.jar
COPY wait-for.sh .
netflix-eureka-server-1.0.jar
ENTRYPOINT ["java","-jar","netflix-eureka-server-1.0.jar"]
Edit 2
I just edited mysql docker file to check if it is even getting executed or not
RUN echo "'Entered in docker file of mysql'"
FROM mysql:8
RUN apt-get -q update && apt-get -qy install netcat
COPY wait-for.sh .
RUN echo "'Exiting docker file of mysql'"
and found that on doing docker-compose up it is not echoing the text
You don't need to install netcat in the database server container. There are a couple of other things you can clean up to simplify this setup.
Let's start by thinking through what needs to happen when you run docker-compose up. The application container can't function until the database is up and running; for that, the application container is using the wait-for script, which in turn uses nc. The database itself doesn't need to make any outbound connections, though; it needs to start up and accept inbound connections so the rest of the system can proceed. So you don't need nc in the database server container, and you can just use the standard unmodified mysql image.
(In your Dockerfile you show the database depending on the Eureka service registry; but the database itself won't do anything to connect to it, and you're using a direct connection to the database from your application. It doesn't need to be part of this stack.)
Your Compose setup also overrides the image's entrypoint:. This shouldn't usually be necessary. I'd suggest a pattern where the image's ENTRYPOINT is a self-contained script that ends with a shell exec "$#" command, which will let it run the CMD passed to it as arguments. So that script could look something like
#!/bin/sh
# ./entrypoint.sh
# Set defaults for common environment variables
: ${MYSQL_PORT:=3306}
: ${MYSQL_DATABASE:=usermanagementappdp}
# Wait for the database to be ready
./wait-for.sh "$MYSQL_HOST:$MYSQL_PORT"
# Dynamically set the Spring database URL
export SPRING_DATASOURCE_URL="jdbc:mysql://$MYSQL_HOST:$MYSQL_PORT/$MYSQL_DATABASE?allowPublicKeyRetrieval=true&autoReconnect=true&useSSL=false"
# Run the main container command
exec "$#"
Then in your application's Dockerfile -- again, you don't need to change anything in the database's Dockerfile -- set this script as the ENTRYPOINT, and make your java -jar command the CMD.
FROM openjdk:8
# Install OS-level dependencies before COPYing anything in
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install --no-install-recommends --assume-yes \
netcat
# COPY in the actual application (don't usually ADD things)
WORKDIR /app
COPY target/User-Management-App-0.0.1-SNAPSHOT.jar app.jar
COPY wait-for.sh entrypoint.sh .
# Set metadata for how to run the application
EXPOSE 8089
ENTRYPOINT ["./entrypoint.sh"] # must be JSON-array syntax
CMD ["java", "-jar", "app.jar"]
Now in your docker-compose.yml setup you can get rid of most of the overrides. Run an unmodified mysql image and don't override the command: or entrypoint: of anything.
version: "3.8"
services:
mysql-standalone:
image: mysql:8.0.25
environment:
- MYSQL_ROOT_PASSWORD=********
- MYSQL_DATABASE=usermanagementappdp
ports:
- 3306:3306
phpmyadmin: { image: phpmyadmin/phpmyadmin, ... }
eureka-server:
build: ../Eureka-Server-For-User-Management-App
usermanagementapp-docker:
ports:
- 8089:8089
environment:
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka
MYSQL_HOST: mysql-standalone
build: .
restart: on-failure
depends_on: [mysql-standalone, eureka-server]
The setup you show above will contaminate your local copy of the MySQL image, so before you start, you should clean it up
docker pull mysql:8.0.25
If you need to do some sort of registration in the MySQL image at startup time, then you can follow this same basic approach. It is helpful to look up the Docker Hub mysql image page and from there its Dockerfile because you will need to know the original ENTRYPOINT and CMD.
In the ENTRYPOINT wrapper script, at the end, run the original entrypoint:
#!/bin/sh
# my-entrypoint.sh
...
exec docker-entrypoint.sh "$#" # running the original entrypoint
In your derived Dockerfile, you'll need to repeat the original CMD
FROM mysql:8.0.27
...
COPY wait-for.sh my-entrypoint.sh /usr/local/bin
ENTRYPOINT ["my-entrypoint.sh"]
CMD ["mysqld"]
In your Compose file, do not specify both image: mysql and a build: block. This will overwrite your local copy of the Docker Hub image with your custom build. For most purposes you can only specify build: and ignore image:. You do not need to use volumes: to inject code, that's contained within the custom Dockerfile.
services:
mysql-standalone:
build: ./mysql
# no image:
You could build and publish your own container image if you wanted with a dockerfile like this
FROM mysql:8
RUN apt-get -q update && apt-get -qy install netcat
and build it like docker build . -t user123/mysql:8
and push it like docker push user123/mysql:8
then switch your docker compose to use your custom container.
if you just need to pop in temporarily to install netcat, you can do that by doing
docker exec -it --user=root ContainerHashOrName /bin/bash where ContainerHashOrName can be retrieved from docker ps then just run your commands like you would on any other distro. Just be aware that you are only making changes to the specific instance of a container and that any rescheduling will bring up a different instance of the container.
You can use "build" option of compose file, https://docs.docker.com/compose/compose-file/compose-file-v3/#build and use your own Dockerfile starts with FROM mysql:8 and then install all additional stuff you need.
On Docker I already have a Laravel container and Container MySQL, how to connect the MySQL container and container Laravel on Docker?
This is what docker-compose was made for!
Check out this tutorial: https://docs.docker.com/compose/wordpress/
It's trying to do something similar: connect wordpress to mysql. The key is that both the docker containers defined in docker-compose.yml share the same network - and you can refer to each container by using their logical name. See how the WORDPRESS_DB_HOST environment variable is set to db:3306 - that will resolve to the IP of the mysql container within the docker network.
Basically, all containers must run in the same network.
# create your network
$ docker network create laravel
# start your container and link it to your network
$ docker run -d --network="laravel" --name="mysql01" mysql:8.0
# after your mysql is up and running, connect your second and third container like this
$ docker run -d --network="laravel" --name="latihananakit_web" yourimage:yourtag
$ docker run -d --network="laravel" --name="latihananakit_app" yourimage:yourtag
I'd recommend to use docker-compose for this scenario, because it makes the whole docker run-thing a lot easier.
See here for reference:
https://docs.docker.com/compose/
https://github.com/bitnami/bitnami-docker-laravel/blob/master/docker-compose.yml
TL;DR:
Create your docker-compose.yml like this (you may change environment-variables or other configuration upon your need):
version: '2'
services:
mariadb:
image: 'bitnami/mariadb:latest'
environment:
- ALLOW_EMPTY_PASSWORD=yes
- MARIADB_USER=my_user
- MARIADB_DATABASE=my_database
- MARIADB_PASSWORD=my_password
myapp:
tty: true
image: bitnami/laravel:5-debian-9
environment:
- DB_HOST=mariadb
- DB_USERNAME=my_user
- DB_DATABASE=my_database
- DB_PASSWORD=my_password
depends_on:
- mariadb
ports:
- 3000:3000
volumes:
- ./:/app
And get everything up and running by executing docker-compose up -d in the same directory.
I have the following yml file, the services are created correctly, but when installing wordpress I cannot logon to mysql and I need to understand why.
I'm totally new to docker, I'd need to see all the services together from command line (bash), now I'm running a command like
$ sudo docker exec -ti 4295b34c014a /bin/bash
but I get a login to a specific service, how can I view wordpress and mysql together from cli?
yml file (from here):
version: '3.1'
services:
adminer:
image: adminer
ports:
- '8080:8080'
db:
image: mysql
volumes:
- 'wptut:/var/lib/mysql'
environment:
MYSQL_ROOT_PASSWORD: mysqlpassword
wordpress:
image: wordpress
ports:
- '81:80'
volumes:
wptut: null
I'm not sure what you mean by viewing them together, but in order to check if they are running you can use docker ps and if you want to see the logs after you docker-compose up -d use docker-compose logs -f. You should also make sure in WordPress you are referencing your MySQL database properly. For hostname, you should probably use db instead of localhost
Each service is running in a separate container. If you want log access, docker-compose up should stream logs from all three by default. If you detached from the docker-compose up session I think docker-compose logs -f should also combine log output of all services. docker-compose exec attaches to a running container, you can only do that to one container at a time. At the very least you can run docker-compose exec wordpress or another service name as a convenience over the direct docker command you have above. docker-compose logs -f wordpress also works for a one-off.
I am learning docker and I created a MySQL container with a persistent database using volumes and I want to connect to the MySQL container from the web container during the docker-compose up --build procedure.
The problem is that the connection always fail during that time. I can only access the MySQL container after everything is finished.
The line RUN mysql -uroot -pmy-root-password -hdatabase in the build/web-server/docker-compose.ymlfile below, always fail.
How can I accomplish this?
docker-compose.yml
version: '3'
services:
database:
container_name: kadu-database
build:
context: build/database
dockerfile: Dockerfile
web-server:
container_name: kadu-web-server
links:
- database
depends_on:
- database
build:
context: build/web-server
dockerfile: Dockerfile
build/database/docker-compose.yml
FROM mariadb:5.5
ARG MYSQL_DATABASE
ARG MYSQL_ROOT_PASSWORD
RUN apt-get update
RUN apt-get install patch --assume-yes
build/web-server/docker-compose.yml
FROM ubuntu:16.04
ARG WEB_USERNAME
ARG MYSQL_DATABASE
ARG MYSQL_ROOT_PASSWORD
RUN apt-get update --quiet=2 && apt-get install mariadb-client --quiet=2
RUN mysql -uroot -pmy-root-password -hdatabase
Working with docker includes 2 steps:
building a image
creating container based on image and running this container
The point is you mysql client can connect to server only on second step.
Dockerfile "executes" while you build image. In this time you don't have any containers, therefore you can't connect to them.
You need move command RUN mysql -uroot -pmy-root-password -hdatabase
from Dockerfile to entrypoint.sh