Skip to content

Instantly share code, notes, and snippets.

@carmark
Last active March 7, 2024 02:03
Show Gist options
  • Select an option

  • Save carmark/4aa32cacd4d041448c39ad8deb87135f to your computer and use it in GitHub Desktop.

Select an option

Save carmark/4aa32cacd4d041448c39ad8deb87135f to your computer and use it in GitHub Desktop.

Revisions

  1. carmark revised this gist May 27, 2016. 1 changed file with 127 additions and 11 deletions.
    138 changes: 127 additions & 11 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -9,6 +9,130 @@ So, the overall picture looks something like this:

    ![](http://anandmanisankar.com/assets/images/DockerSample.png)

    ### The Node container

    The `index.js` :
    ```
    var express = require('express'),
    http = require('http'),
    redis = require('redis');
    app = express();
    console.log(process.env.REDIS_PORT_6379_TCP_ADDR + ':' + process.env.REDIS_PORT_6379_TCP_PORT);
    // APPROACH 1: Using environment variables created by Docker
    // var client = redis.createClient(
    // process.env.REDIS_PORT_6379_TCP_PORT,
    // process.env.REDIS_PORT_6379_TCP_ADDR
    // );
    // APPROACH 2: Using host entries created by Docker in /etc/hosts (RECOMMENDED)
    var client = redis.createClient('6379', 'redis');
    app.get('/', function(req, res, next) {
    client.incr('counter', function(err, counter) {
    if(err) return next(err);
    res.send(`
    <head>
    <link href="https://fonts.googleapis.com/css?family=Roboto:100" rel="stylesheet" type="text/css">
    </head>
    <style>
    body {
    font-family: 'Roboto', sans-serif;
    background-color: rgb(49, 49, 49);
    color: rgb(255, 136, 0);
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 60px;
    flex-direction: column;
    }
    footer {
    margin-top: 20px;
    font-size: 28px;
    color: #848484;
    }
    a {
    color: white;
    text-decoration: none;
    cursor: pointer;
    &:hover {
    opacity: 0.8;
    }
    }
    span {
    margin: 0 5px;
    border-radius: 4px;
    color: white;
    }
    span::before {
    content: " ";
    position: absolute;
    background-color: black;
    width: 40px;
    margin-left: -4px;
    height: 36px;
    z-index: -1;
    border-radius: 4px;
    }
    span::after {
    content: " ";
    position: absolute;
    margin-top: 37px;
    background-color: black;
    width: 40px;
    height: 36px;
    z-index: -1;
    margin-left: -37px;
    border-radius: 4px;
    }
    </style>
    <body>
    <div>This page has been viewed <script>document.write(String(${counter}).split('').map(function(c) {return '<span>' + c + '</span>'}).join(''))</script> times</div>
    <footer>© 2016, HyperHQ Inc. All rights reserved. For more information, visit <a href="https://hyper.sh">hyper.sh</a></footer>
    </body>
    `);
    });
    });
    http.createServer(app).listen(process.env.PORT || 8080, function() {
    console.log('Listening on port ' + (process.env.PORT || 8080));
    });
    ```

    The `Dockerfile` to build node image:
    ```
    # Set the base image to Ubuntu
    FROM ubuntu
    # File Author / Maintainer
    MAINTAINER Lei Xue
    # Install Node.js and other dependencies
    RUN apt-get update && \
    apt-get -y install curl && \
    curl -sL https://deb.nodesource.com/setup_6.x | sudo bash - && \
    apt-get -y install python build-essential nodejs
    # Provides cached layer for node_modules
    ADD package.json /tmp/package.json
    RUN cd /tmp && npm install
    RUN mkdir -p /src && cp -a /tmp/node_modules /src/
    # Define working directory
    WORKDIR /src
    ADD . /src
    # Expose port
    EXPOSE 8080
    # Run app using nodemon
    CMD ["node", "/src/index.js"]
    ```

    ### The NGiNX container

    ```
    @@ -40,9 +164,9 @@ http {
    }
    ```

    ## Composing the application with Docker Compose
    >Compose is a tool for defining and running complex applications with Docker.
    It can get pretty tedious to build the images, run and link containers using individual commands, especially when you are dealing with many. Docker Compose lets you define a multi-container application in a single file, and spin up the application with a single command.
    ## Composing the application with Hyper Compose
    >Compose is a tool for defining and running complex applications with Hyper_.
    It can get pretty tedious to build the images, run and link containers using individual commands, especially when you are dealing with many. Hyper Compose lets you define a multi-container application in a single file, and spin up the application with a single command.

    I’ve defined a hyper compose YAML as follows:

    @@ -57,26 +181,18 @@ services:
    - node3:node3
    node1:
    image: carmark/node
    container_name: node1
    hostname: node1
    links:
    - redis
    node2:
    image: carmark/node
    container_name: node2
    hostname: node2
    links:
    - redis
    node3:
    image: carmark/node
    container_name: node3
    hostname: node3
    links:
    - redis
    redis:
    image: redis
    container_name: redis
    hostname: redis
    ```
    With a single command, Hyper_ Compose will build the required images, expose the required ports, run and link the containers as defined in the YAML. All you need to do is run docker-compose up! Your 5 container application is up and running. Hit your host URL on port 80 and you have your view counter!

  2. carmark revised this gist May 26, 2016. 1 changed file with 30 additions and 30 deletions.
    60 changes: 30 additions & 30 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -47,36 +47,36 @@ It can get pretty tedious to build the images, run and link containers using ind
    I’ve defined a hyper compose YAML as follows:

    ```
    nginx:
    build: ./nginx
    links:
    - node1:node1
    - node2:node2
    - node3:node3
    ports:
    - "80:80"
    node1:
    build: ./node
    links:
    - redis
    ports:
    - "8080"
    node2:
    build: ./node
    links:
    - redis
    ports:
    - "8080"
    node3:
    build: ./node
    links:
    - redis
    ports:
    - "8080"
    redis:
    image: redis
    ports:
    - "6379"
    version: "2"
    services:
    nginx:
    image: carmark/nginx
    links:
    - node1:node1
    - node2:node2
    - node3:node3
    node1:
    image: carmark/node
    container_name: node1
    hostname: node1
    links:
    - redis
    node2:
    image: carmark/node
    container_name: node2
    hostname: node2
    links:
    - redis
    node3:
    image: carmark/node
    container_name: node3
    hostname: node3
    links:
    - redis
    redis:
    image: redis
    container_name: redis
    hostname: redis
    ```
    With a single command, Hyper_ Compose will build the required images, expose the required ports, run and link the containers as defined in the YAML. All you need to do is run docker-compose up! Your 5 container application is up and running. Hit your host URL on port 80 and you have your view counter!

  3. carmark renamed this gist May 26, 2016. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. carmark created this gist May 26, 2016.
    84 changes: 84 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    For this example, I have a very simple Node.js applications that increments a counter stored on Redis. I want to run Redis and the node application independently as I want to have the ability to scale the node application depending on the load. To start off, I have 3 instances of the node server running the application. I have an Nginx server in front of node for load balancing the node instances.

    Let’s now talk in terms of containers, specifically Docker containers. Simple; 1 container for each service/process!

    * 1 Redis container
    * 3 Node containers
    * 1 Nginx container
    So, the overall picture looks something like this:

    ![](http://anandmanisankar.com/assets/images/DockerSample.png)

    ### The NGiNX container

    ```
    worker_processes 4;

    events { worker_connections 1024; }

    http {

    upstream node-app {
    least_conn;
    server node1:8080 weight=10 max_fails=3 fail_timeout=30s;
    server node2:8080 weight=10 max_fails=3 fail_timeout=30s;
    server node3:8080 weight=10 max_fails=3 fail_timeout=30s;
    }

    server {
    listen 80;

    location / {
    proxy_pass http://node-app;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    }
    }
    }
    ```

    ## Composing the application with Docker Compose
    >Compose is a tool for defining and running complex applications with Docker.
    It can get pretty tedious to build the images, run and link containers using individual commands, especially when you are dealing with many. Docker Compose lets you define a multi-container application in a single file, and spin up the application with a single command.

    I’ve defined a hyper compose YAML as follows:

    ```
    nginx:
    build: ./nginx
    links:
    - node1:node1
    - node2:node2
    - node3:node3
    ports:
    - "80:80"
    node1:
    build: ./node
    links:
    - redis
    ports:
    - "8080"
    node2:
    build: ./node
    links:
    - redis
    ports:
    - "8080"
    node3:
    build: ./node
    links:
    - redis
    ports:
    - "8080"
    redis:
    image: redis
    ports:
    - "6379"
    ```
    With a single command, Hyper_ Compose will build the required images, expose the required ports, run and link the containers as defined in the YAML. All you need to do is run docker-compose up! Your 5 container application is up and running. Hit your host URL on port 80 and you have your view counter!

    One of the significant features of Docker Compose is the ability to dynamically scale a container. Using the command docker-compose scale node=5, one can scale the number of containers to run for a service. If you had a Docker based microservices architecture, you could easily scale specific services dynamically depending on the load distribution requirements. Ideally, I would have preferred defining 1 node service and scaling it up using Docker Compose. But I haven’t figured a way to adjust the Nginx configuration dynamically. Please leave a comment if you have any thoughts on this. (UPDATE: See comments below for approaches to maintaining a dynamic Nginx configuration)