0

I would like to link three services together (db, nginx, and web service) under a bridge network and be able to poke at the different services from my localhost or from inside the container, and have an interactive terminal for the web service. How can I achieve this?

My docker-compose configuration is the following:

version: '2'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile-alpine
    command: /bin/bash
    ports:
      - "5000:5000"
    volumes:
      - $REPO_DIR:/repository
    links:
      - db
      - nginx
  nginx:
    image: nginx:stable-alpine
    ports:
      - "8080:8080"
    volumes:
      - $NGINX_STATIC_DIR:/var/www/static
      - $NGINX_CONFIG_FILE:/etc/nginx/nginx.conf
  db:
    image: mysql/mysql-server
    ports:
      - "3307:3306"
    environment:
      MYSQL_USER: $MYSQL_USER
      MYSQL_PASSWORD: $MYSQL_PASSWORD
      MYSQL_DATABASE: $MYSQL_DATABASE
      MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
    volumes:
      - $DB_DATA_DIR:/var/lib/mysql
      - $DB_LOG_DIR:/var/log/mysql

where the web service is using the mhart/alpine-node:6.7.0 as a base and further adds some utilities plus Python3.5 and Flask.

If I do docker-compose run web, I get access to an interactive terminal, but the db and nginx services are not booted/linked properly. I get the following output:

Starting courseadmin_nginx_1
Starting courseadmin_db_1
bash-4.3#

And then further network forensics from inside the container turns up that neither nginx or db are present. I can further support this claim since using docker-compose up actually created a port conflict for the db service granted that I have mysql installed on my host system, thing it never reported with docker-compose run.

On the other hand, if I try docker-compose up, I get a much more active trace, but no interactive terminal:

Starting courseadmin_nginx_1
Recreating courseadmin_db_1
Recreating courseadmin_web_1
Attaching to courseadmin_nginx_1, courseadmin_db_1, courseadmin_web_1
db_1     | Initializing database
courseadmin_web_1 exited with code 0
db_1     | Database initialized
db_1     | MySQL init process in progress...
db_1     | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
db_1     | Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
db_1     | mysql: [Warning] Using a password on the command line interface can be insecure.
db_1     | mysql: [Warning] Using a password on the command line interface can be insecure.
db_1     | mysql: [Warning] Using a password on the command line interface can be insecure.
db_1     | mysql: [Warning] Using a password on the command line interface can be insecure.
db_1     | 
db_1     | /entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
db_1     | 
db_1     | 
db_1     | MySQL init process done. Ready for start up.
db_1     | 

What can I do to achieve an interactive terminal and proper linking of my three containers?

Philippe Hebert
  • 1,616
  • 2
  • 24
  • 51

1 Answers1

1

I'm not entirely certain I fully understood your question, so I will try to answer the part I can:

At first glance, your docker-compose.yml file looks fine, and the correct running of the docker-compose up command seems to confirm this. However, you specify version: '2'. From the docker-compose docs, from Version 2 on, linking is implicitly done by docker-compose itself (I'll add the links in the comments as I don't have enough reputation). This means you can remove the links: part (unless you seek to explicitly specify these aliases, in which case you can disregard this part). I thought a great resource explaining the difference between V1 and V2 was this (he covers links in step 2 of the post), but you can of course also check the docker-compose docs.

For the rest, my suggestions:

  • docker-compose up -d will run everything in detached mode. Docker compose will take care of the implicit linking, as long as you have those correctly configured. For more details on inter-container networking with docker-compose, this was a great resource for me. The real stuff on docker-compose starts in section 3.3 of that page.
  • Once everything is up and running, docker ps -a will show you the active containers
  • To start an 'interactive terminal', just do docker exec -it $container_id bash if I recall correctly. This will start a terminal, in that container. exec executes a command in the specified container, while the i flag starts an 'interactive' terminal, the t flag specifies the TTY layer, and bash the type of shell.

If I could add an additional recommendation, add the depends_on: class in your web configuration. This will make your web container wait for both the SQL and Nginx to have fully started. Like so:

services:
  web:
    [...]
    depends_on:
      - nginx
      - db
d00bsm3n
  • 93
  • 6
  • The `docker-compose` docs I keep talking about can be found here, specifically the part about `links`: https://docs.docker.com/compose/networking/#/links – d00bsm3n Oct 08 '16 at 19:49
  • Great post! It definitely helps me a lot to progress. However I can't do the docker exec -ti $container_id because my web container keeps dying since the /bin/bash doesn't have anything to do. Is there any way I can keep it alive without passing any entrypoint? – Philippe Hebert Oct 08 '16 at 21:07
  • 1
    Just in case you're not clear on **why** your `web` container dies, see [here](http://stackoverflow.com/a/28214133/6942595). For the rest, could you detail a little more in your OP what you're trying to attain with your `web` service? To me it seems you could simply do `image: alpine` and it will set up a container into which you can then start a shell with `exec`? – d00bsm3n Oct 08 '16 at 21:20
  • 1
    Ah, I think I misunderstood. To run your alpine container, as per [this](http://stackoverflow.com/a/30209974/6942595) answer, just do `command: tail -f /dev/null` to keep the container running. – d00bsm3n Oct 08 '16 at 21:39
  • Great! This allowed to solve my issue. It's unfortunate that small details like that are not as well documented as the rest of the docker documentation – Philippe Hebert Oct 08 '16 at 21:55