I made a PHP app and want to make a Docker image out of it.
For my app to work, I need PHP-apache, MySQL, and PhpMyAdmin.
When I run docker-compose up, everything works fine.
So, I did docker ps -a and got:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa19aa03b658 docker2-php-apache-environment "docker-php-entrypoi…" 9 minutes ago Up 26 seconds 0.0.0.0:8000->80/tcp php-apache
cd6a1d03c74c phpmyadmin/phpmyadmin "/docker-entrypoint.…" 9 minutes ago Up 26 seconds 0.0.0.0:8080->80/tcp docker2-phpmyadmin-1
ff13a69f0fde mysql "docker-entrypoint.s…" 9 minutes ago Up 27 seconds 33060/tcp, 0.0.0.0:9906->3306/tcp db
I want to push my project to Docker Hub, but I am not sure how to do it.
When I commit and push docker2-php-apache-environment(fa19aa03b658) and pull the image on a different machine, I am missing MySql and PhpMyAdmin.
Is it possible to push the whole project so that when somebody pulls and runs the image, everything works?
I made docker-compose.yml which looks like this:
version: '3.8'
services:
php-apache-environment:
container_name: php-apache
build:
context: ./php
dockerfile: Dockerfile
depends_on:
- db
volumes:
- ./php/src:/var/www/html/
ports:
- 8000:80
db:
container_name: db
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 12345
MYSQL_DATABASE: turisticka_agencija
ports:
- "9906:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- '8080:80'
restart: always
environment:
PMA_HOST: db
depends_on:
- db
Dockerfile looks like this:
FROM php:8.0-apache
RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli
RUN apt-get update && apt-get upgrade -y
# Install build dependencies and the OPcache extension
RUN apk add --no-cache $PHPIZE_DEPS \
&& docker-php-ext-install opcache \
&& apk del $PHPIZE_DEPS
# Copy the opcache.ini into your Docker image
COPY opcache.ini /usr/local/etc/php/conf.d/opcache.ini
# Run your application
CMD php-fpm
Related
Well, basically I got this docker-compose.yml:
version: "3.9"
services:
# Database
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
- ./schemas/mysql.sql:/data/application/init.sql
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123
MYSQL_ROOT_HOST: 10.5.0.1
MYSQL_DATABASE: forgottenserver
MYSQL_PASSWORD: 123
command: --init-file /data/application/init.sql
networks:
tibia:
ipv4_address: 10.5.0.5
# phpmyadmin
phpmyadmin:
depends_on:
- db
image: phpmyadmin
restart: always
ports:
- "8090:80"
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: 123
networks:
tibia:
ipv4_address: 10.5.0.3
networks:
tibia:
driver: bridge
ipam:
config:
- subnet: 10.5.0.0/16
gateway: 10.5.0.1
volumes:
db_data:
and this Dockerfile:
FROM ubuntu:20.04#sha256:bffb6799d706144f263f4b91e1226745ffb5643ea0ea89c2f709208e8d70c999
ENV TZ=America/Sao_Paulo
ENV WD=/home/tibia/server
ARG DEBIAN_FRONTEND=noninteractive
RUN useradd --system --create-home --shell /bin/bash --gid root --groups sudo --uid 1001 tibia
RUN apt-get update -y && \
apt-get upgrade -y && \
apt-get install --no-install-recommends -y tzdata \
autoconf automake pkg-config build-essential cmake \
liblua5.1-0-dev libsqlite3-dev libmysqlclient-dev \
libxml2-dev libgmp3-dev libboost-filesystem-dev \
libboost-regex-dev libboost-thread-dev
USER tibia
WORKDIR $WD
COPY . .
RUN mv config.lua.dist config.lua && \
mkdir build && \
cd build && \
cmake .. && \
make -j$(grep processor /proc/cpuinfo | wc -l)
EXPOSE 7171 7172
CMD ["/bin/bash"]
The Dockerfile is just building an executable.
The problem is that if I add this to the compose file and try to run all those services, the one that uses the Dockerfile just exits and doesn't restart:
# ...
services:
server:
build: .
ports:
- "7171:7171"
- "7172:7172"
networks:
tibia:
ipv4_address: 10.5.0.4
But if I run the compose with just the services db and phpmyadmin, and then run manually my built image from Dockerfile using:
docker run -itd --network=3777_tibia --ip 10.5.0.4 -p 7171:7171 -p 7172:7172 3777_server
Then it works like a charm!!!! Even the network does work.
Some screenshots of my Docker Desktop:
How can I make this missing service work with the docker-compose file?
NEW EDIT:
image of the logs:
Your dockerfile specifies bash as the command to run.
When you run it via the docker-compose file, bash sees that there's no TTY and it exits immediately and the container stops.
When you run it from the command line, you attach a TTY using the -it options. Bash then runs interactively and waits for input.
To get your container to run interactively when run from docker-compose, you need to add stdin_open and tty options, like this
services:
server:
build: .
ports:
- "7171:7171"
- "7172:7172"
stdin_open: true
tty: true
networks:
tibia:
ipv4_address: 10.5.0.4
Your Dockerfile specifies bash as the command to run. It doesn't actually run the program you built. Since Compose is oriented towards running multiple long-running service-type containers, it's tricky to interact with an interactive shell as the main container process. You also don't usually want to start a container, then start the thing the container does; you just want to start the container and have it run the process.
Once you've built the program, set the image's CMD to run it.
CMD ["./the_program"]
With a typical C(++) program built using Make, you should be able to make install it into /usr/local where you can run it without specifying a path explicitly. You could combine this with a multi-stage build to get a much smaller image without any of the build tools or header files.
I have a setup where I have a Dockerfile and a docker-compose.yml.
Dockerfile:
# syntax=docker/dockerfile:1
FROM php:7.4
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
RUN docker-php-ext-install mysqli pdo pdo_mysql
RUN apt-get -y update
RUN apt-get -y install git
COPY . .
RUN composer install
YML file:
version: '3.8'
services:
foo_db:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=foo
- MYSQL_DATABASE=foo
foo_app:
image: foo_php
platform: linux/x86_64
restart: unless-stopped
ports:
- 8000:8000
links:
- foo_db
environment:
- DB_CONNECTION=mysql
- DB_HOST=foo_db
- DB_PORT=3306
- DB_PASSWORD=foo
command: sh -c "php artisan serve --host=0.0.0.0 --port=8000"
foo_phpmyadmin:
image: phpmyadmin
links:
- foo_db
environment:
PMA_HOST: foo_db
PMA_PORT: 3306
PMA_ARBITRARY: 1
PMA_USER: root
PMA_PASSWORD: foo
restart: always
ports:
- 8081:80
In order to set this up on a new workstation the steps I am taking are first running:
docker build -t foo_php .
As I understand it this runs the commands in the Dockerfile and creates a new image called foo_php.
Once that is done I am running docker compose up.
Question:
How can I tell docker that I would like my foo_app image to be automatically built, so that I can skip the step of first building the image. Ideally I would have one command similar to docker compose up that I could call each time I want to launch my containers. The first time it would build the images it needs including this custom image of mine described in the Dockerfile, and subsequent times calling it would just run these images. Does a method to achieve this exist?
You can ask docker compose to build the image every time:
docker compose up --build
But you need to also instruct docker compose on what to build:
foo_app:
image: foo_php
build:
context: .
where context points to the folder containing your Dockerfile
I have a web server program which requires pdf files from owncloud server. I'm making installation code via docker-compose & docker hub.
I use Ubuntu 20.04LTS and Docker Compose v2.1.0.
Here is the process
store pdf files and create public links in owncloud docker container(under /var/www/owncloud/data)
create new images(both owncloud, mariadb) and tags from container by code below
docker commit 5cba8bf76904
docker tag 9315184e23f5 DOCKERID/docker-mariadb
docker push DOCKERID/docker-mariadb
pull those images in another new fresh Ubuntu server, using docker-compose up
After this process, when I connect to owncloud, running on a new fresh ubuntu server, there are no pdf files and all those configs are intialized (owncloud account, mariadb database configs)
and the owncloud start-up page(config admin account and database page) is opened.
My docker-compose, Dockerfiles are below(related parts only)
docker-compose.yml
owncloud:
#build: ./dockerfiles/owncloud/
image: "dockerhubid/docker-owncloud"
container_name: chatbot_owncloud
restart: always
networks:
- chatbot_network
depends_on:
- mariadb
volumes:
- 'owncloud_php:/var/www/owncloud'
command: php-fpm7.4 -F -R
mariadb:
# build: ./dockerfiles/mariadb/
image: dockerhubid/docker-mariadb
container_name: mariadb
restart: always
expose:
- '3306'
networks:
- chatbot_network
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=owncloud
- MYSQL_PASSWORD=password
- MYSQL_DATABASE=owncloud
command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
nginx:
#build: ./dockerfiles/nginx/
image: "dockerhubid/docker-nginx"
container_name: chatbot_nginx
restart: always
depends_on:
- owncloud
volumes:
- ./dockerfiles/certbot/conf:/etc/letsencrypt
- ./dockerfiles/certbot/www:/var/www/certbot
volumes_from:
- 'owncloud:ro'
networks:
- chatbot_network
ports:
- '80:80'
- '3000:3000'
- '8883:8883'
- '8884:8884'
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
certbot:
image: certbot/certbot
container_name: chatbot_certbot
networks:
- chatbot_network
volumes:
- ./dockerfiles/certbot/conf:/etc/letsencrypt
- ./dockerfiles/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
owncloud Dockerfile
FROM ubuntu:20.04
EXPOSE 9000
ARG DEBIAN_FRONTEND=noninteractive
# dependencies
RUN apt update && apt upgrade -y
RUN apt install -y php-bz2 php-curl php-gd php-imagick php-intl php-mbstring php-xml php-zip php-mysql php-fpm wget zip vim
# owncloud
RUN wget https://download.owncloud.org/community/owncloud-10.5.0.zip
RUN unzip owncloud-10.5.0.zip -d /var/www/
RUN rm /owncloud-10.5.0.zip
WORKDIR /var/www/owncloud
RUN chown www-data:www-data -R /usr/bin/php /var/www/owncloud/
RUN chmod -R 755 /var/www/owncloud/
# php-fpm setup
RUN sed -i 's+/run/php/php7.4-fpm.sock+9000+g' /etc/php/7.4/fpm/pool.d/www.conf
ADD init.sh /docker-entrypoint-initdb.d/
RUN chmod 755 /docker-entrypoint-initdb.d/init.sh
mariadb Dockerfile
from mariadb:10.5
EXPOSE 3306
ARG DEBIAN_FRONTEND=noninteractive
USER root
ADD init.sql /docker-entrypoint-initdb.d/
RUN chmod 755 /docker-entrypoint-initdb.d/init.sql
How can I maintain those files and public links?
Why are those things removed after docker hub push&pull?
I tried it with the owncloud official image first, but by my investigation official image stores data in external docker volume.
I thought that's why my data is gone after docker push&pull.
so I'm trying it by manual installation.
I am using this repo to set up a local wordpress development environment:
https://github.com/mjstealey/wordpress-nginx-docker#tldr
I hijacked the docker-compose to change the nginx port, but also to try to install openssl and vim on the nginx server. But when I do a docker-compose up the nginx server never starts properly.
This is what i see:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57cf3dff059f nginx:latest "bash" About a minute ago Restarting (0) 14 seconds ago nginx
I tried to reference a Dockerfile inside the docker-compose like this:
nginx:
image: nginx:${NGINX_VERSION:-latest}
container_name: nginx
ports:
- '8085:8085'
- '443:443'
build: .
volumes:
- ${NGINX_CONF_DIR:-./nginx}:/etc/nginx/conf.d
- ${NGINX_LOG_DIR:-./logs/nginx}:/var/log/nginx
- ${WORDPRESS_DATA_DIR:-./wordpress}:/var/www/html
- ${SSL_CERTS_DIR:-./certs}:/etc/letsencrypt
- ${SSL_CERTS_DATA_DIR:-./certs-data}:/data/letsencrypt
depends_on:
- wordpress
restart: always
Notice the line that says "build: .".
Here's the contents of my Dockerfile:
FROM debian:buster-slim
RUN apt-get update
# installing vim isn't necessary. but just handy.
RUN apt-get -y install openssl
RUN apt-get -y install vim
Clearly, I'm doing something wrong. Maybe I should be defining tasks directly in the docker-compose for the nginx server?
I wanted to find a way to make a clean separation between our customizations and the original code. But maybe this isn't possible.
Thanks
EDIT 1
This is what the Dockerfile looks like:
FROM nginx:latest
RUN apt-get update
&& apt-get -y install openssl
&& apt-get -y install vim
And the nginx section of the docker-compose.yml:
nginx:
#image: nginx:${NGINX_VERSION:-latest}
container_name: nginx
ports:
- '8085:8085'
- '443:443'
build: .
volumes:
- ${NGINX_CONF_DIR:-./nginx}:/etc/nginx/conf.d
- ${NGINX_LOG_DIR:-./logs/nginx}:/var/log/nginx
- ${WORDPRESS_DATA_DIR:-./wordpress}:/var/www/html
- ${SSL_CERTS_DIR:-./certs}:/etc/letsencrypt
- ${SSL_CERTS_DATA_DIR:-./certs-data}:/data/letsencrypt
depends_on:
- wordpress
restart: always
I think you maybe need to change the base image that you are using in the docker file?:
FROM nginx:latest
Then in the docker file, because you are creating your own customised version of nginx image, you should either give custom name or tag.
Preliminary Info
I have a docker-compose file that describes two services, one built from a dockerhub mysql image and the other built from a dockerhub node alpine image. The docker-compose.yml is as follows:
version: "3.8"
services:
client:
image: node:alpine
command: sh -c "cd server && yarn install && cd .. && yarn install && yarn start"
ports:
- "3000:3000"
working_dir: /portal
volumes:
- ./:/portal
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: password
MYSQL_DB: files
mysql:
image: mysql:5.7
volumes:
- yaml-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: files
volumes:
yaml-mysql-data:
Current Understanding
I'm trying to deploy my app using kubernetes, but a kubernetes .yml file requires that I provide a path to my container images on dockerhub. However, I don't have them on dockerhub. I'm not sure how to push my images as they are built from the mysql and node images that I pull.
I know that docker-compose push can be used, however it's for locally built images; whereas I'm pulling images from dockerhub and am providing specific instructions in my docker-compose.yml when spinning them up.
Question
How can I push these images including the commands that should be run; e.g. command: sh -c "cd server && yarn install && cd .. && yarn install && yarn start"? (which is on line 5 of docker-compose.yml above)
Thanks
The logic that you put in the docker-compose.yml actually belongs with a Dockerfile. So create a Dockerfile for your nodejs applications (there are plenty of examples for this).
Then in your docker-compose.yml you build your own image that you can then push to a registry.
version: "3.8"
services:
client:
image: your_registry/your_name:some_tag
build: .
ports: ...
environment: ....