Search code examples
nginxdockerowncloud

How to put ownCloud behind Nginx with Docker?


I want to access an ownCloud instance trough Nginx both set up inside separate Docker containers. So I've made docker-compose.yml:

nginx:
  image: nginx
  ports:
    - 80:80
  volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf
  links:
    - owncloud
owncloud:
  image: owncloud
  ports:
    - 6789:80
  volumes:
    - ~/ownCloud:/var/www/html/data

And nginx.conf to proxify requests with following contents:

http {
  server {
    listen 80 default;
    server_name docker.dev;

    location / {
      proxy_pass http://127.0.0.1:6789;
      proxy_buffering off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}
events {}

Seems right to me, but Nginx logs out such message:

[error] 6#6: *8 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.99.1, server: docker.dev

What am I doing wrong?


Solution

  • The problem is that inside the nginx container, 127.0.0.1:6789 will not map to owncloud. This is because, docker is only mapping port 80 on owncloud port 6789 on the host machine.

    Imagine each container as well as the docker host is a completely separate machine. In this case the nginx machine sends a request to 127.0.0.1 which is just itself, not the host machine, not the owncloud machine.

    There are many ways to communicate between docker containers and you are already using one of them, docker compose's built in linking system.

    In your docker-compose.yml you have already linked owncloud to nginx, which is correct. What this does is edit the nginx containers /etc/hosts file to map owncloud the owncloud container's ip address. (You can check it out by running docker exec name_of_nginx_container cat /etc/hosts). What this means is, inside the nginx container http://owncloud maps to port 80 on the owncloud comtainer.

    With that in mind, this is a full configuration that works with docker compose's linking system.

    docker-compose.yml

    nginx:
      image: nginx
      ports:
        - 80:80
      volumes:
        - ./nginx.conf:/etc/nginx/nginx.conf
      links:
        - owncloud
    owncloud:
      image: owncloud
      expose:
        - 80
      volumes:
        - ~/ownCloud:/var/www/html/data
    

    nginx.conf

    http {
      server {
        listen 80 default;
        server_name docker.dev;
    
        location / {
          proxy_pass http://owncloud;
          proxy_buffering off;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
        }
      }
    }
    events {}
    

    The only differences are that you only need to expose port 80 on the owncloud image, not map it to the host and the proxy_pass line in nginx.conf.

    Hope that helps.