Deploying a Phoenix project to Digital Ocean with Docker

I’m trying to deploy a Phoenix project to Digital Ocean using Docker for the 1st time. In the past, I’ve used either Heroku or Gigalixir. This is my first experience with both Docker and Digital Ocean. I’ve used the following resources:

Distillery: Deploying to Digital Ocean

My hello_docker project is on Github here. My image is on docker hub here.

The docker-compose.yml is:

# File my_app/docker-compose.yml
version: "3.5"

networks:
  webnet:
    driver: overlay
    attachable: true # Needed in order to run custom commands in the container

services:
  app:
    image: axelclark/hello_docker:0.2.0
    ports:
      - "80:4000" # In our .env file above, we chose port 4000
    env_file:
      - config/docker.env
    depends_on:
      - db
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    networks:
      - webnet

  db:
    image: postgres:10-alpine
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
      restart_policy:
        condition: on-failure
    volumes:
      - "./volumes/postgres:/var/lib/postgresql/data"
    ports:
      - "5432:5432"
    env_file:
      - config/docker.env
    networks:
      - webnet

I’ve followed the deploy steps in Distillery: Deploying to Digital Ocean.

I saved the config/docker.env and docker-compose.yml files to the droplet. Then I ran the docker swarm and docker stack deploy commands:

root@docker-axelclark:~$ docker swarm init --advertise-addr  64.227.3.73
Swarm initialized: current node (kdqwzzipuli9rbncr282mm633) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-5w2kptuxwtwbnu3nvr4abx4vh6qo3b3k82nnu91qnkojqosx1s-6b4a9ifclb3hprmkn227cjwo6 64.227.3.73:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

root@docker-axelclark:~$ docker stack deploy -c ~/etc/myapp/docker-compose.yml myapp
Creating network myapp_webnet
Creating service myapp_db
Creating service myapp_app

root@docker-axelclark:~$ docker stack ls
NAME                SERVICES            ORCHESTRATOR
myapp               2                   Swarm

When I deploy locally with docker swarm init and docker stack deploy, everything works as expected.

However, when I deploy to Digital Ocean, I can’t figure out how to visit my site. What url can I visit to see if my app is working?

I tried the ip: 64.227.3.73, but it says the site can’t be reached. There is probably a simple answer, but I haven’t been able to figure it out.

Thanks!
Axel

1 Like

You should be able to access it from the public IP of your DO droplet, since your docker-compose.yml file has the container port 4000 mapped to the host (your droplet) port 80.

It looks like you have it configured to run on port 80, instead of port 4000 like your compose file expects: https://github.com/axelclark/hello_docker/blob/master/config/prod.exs#L13. Can you try either changing that line to 4000 instead of 80 or changing "80:4000" in your compose file to "80:80"?

2 Likes

As @jswny says, your application is configured to listen on port 80:

Though your docker-compose file maps requests comming from external to port 4000 in the container, where nothing is listening.

I think its indeed easier to just change the pheonix configuration to listen on port 4000, as listening on port 80 would require special permissions, which one shouldn’t give away to web servers without a very good reason.

3 Likes

I made the changes you suggested. Now everything is working as expected. Thanks @jswny and @NobbZ!

1 Like

I wrote a blog post with everything I learned:

In the past, I’ve used either Heroku or Gigalixir to deploy my Elixir / Phoenix projects. I wanted to learn how to deploy using Elixir releases (available in Elixir 1.9+) and Docker. I decided to use Digital Ocean because I read it is a little easier to set up than AWS.

I used a number of resources to deploy my project, this post covers the steps to get a Phoenix project with a Postgres database deployed on Digital Ocean using Elixir Releases and Docker.

9 Likes