Improve Docker support

- default command should be start, rather than start:dev in the docker image
- added a multistage build
- fixed node-gyp error
- removed dev dependencies
- added a start:dotenv script to support a .env file in production (may be useful for
k8s later)
- updated Readme and generateEnv script to simplify the setup
- updated external network in docker-compose.yaml to match the test network

Signed-off-by: James Taylor <jamest@uk.ibm.com>
This commit is contained in:
James Taylor 2021-08-18 17:01:04 +01:00
parent 5d1adddd03
commit 82b1249f4e
6 changed files with 85 additions and 51 deletions

View file

@ -46,6 +46,28 @@ Start the sample REST server
npm run start:dev
```
### Docker image
Alternatively, run the following commands in the `fabric-rest-sample/asset-transfer-basic/rest-api-typescript` directory to start the sample in a Docker container
Build the Docker image
```shell
docker build -t fabric-rest-sample .
```
Create a `.env` file to configure the server for the test network (make sure `TEST_NETWORK_HOME` is set to the fully qualified `test-network` directory and `AS_LOCAL_HOST` is set to `false` so that the server works inside the Docker Compose network)
```shell
TEST_NETWORK_HOME=$HOME/fabric-samples/test-network AS_LOCAL_HOST=false npm run generateEnv
```
Start the sample REST server and Redis server
```shell
docker-compose up -d
```
## REST API
If everything went well, you can now make basic asset transfer REST calls!
@ -105,22 +127,3 @@ curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${
```shell
curl --include --header "X-Api-Key: ${SAMPLE_APIKEY}" --request DELETE http://localhost:3000/api/assets/asset7
```
## Steps to run the application using docker:
Move to directory fabric-rest-sample/asset-transfer-basic/rest-api-typescript
### Build docker image
docker build -t fabricapp .
### Generate .env file
TEST_NETWORK_HOME=$HOME/fabric-samples/test-network ./scripts/generateEnv.sh
Note: Connection profile need to use the peer containers hostname instead of localhost.
### Run docker containers
docker-compose up -d

View file

@ -4,6 +4,10 @@ PORT=3000
RETRY_DELAY=3000
MAX_RETRY_COUNT=5
AS_LOCAL_HOST=true
HLF_CONNECTION_PROFILE_ORG1={"name":"test-network-org1","version":"1.0.0","client":{"organization":"Org1" ... }
HLF_CERTIFICATE_ORG1="-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n"
@ -16,19 +20,20 @@ HLF_CERTIFICATE_ORG2="-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE----
HLF_PRIVATE_KEY_ORG2="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
HLF_COMMIT_TIMEOUT=3000
HLF_ENDORSE_TIMEOUT=30
HLF_QUERY_TIMEOUT=3
REDIS_HOST=localhost
REDIS_PORT=6379
ORG1_APIKEY=D2F66BFF-D68B-458D-8FA6-285F172D5B03
ORG2_APIKEY=92042C1F-8E58-48F9-9EAF-91A98A2B7648
#REDIS_USERNAME=
#REDIS_PASSWORD=
ORG1_APIKEY=D2F66BFF-D68B-458D-8FA6-285F172D5B03
ORG2_APIKEY=92042C1F-8E58-48F9-9EAF-91A98A2B764

View file

@ -1,20 +1,25 @@
FROM node:14-alpine3.12
RUN apk add dumb-init
WORKDIR /fabric_app/
FROM node:14-alpine3.12 AS build
COPY --chown=node:node . /fabric_app/
RUN apk add --no-cache g++ make python3 dumb-init
RUN npm ci
WORKDIR /app
COPY --chown=node:node . /app
RUN npm ci
RUN npm run build
RUN npm prune --production
FROM node:14-alpine3.12
ENV NODE_ENV production
WORKDIR /app
COPY --from=build /usr/bin/dumb-init /usr/bin/dumb-init
COPY --chown=node:node --from=build /app .
EXPOSE 3000
USER node
CMD dumb-init npm run start:dev
ENTRYPOINT [ "dumb-init", "--", "npm", "run"]
CMD ["start"]

View file

@ -6,21 +6,19 @@ services:
ports:
- 6379:6379
networks:
- net_test
- fabric_test
nodeapp:
image: 'fabricapp'
image: 'fabric-rest-sample'
command: ['start:dotenv']
ports:
- 3000:3000
env_file:
- ./.env
environment:
- REDIS_HOST=redis
- AS_LOCAL_HOST=false
networks:
- net_test
- fabric_test
networks:
net_test:
fabric_test:
external: true

View file

@ -51,6 +51,7 @@
"generateEnv": "./scripts/generateEnv.sh",
"lint": "eslint . --ext .ts",
"start": "node --require source-map-support/register ./dist",
"start:dotenv": "node --require source-map-support/register --require dotenv/config ./dist",
"start:dev": "node --require source-map-support/register --require dotenv/config ./dist | pino-pretty",
"start:redis": "docker run -p 6379:6379 --name fabric-sample-redis -d redis",
"test": "jest"

View file

@ -4,6 +4,8 @@
# SPDX-License-Identifier: Apache-2.0
#
${AS_LOCAL_HOST:=true}
: "${TEST_NETWORK_HOME:=../..}"
: "${CONNECTION_PROFILE_FILE_ORG1:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org1.example.com/connection-org1.json}"
: "${CERTIFICATE_FILE_ORG1:=${TEST_NETWORK_HOME}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem}"
@ -23,14 +25,10 @@ RETRY_DELAY=3000
MAX_RETRY_COUNT=5
HLF_CONNECTION_PROFILE_ORG1=$(cat ${CONNECTION_PROFILE_FILE_ORG1} | jq -c .)
HLF_CERTIFICATE_ORG1="$(cat ${CERTIFICATE_FILE_ORG1} | sed -e 's/$/\\n/' | tr -d '\r\n')"
HLF_PRIVATE_KEY_ORG1="$(cat ${PRIVATE_KEY_FILE_ORG1} | sed -e 's/$/\\n/' | tr -d '\r\n')"
HLF_CONNECTION_PROFILE_ORG2=$(cat ${CONNECTION_PROFILE_FILE_ORG2} | jq -c .)
HLF_CERTIFICATE_ORG2="$(cat ${CERTIFICATE_FILE_ORG2} | sed -e 's/$/\\n/' | tr -d '\r\n')"
HLF_PRIVATE_KEY_ORG2="$(cat ${PRIVATE_KEY_FILE_ORG2} | sed -e 's/$/\\n/' | tr -d '\r\n')"
@ -39,7 +37,7 @@ HLF_COMMIT_TIMEOUT=3000
HLF_ENDORSE_TIMEOUT=30
REDIS_HOST=localhost
HLF_QUERY_TIMEOUT=3
REDIS_PORT=6379
@ -47,8 +45,32 @@ ORG1_APIKEY=$(uuidgen)
ORG2_APIKEY=$(uuidgen)
#REDIS_USERNAME=
#REDIS_PASSWORD=
ENV_END
if [ "${AS_LOCAL_HOST}" = "true" ]; then
cat << LOCAL_HOST_END >> .env
AS_LOCAL_HOST=true
HLF_CONNECTION_PROFILE_ORG1=$(cat ${CONNECTION_PROFILE_FILE_ORG1} | jq -c .)
HLF_CONNECTION_PROFILE_ORG2=$(cat ${CONNECTION_PROFILE_FILE_ORG2} | jq -c .)
REDIS_HOST=localhost
LOCAL_HOST_END
elif [ "${AS_LOCAL_HOST}" = "false" ]; then
cat << WITH_HOSTNAME_END >> .env
AS_LOCAL_HOST=false
HLF_CONNECTION_PROFILE_ORG1=$(cat ${CONNECTION_PROFILE_FILE_ORG1} | jq -c '.peers["peer0.org1.example.com"].url = "grpcs://peer0.org1.example.com:7051" | .certificateAuthorities["ca.org1.example.com"].url = "https://ca.org1.example.com:7054"')
HLF_CONNECTION_PROFILE_ORG2=$(cat ${CONNECTION_PROFILE_FILE_ORG2} | jq -c '.peers["peer0.org2.example.com"].url = "grpcs://peer0.org2.example.com:9051" | .certificateAuthorities["ca.org2.example.com"].url = "https://ca.org2.example.com:8054"')
REDIS_HOST=redis
WITH_HOSTNAME_END
fi