From 0e690663fe7e2e24c690c49097ad6934005b555a Mon Sep 17 00:00:00 2001 From: Silas Date: Fri, 28 Jul 2023 18:10:37 -0400 Subject: [PATCH] buncha fixes to make sure env vars are set properly before creating the image, and move npm install to dockerfile to bake it in the image --- .dockerizedroot | 0 .env | 5 +++- Dockerfile | 13 ++++++++-- README.md | 65 ++++++++++++++++++++++++++++++---------------- docker-compose.yml | 8 +++--- dockman.sh | 34 +++++++++++++++++------- entrypoint.sh | 21 --------------- supervisord.conf | 6 ++--- 8 files changed, 89 insertions(+), 63 deletions(-) create mode 100644 .dockerizedroot delete mode 100755 entrypoint.sh diff --git a/.dockerizedroot b/.dockerizedroot new file mode 100644 index 0000000..e69de29 diff --git a/.env b/.env index c49eac8..e5b2ad0 100644 --- a/.env +++ b/.env @@ -1,3 +1,6 @@ CONTAINER_NAME=react-native-dockerized RN_PROJECT_FOLDER_NAME=app -SSH_KEY="~/.ssh/id_docker_dev" +SSH_KEY="id_docker_dev" +NPM_TOKEN= +GH_TOKEN= +NODE_VERSION=16.13.0 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index bd9d788..05dc059 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,20 +3,29 @@ FROM reactnativecommunity/react-native-android # config and update ENV DEBIAN_FRONTEND noninteractive +ENV DOCKER=true WORKDIR /home RUN apt-get update RUN mkdir /var/log/app ARG SSH_KEY +ARG NODE_VERSION +ARG GH_TOKEN +ARG NPM_TOKEN +ARG RN_PROJECT_FOLDER_NAME # set up NVM and use v16 LTS RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash ENV NVM_DIR /root/.nvm -ENV NODE_VERSION 16.13.0 RUN . "$NVM_DIR/nvm.sh" && nvm install $NODE_VERSION && nvm alias default $NODE_VERSION && nvm use default ENV NODE_PATH $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH RUN npm install -g react-native-cli +# add gh/npm tokens and install project dependencies +RUN echo \"//github.com/:_authToken=$GH_TOKEN\" > /home/app/.npmrc +RUN echo \"//registry.npmjs.org/:_authToken=$NPM_TOKEN\" >> /home/app/.npmrc +RUN cd /home/$RN_PROJECT_FOLDER_NAME && npm install + # Install SSH server RUN apt-get -y install openssh-server COPY sshd_config /etc/ssh/sshd_config @@ -31,4 +40,4 @@ COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] \ No newline at end of file diff --git a/README.md b/README.md index 479a41e..fad8bd5 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Things to keep in mind: * [Docker Desktop ](https://docs.docker.com/desktop/install/mac-install/) * [OrbStack](https://orbstack.dev/) _(great alternative but it will be out of its free beta soon and may not be stable)_ * If you're running Linux, you can also just use the docker CLI and docker service, installed through your package manager. +* A Github and NPM account * A React Native project to dockerize! ## Installation @@ -26,6 +27,8 @@ You will either want to dockerize an app you haven't cloned/created yet, or an e
Expand + + Depending on whether you're starting a new project or dockerizing an existing one, there are two options: ```zsh @@ -42,6 +45,8 @@ git clone git@github.com:my-github-org/my-rn-project.git app
Expand + + To dockerize an existing React Native repository, clone this repository first. Then, move your React Native repository into this repository under a folder named app. ```zsh @@ -53,11 +58,36 @@ cd my-rn-project-dockerized && rm -rf .git
-#### Add `dockman.sh` to your PATH +#### Configure Github and NPM Auth
Expand + + +Prior to starting up the container, the image will run `npm install` during the build process. This may require Github authentication if you're installing NPM packages from private Github repositories. + +#### Github + +1. Create a [legacy access token](https://github.com/settings/tokens) with all Repo-related permissions checked, and save the token in your password manager. +2. Add `export GH_TOKEN="your_legacy_access_token"` to your `~/.zshrc` file + * Alternatively, you could add it to the `.env` file + +#### NPM + +1. If you're using private npm packages, create an [access token](https://docs.npmjs.com/creating-and-viewing-access-tokens) on npm's website. Ensure it has the appropriate permissions for the packages you need. +2. Add `export NPM_TOKEN="your_npm_access_token"` to your `~/.zshrc` file + * Alternatively, you could add it to the `.env` file + +
+ +#### Add `dockman.sh` to your PATH + +
+ Expand - optional + + + If you would like to run `dockman.sh` from any directory on your system, follow these steps: 1. Create a new directory named `.react-native-dockerized` in your home directory (if it doesn't already exist): @@ -65,9 +95,9 @@ If you would like to run `dockman.sh` from any directory on your system, follow mkdir -p $HOME/.react-native-dockerized ``` -2. Move the `dockman.sh` script into this new directory: +2. Copy the `dockman.sh` script into this new directory: ```zsh - mv /path/to/dockman.sh $HOME/.react-native-dockerized + cp ./dockman.sh $HOME/.react-native-dockerized ``` 3. Make the script executable: @@ -95,16 +125,12 @@ Note: The `source` command makes the changes effective immediately. You may need
- - -Check out the other optional setup sections, especially [Configure Github Auth](#configure-github-auth) if your project has dependencies installing from a private Github repository. - ## Usage After completing [Installation](#installation) and any optional setup: ```zsh -docker-compose up +./dockman.sh up ./dockman.sh start-metro # boot up an Android emulator before this step ./dockman.sh run-android @@ -128,36 +154,29 @@ _You may need to run `sudo chmod +x ./dockman.sh` first for executable permissio ## Settings -You can adjust a few settings in the `.env` file at the root of the repository. +You can adjust a few settings in the `.env` file at the root of the repository. Alternatively you could add them to your shell's environment. | Variable | Description | Default | | ------------- | ------------- | ------------- | | `CONTAINER_NAME` | The name of the Docker container with which the script interacts. | `react-native-dockerized` | | `SSH_KEY` | The location of the SSH key file used for secure communication with the Docker container. | `~/.ssh/id_docker_dev` | -| `RN_PROJECT_FOLDER_NAME` | The name of the React Native project folder. This should match the name of the folder that you cloned at the root of your repository. | `app` | +| `RN_PROJECT_FOLDER_NAME` | The name of the React Native project folder. This should match the name of the folder that you cloned at the root of this repository. | `app` | +| `NODE_VERSION` | The version of Node.js that will be installed by the Node Version Manager (NVM). | `16.13.0` | +| `NPM_TOKEN` | Token for authenticating with npm for installing npm packages. This should be a valid token associated with your npm account. | - | +| `GH_TOKEN` | Token for authenticating with GitHub. This is required for installing packages from private GitHub repositories. | - | + If you plan on running multiple Docker containers simultaneously, you will need to assign a unique name to each container. For instance, if you're developing two separate React Native apps, you'll need to dockerize the second app using a different container name. Please note that modifying the `RN_PROJECT_FOLDER_NAME` variable won't rename the project folder on your host machine. This variable should match the existing name of your project folder. -### Configure Github Auth - -
- Expand - optional, but highly recommended - -Prior to starting up the container, the image will run `npm install` during the build process. This may require Github authentication if you're installing NPM packages from private Github repositories. - -1. Create a [legacy access token](https://github.com/settings/tokens) with all Repo-related permissions checked, and save the token in your password manager. -2. Add `export GH_TOKEN="your_legacy_access_token"` to your `~/.zshrc` file - * Alternatively, you could add it to the `.env` file - -
- ### Remote Workspace Inside The Container:
Expand - optional + + You can open a new remote workspace in your IDE to access the React Native project within this Docker container. With VS Code, you may not require SSH for this, thanks to the robust integration of the [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) extension with Docker. However, if you're using VSCodium, your best bet is the [Open Remote SSH](https://open-vsx.org/vscode/item?itemName=jeanp413.open-remote-ssh) extension. Do note that VSCodium comes with certain limitations, such as the need to manually provision an SSH server and client - but hey that's the FOSS life. diff --git a/docker-compose.yml b/docker-compose.yml index 88dc10d..3dbb412 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,11 @@ services: - SSH_KEY=${SSH_KEY} - RN_PROJECT_FOLDER_NAME=${RN_PROJECT_FOLDER_NAME} - GH_TOKEN=${GH_TOKEN} + - NPM_TOKEN=${NPM_TOKEN} + - NODE_VERSION=${NODE_VERSION} + environment: + - GH_TOKEN=${GH_TOKEN} + - NPM_TOKEN=${NPM_TOKEN} container_name: "${CONTAINER_NAME}" volumes: - type: bind @@ -16,6 +21,3 @@ services: target: /home/app ports: - 8081:8081 - environment: - - EXPO_DEVTOOLS_LISTEN_ADDRESS=0.0.0.0 - diff --git a/dockman.sh b/dockman.sh index 15d01be..da5b255 100755 --- a/dockman.sh +++ b/dockman.sh @@ -22,10 +22,24 @@ if [[ -z "${CONTAINER_NAME}" ]]; then fi # Define the project directory -PROJECT_DIR="/home/app" +PROJECT_DIR="/home/$RN_PROJECT_FOLDER_NAME" # Docker command handling case $1 in + up) + # List of required environment variables + REQUIRED_VARS=("SSH_KEY" "GH_TOKEN" "NPM_TOKEN" "NODE_VERSION" "RN_PROJECT_FOLDER_NAME" "CONTAINER_NAME") + + for VAR in ${REQUIRED_VARS[@]}; do + if [[ -z "${!VAR}" ]]; then + echo "Error: Required environment variable $VAR is not set" + exit 1 + fi + done + + # If we get here, all variables are set + docker-compose up + ;; stop-metro) docker exec -it ${CONTAINER_NAME} supervisorctl stop npm ;; @@ -35,15 +49,14 @@ case $1 in echo "Please set the RN_PROJECT_FOLDER_NAME environment variable before running the script." exit 1 fi - docker exec ${CONTAINER_NAME} /bin/bash -c "echo \"//github.com/:_authToken=$GH_TOKEN\" > ${PROJECT_DIR}/.npmrc" docker exec ${CONTAINER_NAME} /bin/bash -c "cd ${PROJECT_DIR} && npm install" || { echo 'npm install failed' ; exit 1; } - docker exec ${CONTAINER_NAME} /bin/bash -c "rm -f ${PROJECT_DIR}/.npmrc" - docker exec ${CONTAINER_NAME} supervisorctl start npm -- --reset-cache + docker exec ${CONTAINER_NAME} supervisorctl start npm docker logs -f ${CONTAINER_NAME} ;; metro-logs) - docker exec -it ${CONTAINER_NAME} cat /var/log/app/npm.log + echo "Press CTRL + C to safely exit. It won't stop the server." + docker exec -it ${CONTAINER_NAME} supervisorctl tail -f npm stdout ;; connect-android) @@ -72,13 +85,14 @@ case $1 in echo "Please set the SSH_KEY environment variable before running the script." exit 1 fi + SSH_KEY_PATH="$HOME/.ssh/id_docker_dev" # generate ssh key - if [ ! -f "${SSH_KEY}" ]; then - ssh-keygen -t ed25519 -f "${SSH_KEY}" -N "" - echo "SSH key generated at ${SSH_KEY}" + if [ ! -f "${SSH_KEY_PATH}" ]; then + ssh-keygen -t ed25519 -f ${SSH_KEY_PATH} -N "" + echo "SSH key generated at ${SSH_KEY_PATH}" else - echo "SSH key already exists at ${SSH_KEY}" + echo "SSH key already exists at ${SSH_KEY_PATH}" fi # Check if Docker is running @@ -102,7 +116,7 @@ case $1 in echo "SSH config already contains the Docker IP." else echo "Adding Docker IP to SSH config..." - echo -e "Host ${CONTAINER_IP}\n\tPort 22\n\tUser root\n\tPubkeyAuthentication yes\n\tIdentityFile ${SSH_KEY}" >> ~/.ssh/config + echo -e "Host ${CONTAINER_IP}\n\tPort 22\n\tUser root\n\tPubkeyAuthentication yes\n\tIdentityFile ${SSH_KEY_PATH}" >> ~/.ssh/config echo "Docker IP added to SSH config." fi ;; diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100755 index 4d586e3..0000000 --- a/entrypoint.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -set -e - -# Check if GH_TOKEN exists -if [[ -n $GH_TOKEN ]]; then - # Github auth for private npm packages - su -c "echo \"//github.com/:_authToken=$GH_TOKEN\" > /home/app/.npmrc" -fi - -# install npm dependencies -su -c "cd /home/app && npm install" - -# If GH_TOKEN exists, remove the token -if [[ -n $GH_TOKEN ]]; then - su -c "rm -f /home/app/.npmrc" -fi - - -# run supervisord -exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf \ No newline at end of file diff --git a/supervisord.conf b/supervisord.conf index 4421cb1..eb6c794 100644 --- a/supervisord.conf +++ b/supervisord.conf @@ -19,10 +19,10 @@ stdout_logfile=/var/log/supervisor/%(program_name)s.log stderr_logfile=/var/log/supervisor/%(program_name)s.log [program:npm] -command=bash -c "npm start -- --reset-cache --docker" +command=npm start -- --reset-cache user=root -autostart=false -autorestart=false +autostart=true +autorestart=true directory=/home/app stdout_logfile=/var/log/app/%(program_name)s.log stderr_logfile=/var/log/app/%(program_name)s.log \ No newline at end of file