# Sidecar Tutorial: Docker & Deploy

The last step in configuring the application is to containerise the app with Docker. First we create a `Dockerfile` for the server-side API and the client-side app then compose a build using the demonstrated `docker-compose.yml` file available below.

### <img src="/files/omTIzJPscZcIOuMlpV38" alt="" data-size="line">Python FastApi Container

Add the `Dockerfile` to the server directory.

{% code title="server/Dockerfile" %}

```docker
# Python FastApi Docker Build
FROM python:3.10
# Alternatively you can use different tags from https://hub.docker.com/r/nginx/unit
WORKDIR /server

COPY ./server/requirements.txt /server/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /server/requirements.txt

# server/backend/requirements.txt
COPY . /server

EXPOSE 5000
# 
CMD ["uvicorn", "server.main:app", "--host", "0.0.0.0", "--port", "5000"]
```

{% endcode %}

The server-side API will run on port 5000, the client-side application will call the API for requests on this designated port.

### <img src="/files/cVz6GWnXoVbLbGgZhhTa" alt="" data-size="line">Vue / Nuxt js Container

Add the `Dockerfile` to the app directory.

{% code title="app/Dockerfile" %}

```docker
# Nuxt JS Docker Build
FROM node:16

# create destination directory
WORKDIR /app

COPY . .

COPY ./package*.json ./

COPY ./package-lock.json ./

RUN npm install && npm run build

#Ports to expose for client-side app, & sidecar connection.
EXPOSE 8080
ENV NUXT_HOST=0.0.0.0
ENV NUXT_PORT=80

```

{% endcode %}

### Docker-compose Application

The docker-compose.yml file will be composed of three sections.&#x20;

* FastAPI - Server-side API, run on port 5000. Container is named 'fastapi' as the name suggests.
* Vue/Nuxt js - Client-side application named frontend, run on port 80. Running the client-side app on port 80 will allow for automatic rerouting to port 443 while adding an ssl certificate to your application rather than having it run on another port and require a configuration for a reroute to port 80 later on.
* Sidecar - Connects the application to IndustryApps with your unique credentials.

{% code title="docker-compose.yml" %}

```docker
# Docker-compose build with Sidecar
version: '3.3'

services:
    fastapi:
      build: ./server
      container_name: fastapi
      ports:
        - "5000:5000"
      command:  uvicorn server.backend.main:app --reload --workers 1 --host 0.0.0.0 --port 5000
      restart: always
      tty: true
      
      
    frontend:
      build: ./app
      working_dir: /app
      ports:
        - "80:80"
      environment:
        - HOST=0.0.0.0
      container_name: nuxt-app
      command: npm run dev
      restart: always
      tty: true

    sidecar:
      image: industryapps.azurecr.io/service-discovery-sidecar
      container_name: sidecar
      environment:
         NODE_ENV: production
         DEPLOYMENT_MODE: public
         EUREKA_INSTANCE_IP: { IP }
         EUREKA_INSTANCE_PORT: { PORT }
         EUREKA_INSTANCE_APP: { APPCODE }
         EUREKA_HOST: servicediscovery.uat.industryapps.net
         EUREKA_PORT: 443
         EUREKA_INSTANCE_HOST_NAME: { HOSTNAME }

networks:
  default:
    driver: bridge

```

{% endcode %}

Inside the `docker-compose.yml` file, add the necessary information which is tagged with curly braces ' `{  }` '.&#x20;

* **`IP`** -> The IP of the web service which you are running, such as on AWS EC2 Ubuntu, Lightsail instance or Azure Web services as an example.
* **`PORT`** -> The port which the app client-side is served at (e.g. Port 80).
* **`APPCODE`** -> Navigate to your Developer dashboard > Applications > {App Name} > App Data, the Application code will be available there.
* **`HOSTNAME`** -> The domain of the application such as: \
  `https://sample-app.com/<<AppCode>>`.

### Deployment

Once the docker-compose has been updated accordingly, the app can be run by:

Building the container:

* `docker-compose build`

Run the container:

* `docker-compose up`

The application will need to be connected with a hostname which is ssl certified. There are various affordable or free options available to upload your application to a web service to accommodate this requirement.&#x20;

#### Obtaining a Hostname and utilising a Web Service for hosting the application externally

For this tutorials purpose you can use [AWS Lightsail](https://aws.amazon.com/lightsail/), which offers Ubuntu Instances. After you've registered with AWS:

* &#x20;The Lightsail instance can receive a free certificate from [AWS ACM](https://aws.amazon.com/certificate-manager/) which can be used by the [Elastic load balancer](https://aws.amazon.com/elasticloadbalancing/).&#x20;
* The load balancer can connect to your Lightsail instance by [enabling VPC peering](https://lightsail.aws.amazon.com/ls/docs/en_us/articles/lightsail-how-to-set-up-vpc-peering-with-aws-resources) on your Lightsail Instance then copying the Lightsail instance Private IP into the [elastic load balancer](https://aws.amazon.com/elasticloadbalancing/) which has the ssl certificate.
* Once the web service instance has been configured, the built application can be moved to the web service instance through `scp which is a secure copy with directory structure kept.`

Example:

```
scp -i MyLightsailKey.pem -r /path/to/application/root/folder/ ubuntu@<<instance-ip>>
```

Once the application has been setup in the appropriate environment, by running the [docker-compose commands](#deployment), a status code 204 showing successful registration should notify the app has been connected.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.industryapps.net/fundamentals/deploy-an-app-via-pre-defined-sidecar/sidecar-tutorial-docker-and-deploy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
