Answers: <p>The layer that you're missing is nginx proxy. See my toy Mafia Game project here how to do it:</p>
  <ul>
  <li>Shell deployment project (uses either Docker compose or k8s) - <a href="https://github.com/taleodor/mafia-deployment" rel="nofollow noreferrer">https://github.com/taleodor/mafia-deployment</a></li>
  <li>Vue.js frontend - <a href="https://github.com/taleodor/mafia-vue" rel="nofollow noreferrer">https://github.com/taleodor/mafia-vue</a></li>
  <li>Express.js backend - <a href="https://github.com/taleodor/mafia-express" rel="nofollow noreferrer">https://github.com/taleodor/mafia-express</a></li>
  <li>(Optional) detailed write-up about CI/CD and how it's built from DevOps prospective - <a href="https://itnext.io/building-kubernetes-cicd-pipeline-with-github-actions-argocd-and-reliza-hub-e7120b9be870" rel="nofollow noreferrer">https://itnext.io/building-kubernetes-cicd-pipeline-with-github-actions-argocd-and-reliza-hub-e7120b9be870</a></li>
  </ul>
  <p>The missing piece in your case is nginx proxy that you use in your UI.</p>
  <p>So what you need to do is to define some location for your api - i.e. <code>/api</code>. Then your proxy it via nginx - see my nginx configuration for the project above here - <a href="https://github.com/taleodor/mafia-vue/tree/master/nginx" rel="nofollow noreferrer">https://github.com/taleodor/mafia-vue/tree/master/nginx</a>. At the same time it's highly recommended for performance to deploy static resources on the same nginx.</p>
  <p>Use Dockerfile to define environment variables and defaults, i.e. in my project - <a href="https://github.com/taleodor/mafia-vue/blob/master/Dockerfile" rel="nofollow noreferrer">https://github.com/taleodor/mafia-vue/blob/master/Dockerfile</a></p>
  <p>Finally, you can update configuration via environment variables in your docker-compose yaml or k8s definitions.</p>
  
Answers: CC BY-SA 4.0
Answers: 2020-07-02T18:50:11.280Z
Answers: I updated my repository with this solution and everything seems nice now.
  But, just one more question, what are these configurations that can be updated with environment variables in docker-compose that you suggested? Is there any guide that I could follow?
Answers: Sinayra
Answers: CC BY-SA 4.0
Answers: 2020-07-02T21:11:25.777Z
Answers: You don't have to parametrize anything right away. But as you go you may notice certain things that need parametrizing - so for those things you may create env variables. 
  
  Personally, I usually always parametrize host names and ports for upstreams - because name conventions may be sometimes different between local docker, docker-compose and k8s.
  
  Sometimes you will find other things later to parametrize - but no hard rules here.
  
  + Rarely, there may be more complex cases, where you can include more sophisticated templating engine if needed.
