Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker for development and production environments #261

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# items that do not need to be in a Docker image as they
# are not used by the build system
.circleci/
.git/
docker/Dockerfile.*
.dockerignore
.env
.gitignore
README.md
docker-*

# items that may be built during Docker image creation
build/
node_modules/
6 changes: 6 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
PUBLIC_IP_ADDRESS=
# set to development or production
NODE_ENV=development
# React requires variable name to be `PORT` in development
PORT=8000
PORT_PROD=8001
PORT_NGINX=80
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
PUBLIC_IP_ADDRESS=
# set to development or production
NODE_ENV=development
# React requires variable name to be `PORT` in development
PORT=8000
PORT_PROD=8001
PORT_NGINX=80
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ coverage
!.yarn/sdks
!.yarn/versions
.pnp.*
docker-dev.log
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,44 @@ it also displays the user's token balance. It is included in the template alread
```

Refer to [this doc page](https://github.com/vacp2p/docs.wakuconnect.dev/blob/develop/content/docs/guides/07_reactjs_relay.md).

## Docker

### Development

* Install and run [Docker](https://www.docker.com/)
* Setup environment
```bash
cp .env.example .env
```
* Run Substrate front-end from a Docker container and follow the terminal log instructions.
```bash
./docker-dev.sh
```

### Production

* Install and run [Docker](https://www.docker.com/)
* Setup environment
```bash
cp .env.example .env
```
Note: It will fallback to automatically detecting your Public IP Address, however you may assign the value to `PUBLIC_IP_ADDRESS` in the .env file to manually override it.
* Run Substrate front-end from a Docker container and follow the terminal log instructions.
```bash
./docker-prod.sh
```

### Useful Docker Commands

* List Docker containers `docker ps -a`
* List Docker images `docker images -a`
* Enter Docker container shell `docker exec -it $CONTAINER_ID /bin/sh`
* View Docker container logs `docker logs -f $CONTAINER_ID`
* Remove Docker container `docker stop $CONTAINER_ID && docker rm $CONTAINER_ID;`
* Remove Docker image `docker rmi $IMAGE_ID`

### Useful Nginx Commands

* Verify Nginx Config File Syntax Ok `nginx -t`
* [Reload](https://docs.nginx.com/nginx/admin-guide/basic-functionality/runtime-control/) Nginx Config File for changes to take effect `nginx -s reload`
21 changes: 21 additions & 0 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: "3.8"
services:
dev:
container_name: ${APP_NAME}-dev
restart: always
build:
context: "."
dockerfile: ./docker/Dockerfile.dev
args:
- APP_NAME=${APP_NAME}
- PORT=${PORT}
volumes:
- ./:/app/${APP_NAME}:delegated
- ignore:/app/${APP_NAME}/node_modules
ports:
- "${PORT}:${PORT}"
env_file:
- .env

volumes:
ignore:
23 changes: 23 additions & 0 deletions docker-compose-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: "3.8"
services:
prod:
container_name: ${APP_NAME}-prod
restart: always
build:
context: "."
dockerfile: ./docker/Dockerfile.prod
args:
- NODE_ENV=${NODE_ENV}
- PORT_NGINX=${PORT_NGINX}
- PORT_PROD=${PORT_PROD}
- PUBLIC_URL=${PUBLIC_URL}
volumes:
- ./:/app:delegated
- ignore:/app/node_modules
ports:
- ${PORT_PROD}:${PORT_NGINX}
env_file:
- .env

volumes:
ignore:
34 changes: 34 additions & 0 deletions docker-dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Copyright 2017-2022 @polkadot authors & contributors
# This software may be modified and distributed under the terms
# of the Apache-2.0 license. See the LICENSE file for details.

trap "echo; exit" INT
trap "echo; exit" HUP

# try to fetch public IP address if value not set in .env
PUBLIC_IP_ADDRESS_FALLBACK=$(wget http://ipecho.net/plain -O - -q ; echo)

# assign fallback values for environment variables from .env.example incase
# not declared in .env file. alternative approach is `echo ${X:=$X_FALLBACK}`
source $(dirname "$0")/.env.example
source $(dirname "$0")/.env
${PUBLIC_IP_ADDRESS:=$PUBLIC_IP_ADDRESS_FALLBACK}
export APP_NAME=$(jq '.name' package.json | sed 's/\"//g')
export PORT
if [ "$NODE_ENV" != "development" ]; then
printf "\nError: NODE_ENV should be set to development in .env\n";
kill "$PPID"; exit 1;
fi

printf "\n*** Building Docker container. Please wait... \n***"
DOCKER_BUILDKIT=0 docker compose -f docker-compose-dev.yml up --build -d
if [ $? -ne 0 ]; then
kill "$PPID"; exit 1;
fi

printf "\n*** Finished building. Please open:\n***"
printf "\n*** - http://localhost:${PORT} (local server)"
if [ "$PUBLIC_IP_ADDRESS" != "" ]; then
printf "\n*** - http://${PUBLIC_IP_ADDRESS}:${PORT} (remote server)\n***\n";
fi
36 changes: 36 additions & 0 deletions docker-prod.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# Copyright 2017-2022 @polkadot authors & contributors
# This software may be modified and distributed under the terms
# of the Apache-2.0 license. See the LICENSE file for details.

trap "echo; exit" INT
trap "echo; exit" HUP

# try to fetch public IP address if value not set in .env
PUBLIC_IP_ADDRESS_FALLBACK=$(wget http://ipecho.net/plain -O - -q ; echo)

# assign fallback values for environment variables from .env.example incase
# not declared in .env file. alternative approach is `echo ${X:=$X_FALLBACK}`
source $(dirname "$0")/.env.example
source $(dirname "$0")/.env
export PUBLIC_IP_ADDRESS NODE_ENV PORT_NGINX PORT_PROD
export APP_NAME=$(jq '.name' package.json | sed 's/\"//g')
if [ "$NODE_ENV" != "production" ]; then
printf "\nError: NODE_ENV should be set to production in .env\n";
kill "$PPID"; exit 1;
fi
echo ${PUBLIC_IP_ADDRESS:=$PUBLIC_IP_ADDRESS_FALLBACK}
if [ "$PUBLIC_IP_ADDRESS" = "" ]; then
printf "\nError: PUBLIC_IP_ADDRESS should be set in .env\n";
kill "$PPID"; exit 1;
fi
export PUBLIC_URL="http://${PUBLIC_IP_ADDRESS}:${PORT_PROD}"

printf "\n*** Building $NODE_ENV $APP_NAME. Please wait...\n***"
DOCKER_BUILDKIT=0 docker compose -f docker-compose-prod.yml up --build -d
if [ $? -ne 0 ]; then
kill "$PPID"; exit 1;
fi

printf "\n*** Finished building ${NODE_ENV}.\n***"
printf "\n*** Please open: ${PUBLIC_URL}.\n***\n"
25 changes: 25 additions & 0 deletions docker/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM node:gallium-alpine

ARG APP_NAME=${APP_NAME}
ARG APP_PATH=/app/${APP_NAME}
ARG PORT=${PORT}

ENV PATH=${APP_PATH}/node_modules/.bin:$PATH

WORKDIR ${APP_PATH}

COPY package.json .

RUN apk update && apk add --update git && rm -rf /var/cache/apk/*
RUN corepack enable \
&& corepack prepare yarn@stable --activate \
&& yarn set version 3.1.1 \
&& yarn plugin import interactive-tools \
&& echo -e "nodeLinker: node-modules\n\n$(cat ${APP_PATH}/.yarnrc.yml)" > ${APP_PATH}/.yarnrc.yml \
&& yarn

COPY . .

EXPOSE ${PORT}

CMD ["yarn", "run", "start"]
40 changes: 40 additions & 0 deletions docker/Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
FROM node:gallium-alpine AS builder

ARG NODE_ENV=${NODE_ENV}
ARG PORT_NGINX=${PORT_NGINX}
ARG PUBLIC_URL=${PUBLIC_URL}
ARG APP_PATH=/app
ENV PUBLIC_URL=${PUBLIC_URL}
ENV PATH=${APP_PATH}/node_modules/.bin:$PATH
WORKDIR ${APP_PATH}

COPY package.json .

RUN apk update && apk add --update git && rm -rf /var/cache/apk/*
RUN corepack enable \
&& corepack prepare yarn@stable --activate \
&& yarn set version 3.1.1 \
&& yarn plugin import interactive-tools \
&& echo -e "nodeLinker: node-modules\n\n$(cat ${APP_PATH}/.yarnrc.yml)" > ${APP_PATH}/.yarnrc.yml \
&& yarn
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be yarn install --production


COPY . .

RUN NODE_ENV=${NODE_ENV} yarn build

# ===========================================================
FROM nginx:stable-alpine

ARG APP_PATH=/app
ARG NGINX_PATH=/usr/share/nginx/html
ARG PUBLIC_URL=${PUBLIC_URL}
ENV PUBLIC_URL=${PUBLIC_URL}
WORKDIR ${NGINX_PATH}

COPY --from=builder ${APP_PATH}/docker/nginx.conf /etc/nginx/nginx.conf
COPY --from=builder ${APP_PATH}/build/index.html ${NGINX_PATH}/index.html
COPY --from=builder ${APP_PATH}/build ${NGINX_PATH}

EXPOSE ${PORT_NGINX}

CMD ["nginx", "-g", "daemon off;"]
39 changes: 39 additions & 0 deletions docker/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Copyright 2017-2022 @polkadot/apps authors & contributors
# This software may be modified and distributed under the terms
# of the Apache-2.0 license. See the LICENSE file for details.

# Reference: https://github.com/polkadot-js/apps/blob/master/docker/nginx.conf

# Directives and parameters
user nginx; # Directive in the 'main' context
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
# Configuration of connection processing
worker_connections 1024;
}

http {
# Configuration specific to HTTP and affecting all virtual servers
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;
gzip on;

# Includes server contexts for configuring each HTTP virtual server
include /etc/nginx/conf.d/*.conf;
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"polkadot-js"
],
"scripts": {
"start": "react-app-rewired start",
"start": "WATCHPACK_POLLING=true react-app-rewired start",
"build": "react-app-rewired build",
"test": "CI=true react-app-rewired test",
"eject": "react-scripts eject",
Expand Down