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?
2
Answers
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
andtty
options, like thisYour 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.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.