-3

I have the following docker-compose.yml file:

docker-compose.staging.yml:

version: '3.7'

services:
  web:
    restart: always
    build: ./django
    expose:
      - "8000"
    volumes:
      - django-static:/usr/src/app/static
      - django-uploads:/usr/src/app/uploads
    environment:
      DJANGO_POSTGRES_REMOTE: 'True'
      DJANGO_POSTGRES_HOST: myservername.postgres.database.azure.com
      DJANGO_POSTGRES_PORT: '1234'
      DJANGO_POSTGRES_NAME: dbname
      DJANGO_POSTGRES_USER: dbuser
      DJANGO_POSTGRES_PASS: dbpassword
      DJANGO_SECRET_KEY: 
      DJANGO_DEBUG: 1
      DJANGO_TESTING: 0
      DJANGO_WAVE_API_VERSION: '1'
      DJANGO_WAVE_SUPERUSER_USERNAME: ''
      DJANGO_WAVE_SUPERUSER_PASSWORD: ''
      DJANGO_WAVE_SUPERUSER_EMAIL: ''
      DJANGO_BUGSNAG_LOGGING_ENABLED: 0
      DJANGO_BUGSNAG_API_KEY: ''
      DJANGO_ROOT_DOMAIN: ''
      DJANGO_MEMCACHED_ON: 'False'
      VUE_ROOT_DOMAIN: ''

    command: /usr/src/app/wave.sh

  nginx:
    build:
      context: nginx
      dockerfile: Dockerfile
    restart: on-failure
    ports:
      - 80:80
      - 443:443
    volumes:
      - ssl_data:/etc/resty-auto-ssl
    environment:
      ALLOWED_DOMAINS: "${STAGING_ALLOWED_DOMAINS}"
      SITES: "${STAGING_SITES}"

volumes:
  ssl_data:
  django-static:
  django-uploads:

I have tested this docker-compose file build process with the code, and all deploys fine:

docker-compose -f docker-compose.staging.yml up --build

My question is, I usually deploy automatically using docker-machine, which deploys a new virtual machine.

However, I am wondering, what is the procedure with docker-compose to publish this as an image to a Docker registry like Docker Hub? I have tried to search for an answer, but there doesn't seem to be anything that I can find.

Do I build two images from both services?

Is it possible to push two or more services from a docker-compose.yml file to Docker Hub (or similar)?

halfer
  • 19,824
  • 17
  • 99
  • 186
Micheal J. Roberts
  • 3,735
  • 4
  • 37
  • 76

2 Answers2

3

The Docker Compose YAML file you show builds two separate images from two separate Dockerfiles, then runs one container from each. You can use docker push or docker-compose push to push the individual images to Docker Hub, but there's no way to combine these into a single image or to push this entire deployment setup as a unit.

The setup you'll wind up with when you go to run these two images will need a very similar docker-compose.yml file, but with image: lines instead of build:

version: '3.7'
services:
  web:
    restart: always
    image: myname/web:20191129
    volumes: [ ... ]
    environment: { ... }
  nginx:
    image: myname/nginx:20191129
    restart: on-failure
    ports: ['80:80', '443:443']
    volumes: [ ... ]
    environment: { ... }
volumes: { ... }

(The volumes:, ports:, and environment: are the same as in your original file; expose: and command: should probably be built into the image and don't need to be repeated.)

Check this file into source control. You can distribute it to the target system however you'd like: manually scp it, or use an automation tool like Ansible or Chef to put it there and launch it.

To get the images pushed to Docker Hub (or another registry) you need a Docker Compose file with both build: and image:. If you specify both, then when you docker-compose build the images, they will get tagged with the name you specify. You can then docker-compose push both images (with one command, but still as two separate images).

In this environment you also might find it helpful to have multiple overlapping docker-compose.yml files. Make the base docker-compose.yml file only have the image: declarations, and add a separate docker-compose.build.yml

version: '3'
services:
  web:
    build: ./django
    # and no other options
  nginx:
    build: ./nginx

Then when you want to build the image for pre-deployment testing or to push it you can

docker-compose -f docker-compose.yml -f docker-compose.build.yml build
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Hi David. Thanks for this answer. I have one question as I am still confused, and apologies if it is tracing over the same ground twice. Can I build one image from the one docker-compose file? The two services work in tandem as the resty-auto-ssl image allows for SSL which is pretty much a requirement. I think my outcome is is that I somehow have one image which can be pushed to dockerhub... – Micheal J. Roberts Nov 29 '19 at 15:15
  • No, there is no way to combine the two images and no way to push the Compose setup to Docker Hub. But overall the setup you've shown here is extremely routine; it's very normal to have multiple closely-related containers like this. – David Maze Nov 29 '19 at 16:32
  • Ok, thanks. Do you have any resources you know of that could help me to understand building an image from multiple services, as say Elastic Beanstalk, wants one image of truth...definitely correct me if I am wrong but there doesn't seem to be anything to take people from a routine docker-compose file as you described mine as to a single image? – Micheal J. Roberts Nov 29 '19 at 16:44
  • On AWS, hosted services like ECS (Amazon-specific) or EKS (Kubernetes-based) can run multiple containers in concert, or you can run Compose manually on an EC2 instance. – David Maze Nov 29 '19 at 16:52
-1

You don't deploy to DockerHub. You push to docker hub. Hopefully this command might be what you're looking for: docker-compose push

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Ben Lewis Watson
  • 168
  • 2
  • 11