Answers: taleodor
Answers: CC BY-SA 4.0
Answers: 2020-07-01T00:21:13.540Z
Answers: 2020-07-01T00:21:13.540Z
Answers: taleodor
Body: <p>I'm studying Docker and how to properly publish my containers coding a very simple web application. It has only two containers, backend and frontend. I've published the source code here: <a href="https://github.com/sinayra/hello-private-world" rel="nofollow noreferrer">https://github.com/sinayra/hello-private-world</a></p>
  <p>If I run locally each node application, its works &quot;fine&quot; (everything is public, but this is not what I want in the end of the day). Then, I created Dockerfile for each container, to try to simulate a real application. For the frontend, I exposed the port 3000 to access from the host. However, I don't want to expose the port 3333 for the host, and, because of that, my front can't fetch the data from the back.</p>
  <p>Here is my index.html from the frontend.</p>
  <pre><code>&lt;html&gt;
    &lt;head&gt;
      &lt;title&gt;Hello Public World&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;h1&gt;Message from backend:&lt;/h1&gt;
      &lt;p id=&quot;backend&quot;&gt;&lt;/p&gt;
  
      &lt;script&gt;
        const back = document.getElementById(&quot;backend&quot;);
        const url = &quot;http://localhost:3333/&quot;; //I tried backend:3333, but without success
  
        fetch(url)
          .then((resp) =&gt; resp.json()) // Transform the data into json
          .then(function (data) {
            back.innerHTML = data.message;
          });
      &lt;/script&gt;
    &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <p>Its Dockerfile:</p>
  <pre><code># pull official base image
  FROM node:lts
  
  # set working directory
  WORKDIR /usr/src/app
  
  # install app dependencies
  COPY package.json ./
  RUN npm install
  
  # add app
  COPY . ./
  
  EXPOSE 3000
  
  # start app
  CMD [&quot;npm&quot;, &quot;run&quot;, &quot;start&quot;]
  </code></pre>
  <p>My index.js from backend:</p>
  <pre><code>const express = require(&quot;express&quot;);
  const app = express();
  const cors = require(&quot;cors&quot;);
  const port = 3333;
  
  const allowlist = [&quot;http://localhost:3000&quot;];
  const corsOptions = {
    origin: allowlist,
    methods: &quot;GET&quot;,
    preflightContinue: false,
    optionsSuccessStatus: 204,
  };
  app.use(cors(corsOptions));
  
  app.use(express.json());
  app.get(&quot;/&quot;, (req, res) =&gt; {
    console.log(&quot;GET /&quot;);
    res.json({ message: &quot;Hello Private World!&quot; });
  });
  
  app.listen(port, () =&gt;
    console.log(`Example app listening at http://localhost:${port}`)
  );
  </code></pre>
  <p>Its Dockerfile:</p>
  <pre><code># pull official base image
  FROM node:lts
  
  # set working directory
  WORKDIR /usr/src/app
  
  # install app dependencies
  COPY package.json ./
  RUN npm install
  
  # add app
  COPY . ./
  
  #EXPOSE 3333
  
  # start app
  CMD [&quot;npm&quot;, &quot;run&quot;, &quot;start&quot;]
  </code></pre>
  <p>And the Docker compose file</p>
  <pre><code>version: &quot;3.8&quot;
  services:
  
    backend:
      image: helloworld-private
      build:
        context: ./backend
        dockerfile: Dockerfile
      working_dir: /usr/src/app
      container_name: &quot;express_container&quot;
      volumes:
        - ./backend/:/usr/src/app
        - /usr/src/app/node_modules
      networks: 
        - webappnetwork
      expose:
        - &quot;3333&quot;
  
    web:
      image: helloworld-public
      build:
        context: ./web
        dockerfile: Dockerfile
      working_dir: /usr/src/app
      container_name: &quot;liveserver_container&quot;
      links:
        - backend
      volumes:
        - ./web/:/usr/src/app
        - /usr/src/app/node_modules
      environment:
        - PORT=3000
      networks: 
        - webappnetwork
      ports: 
        - &quot;3000:3000&quot;
  
  networks:
    webappnetwork:
      driver: bridge
  </code></pre>
  <p>Is there any abstraction layer that I'm missing?</p>
  
Comments: CC BY-SA 4.0
Comments: 2020-09-03T17:34:22.340Z
Comments: Side Note: I see what you did there with that title phrasing. ;)
Comments: J. Scott Elblein
Comments: CC BY-SA 4.0
Comments: 2020-09-04T18:07:21.707Z
Comments: omg... I swear it was unintentional
Comments: Sinayra
Tags: <docker><docker-compose><containers><security><node.js>
Title: How not expose my backend
UserDisplayName: Sinayra
ThreadText: # How not expose my backend
  
  (Asked by: username_0 on 2020-06-29)
  
  I'm studying Docker and how to properly publish my containers coding a very simple web application. It has only two containers, backend and frontend. I've published the source code here: <https://github.com/username_0/hello-private-world>
  
  If I run locally each node application, its works "fine" (everything is public, but this is not what I want in the end of the day). Then, I created Dockerfile for each container, to try to simulate a real application. For the frontend, I exposed the port 3000 to access from the host. However, I don't want to expose the port 3333 for the host, and, because of that, my front can't fetch the data from the back.
  
  Here is my index.html from the frontend.
  
  ```
  <html>
    <head>
      <title>Hello Public World</title>
    </head>
    <body>
      <h1>Message from backend:</h1>
      <p id="backend"></p>
  
      <script>
        const back = document.getElementById("backend");
        const url = "http://localhost:3333/"; //I tried backend:3333, but without success
  
        fetch(url)
          .then((resp) => resp.json()) // Transform the data into json
          .then(function (data) {
            back.innerHTML = data.message;
          });
      </script>
    </body>
  </html>
  
  ```
  
  Its Dockerfile:
  
  ```
  # pull official base image
  FROM node:lts
  
  # set working directory
  WORKDIR /usr/src/app
  
  # install app dependencies
  COPY package.json ./
  RUN npm install
  
  # add app
  COPY . ./
  
  EXPOSE 3000
  
  # start app
  CMD ["npm", "run", "start"]
  
  ```
  
  My index.js from backend:
  
  ```
  const express = require("express");
  const app = express();
  const cors = require("cors");
  const port = 3333;
  
  const allowlist = ["http://localhost:3000"];
  const corsOptions = {
    origin: allowlist,
    methods: "GET",
    preflightContinue: false,
    optionsSuccessStatus: 204,
  };
  app.use(cors(corsOptions));
  
  app.use(express.json());
  app.get("/", (req, res) => {
    console.log("GET /");
    res.json({ message: "Hello Private World!" });
  });
  
  app.listen(port, () =>
    console.log(`Example app listening at http://localhost:${port}`)
  );
  
  ```
  
  Its Dockerfile:
  
  ```
  # pull official base image
  FROM node:lts
  
  # set working directory
  WORKDIR /usr/src/app
  
  # install app dependencies
  COPY package.json ./
  RUN npm install
  
  # add app
  COPY . ./
  
  #EXPOSE 3333
  
  # start app
  CMD ["npm", "run", "start"]
  
  ```
  
  And the Docker compose file
  
  ```
  version: "3.8"
  services:
  
    backend:
      image: helloworld-private
      build:
        context: ./backend
        dockerfile: Dockerfile
      working_dir: /usr/src/app
      container_name: "express_container"
      volumes:
        - ./backend/:/usr/src/app
        - /usr/src/app/node_modules
      networks: 
        - webappnetwork
      expose:
        - "3333"
  
    web:
      image: helloworld-public
      build:
        context: ./web
        dockerfile: Dockerfile
      working_dir: /usr/src/app
      container_name: "liveserver_container"
      links:
        - backend
      volumes:
        - ./web/:/usr/src/app
        - /usr/src/app/node_modules
      environment:
        - PORT=3000
      networks: 
        - webappnetwork
      ports: 
        - "3000:3000"
  
  networks:
    webappnetwork:
      driver: bridge
  
  ```
  
  Is there any abstraction layer that I'm missing?
  
  **Tags:** docker, docker-compose, containers, security, node.js
  
  > **Comments:**
  > **username_1**: Side Note: I see what you did there with that title phrasing. ;)  
  > **username_0**: omg... I swear it was unintentional  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2020-07-01. Score: 2 | Accepted answer
  
  The layer that you're missing is nginx proxy. See my toy Mafia Game project here how to do it:
  
  * Shell deployment project (uses either Docker compose or k8s) - <https://github.com/username_2/mafia-deployment>
  * Vue.js frontend - <https://github.com/username_2/mafia-vue>
  * Express.js backend - <https://github.com/username_2/mafia-express>
  * (Optional) detailed write-up about CI/CD and how it's built from DevOps prospective - <https://itnext.io/building-kubernetes-cicd-pipeline-with-github-actions-argocd-and-reliza-hub-e7120b9be870>
  
  The missing piece in your case is nginx proxy that you use in your UI.
  
  So what you need to do is to define some location for your api - i.e. `/api`. Then your proxy it via nginx - see my nginx configuration for the project above here - <https://github.com/username_2/mafia-vue/tree/master/nginx>. At the same time it's highly recommended for performance to deploy static resources on the same nginx.
  
  Use Dockerfile to define environment variables and defaults, i.e. in my project - <https://github.com/username_2/mafia-vue/blob/master/Dockerfile>
  
  Finally, you can update configuration via environment variables in your docker-compose yaml or k8s definitions.
  
  > **Comments:**
  > **username_0**: I updated my repository with this solution and everything seems nice now. But, just one more question, what are these configurations that can be updated with environment variables in docker-compose that you suggested? Is there any guide that I could follow?  
  > **username_2**: You don't have to parametrize anything right away. But as you go you may notice certain things that need parametrizing - so for those things you may create env variables.   Personally, I usually always parametrize host names and ports for upstreams - because name conventions may be sometimes different between local docker, docker-compose and k8s.  Sometimes you will find other things later to parametrize - but no hard rules here.  + Rarely, there may be more complex cases, where you can include more sophisticated templating engine if needed.  
  
  ---
  
  