Search code examples
dockerdocker-composedockerfiledocker-machine

Deploy with docker-compose.yml


Not sure if it will be a duplicate question but i tried to find out stuff but not sure if i have similar situation like others. So i am new to docker and trying to setup a deployment for a small website.

So far i have a folder which has 3 files.

  1. index.html - has basic html

  2. Dockerfile - which has

FROM ubuntu:16.04
COPY . /var/www/html/
  1. docker-compose.yml - which has
version: '2.1'
services:
    app:
        build: .
        image: myname/myapp:1.0.0
    nginx:
        image: nginx
        container_name: nginx
        volumes:
            - ./host-volumes:/cont-volumes
        network_mode: "host"
    phpfpm56:
        image: php-fpm:5.6
        container_name: phpfpm56
        volumes:
            - ./host-volumes:/cont-volumes
        network_mode: "host"
    mysql:
        image: mysql:5.7
        container_name: mysql
        ports:
            - "3306:3306"
        volumes:
            - mysql:/var/lib/mysql
volumes:
    mysql:

Now i am using jenkins to create build, putting my all codes to host volumes to make it available to container and then i would run

docker-compose build

Now it creates an image and i push it to docker hub.

Then i login to remote server and pull the image and run. But that wont work because i still need to run docker-compose up inside the container.

Is this the right approach or i am missing something here?


Solution

  • The standard way to do this is to copy your code into the image. Do not bind-mount host folders containing your code; instead, use a Dockerfile COPY directive to copy in the application code (and in a compiled language, use a RUN command to build it). For example, your PHP container might have a corresponding Dockerfile that looks like (referencing this base Dockerfile)

    FROM php-fpm:5.6
    # Base Dockerfile defines a sensible WORKDIR
    COPY . .
    # Base Dockerfile sets EXPOSE 9000
    # Base Dockerfile defines ENTRYPOINT, CMD
    

    Then your docker-compose.yml would say, in part

    version: '3'
    service:
      phpfpm56:
        build: .
        image: me/phpfpm56:2019-04-30
        # No other settings
    

    And then your nginx configuration would say, in part (using the Docker Compose service name as a hostname)

    fastcgi_pass phpfpm56:9000
    

    If you use this in production you need to comment out the build: lines I think.

    If you're extremely set on a workflow where there is no hostname other than localhost and you do not need to rebuild Docker images to update code, you at least need to restart (some of) your containers after you've done the code push.

    docker-compose stop app phpfpm56
    docker-compose up -d
    

    You might look into a system-automation tool like Ansible or Chef to automate the code-push mechanism. Those same tools can also just install nginx and PHP, and if you're trying to avoid the Docker image build sequence, you might have a simpler installation and deployment system running servers directly on the host.