Rework the docker image and bootstrap tooling
The old docker image installed nginx, mysql, and refstack in an all in one container. This is not the preferred way to do containers as each container should run a single process instead. Additionally the old builds relied on PYTHONPATH munging rather than properly installing the refstack project. We can fix that by splitting up the services into per process containers. Refstack now runs in a dedicated container based on opendev's python-builder and python-base staged builds. We then run a MariaDB along side refstack using docker-compose. A later addition can add in a webserver and SSL termination. Note that the end goal here is to have something we can deploy in OpenDev using ansible and docker-compose to manage the refstack service. This needs a lot of cleanup, but this records a working point in time. Change-Id: I9d1c0a1b78a826266ffa67b0f58381a39a8ea89a
This commit is contained in:
parent
b1403ead09
commit
d71c01ba1e
|
@ -1,12 +0,0 @@
|
|||
*.egg*
|
||||
*.py[cod]
|
||||
.coverage
|
||||
.testrepository/
|
||||
.tox/
|
||||
.venv/
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
build/
|
||||
cover/
|
||||
dist
|
||||
.git/
|
|
@ -0,0 +1,43 @@
|
|||
# Copyright (c) 2019 Red Hat, Inc.
|
||||
# Copyright (c) 2020 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM opendevorg/python-builder as builder
|
||||
|
||||
COPY . /tmp/src
|
||||
RUN /tmp/src/tools/install-js-tools.sh
|
||||
RUN assemble
|
||||
|
||||
RUN cd /tmp/src && yarn install
|
||||
|
||||
# Refstack's docs are built and then hosted by refstack UI
|
||||
RUN python -m venv /tmp/venv \
|
||||
&& /tmp/venv/bin/pip install beautifulsoup4 docutils \
|
||||
&& /tmp/venv/bin/python /tmp/src/tools/convert-docs.py -o /tmp/src/refstack-ui/app/components/about/templates /tmp/src/doc/source/*.rst \
|
||||
&& rm -rf /tmp/venv
|
||||
|
||||
FROM opendevorg/python-base as refstack
|
||||
|
||||
COPY --from=builder /output/ /output
|
||||
COPY --from=builder /tmp/src/refstack-ui/app/ /refstack-ui/app
|
||||
COPY --from=builder /tmp/src/docker/entrypoint.sh /usr/bin/entrypoint
|
||||
# TODO this should be fixed probably through proper js packaging
|
||||
RUN rm /refstack-ui/app/assets/lib
|
||||
COPY --from=builder /tmp/src/node_modules/@bower_components/ /refstack-ui/app/assets/lib
|
||||
RUN /output/install-from-bindep \
|
||||
&& rm -rf /output
|
||||
|
||||
ENTRYPOINT ["/usr/bin/entrypoint"]
|
||||
CMD ["pecan", "serve", "/usr/local/lib/python3.7/site-packages/refstack/api/config.py"]
|
|
@ -1,8 +1,3 @@
|
|||
# This is a cross-platform list tracking distribution packages needed for install and tests;
|
||||
# see https://docs.openstack.org/infra/bindep/ for additional information.
|
||||
|
||||
mysql-client [platform:dpkg]
|
||||
mysql-server [platform:dpkg]
|
||||
postgresql
|
||||
postgresql-client [platform:dpkg]
|
||||
|
||||
gcc [compile test]
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# Version 2 is the latest that is supported by docker-compose in
|
||||
# Ubuntu Xenial.
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
image: docker.io/library/mariadb:10.4
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "secret"
|
||||
MYSQL_DATABASE: "refstack"
|
||||
MYSQL_USER: "refstack"
|
||||
MYSQL_PASSWORD: "refstack"
|
||||
refstack-api:
|
||||
depends_on:
|
||||
- mariadb
|
||||
image: opendevorg/refstack:latest
|
||||
restart: always
|
||||
ports:
|
||||
- "8000:8000"
|
||||
volumes:
|
||||
# These paths must be fully rooted apparently. Update them to your
|
||||
# repo location.
|
||||
- /home/clark/src/openstack/refstack/docker/refstack.conf:/etc/refstack.conf
|
||||
- /home/clark/src/openstack/refstack/docker/config.json:/refstack-ui/app/config.json
|
|
@ -1,49 +0,0 @@
|
|||
FROM ubuntu:16.04
|
||||
EXPOSE 443
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
ENV PYTHONPATH=/home/dev/refstack \
|
||||
SQL_DIR=/home/dev/mysql
|
||||
ENV REFSTACK_MYSQL_URL="mysql+pymysql://root@localhost/refstack?unix_socket=${SQL_DIR}/mysql.socket&charset=utf8"
|
||||
|
||||
ADD /docker/scripts/* /usr/bin/
|
||||
ADD . /refstack
|
||||
|
||||
RUN apt update -y \
|
||||
&& apt upgrade -y
|
||||
|
||||
RUN apt install -y curl \
|
||||
sudo \
|
||||
&& groupadd dev \
|
||||
&& useradd -g dev -s /bin/bash -d /home/dev -m dev \
|
||||
&& ( umask 226 && echo "dev ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/50_dev ) \
|
||||
&& curl -sL https://deb.nodesource.com/setup_8.x -o /tmp/setup_8.x.sh \
|
||||
&& sudo bash /tmp/setup_8.x.sh \
|
||||
&& apt install -y git \
|
||||
libffi-dev \
|
||||
libmysqlclient-dev \
|
||||
mysql-client \
|
||||
mysql-server \
|
||||
nginx \
|
||||
nodejs \
|
||||
python-dev \
|
||||
python-pip \
|
||||
python3-dev \
|
||||
sudo \
|
||||
vim \
|
||||
wget \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& rm -rf /var/lib/mysql/* \
|
||||
&& rm -rf /etc/nginx/sites-enabled/default \
|
||||
&& npm install -g yarn \
|
||||
&& pip install virtualenv tox httpie
|
||||
|
||||
USER dev
|
||||
|
||||
RUN echo "cd /home/dev/refstack" >> /home/dev/.bashrc \
|
||||
&& echo "alias activate='source /home/dev/refstack/.venv/bin/activate'" >> /home/dev/.bashrc \
|
||||
&& echo "alias mysql='mysql --no-defaults -S ${SQL_DIR}/mysql.socket'" >> /home/dev/.bashrc \
|
||||
&& start.sh \
|
||||
&& api-init-db
|
||||
|
||||
CMD start.sh -s
|
|
@ -0,0 +1 @@
|
|||
{"refstackApiUrl": "http://127.0.0.1:8000/v1"}
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
refstack-manage upgrade --revision head
|
||||
$@
|
|
@ -0,0 +1,16 @@
|
|||
[DEFAULT]
|
||||
debug = true
|
||||
verbose = true
|
||||
ui_url = http://127.0.0.1:8000
|
||||
|
||||
[api]
|
||||
static_root = /refstack-ui/app
|
||||
template_path = /refstack-ui/app
|
||||
app_dev_mode = true
|
||||
api_url = http://127.0.0.1:8000
|
||||
|
||||
[database]
|
||||
connection = "mysql+pymysql://refstack:refstack@mariadb/refstack?charset=utf8"
|
||||
|
||||
[osid]
|
||||
openstack_openid_endpoint = https://172.17.42.1:8443/accounts/openid2
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/bash
|
||||
/home/dev/refstack/.venv/bin/python /home/dev/refstack/bin/refstack-manage --log-file /dev/null version 2>/dev/null
|
|
@ -1,7 +0,0 @@
|
|||
#!/bin/bash
|
||||
[[ ${DEBUG_MODE} ]] && set -x
|
||||
mysql --no-defaults -S ${SQL_DIR}/mysql.socket -e 'CREATE DATABASE refstack;'
|
||||
mysql --no-defaults -S ${SQL_DIR}/mysql.socket -e 'set @@global.show_compatibility_56=ON;'
|
||||
|
||||
cd /home/dev/refstack
|
||||
.venv/bin/python bin/refstack-manage upgrade --revision head
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
[[ ${DEBUG_MODE} ]] && set -x
|
||||
echo "Syncing project files..."
|
||||
rsync -avr /refstack /home/dev --exclude-from '/refstack/.gitignore' > /dev/null && \
|
||||
echo "Done!"
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
[[ ${DEBUG_MODE} ]] && set -x
|
||||
api-sync
|
||||
cd /home/dev/refstack
|
||||
.venv/bin/pecan serve refstack/api/config.py
|
|
@ -1,78 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
wait_for_line () {
|
||||
while read line; do
|
||||
echo "$line" | grep -q "$1" && break
|
||||
done < "$2"
|
||||
# Read the fifo for ever otherwise process would block
|
||||
cat "$2" >/dev/null &
|
||||
}
|
||||
|
||||
build_tmpl () {
|
||||
TEMPLATE="$1"
|
||||
TARGET="$2"
|
||||
cat ${TEMPLATE} | \
|
||||
while read LINE; do
|
||||
NEWLINE=$(eval echo ${LINE})
|
||||
[[ ! -z "$NEWLINE" ]] && echo ${NEWLINE}
|
||||
done > ${TARGET}
|
||||
}
|
||||
|
||||
start_mysql () {
|
||||
# Start MySQL process for tests
|
||||
[ ! -d ${SQL_DIR} ] && mkdir ${SQL_DIR}
|
||||
sudo chown dev:dev ${SQL_DIR}
|
||||
rm -rf ${SQL_DIR}/out && mkfifo ${SQL_DIR}/out
|
||||
rm -rf ${SQL_DIR}/mysql.socket
|
||||
# On systems like Fedora here's where mysqld can be found
|
||||
PATH=$PATH:/usr/libexec
|
||||
mysqld --no-defaults --datadir=${SQL_DIR} --pid-file=${SQL_DIR}/mysql.pid \
|
||||
--socket=${SQL_DIR}/mysql.socket --skip-networking \
|
||||
--skip-grant-tables &> ${SQL_DIR}/out &
|
||||
# Wait for MySQL to start listening to connections
|
||||
wait_for_line "mysqld: ready for connections." ${SQL_DIR}/out
|
||||
}
|
||||
|
||||
build_refstack_env () {
|
||||
api-sync
|
||||
cd /home/dev/refstack
|
||||
[ ! -d .venv ] && virtualenv .venv
|
||||
.venv/bin/pip install -r requirements.txt
|
||||
#Install some dev tools
|
||||
.venv/bin/pip install pymysql httpie
|
||||
cd /home/dev/refstack
|
||||
yarn
|
||||
|
||||
build_tmpl /refstack/docker/templates/config.json.tmpl /home/dev/refstack/refstack-ui/app/config.json
|
||||
build_tmpl /refstack/docker/templates/refstack.conf.tmpl /home/dev/refstack.conf
|
||||
sudo cp /home/dev/refstack.conf /etc
|
||||
}
|
||||
|
||||
start_nginx () {
|
||||
[ ! -d /etc/nginx/certificates ] && sudo mkdir /etc/nginx/certificates
|
||||
sudo cp /refstack/docker/nginx/refstack_dev.key /etc/nginx/certificates
|
||||
sudo cp /refstack/docker/nginx/refstack_dev.crt /etc/nginx/certificates
|
||||
sudo cp /refstack/docker/nginx/refstack-site.conf /etc/nginx/sites-enabled/
|
||||
sudo nginx
|
||||
}
|
||||
|
||||
while getopts ":s" opt; do
|
||||
case ${opt} in
|
||||
s) SLEEP=true;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ ${DEBUG_MODE} ]] && set -x
|
||||
|
||||
touch /tmp/is-not-ready
|
||||
|
||||
start_mysql
|
||||
start_nginx
|
||||
build_refstack_env
|
||||
|
||||
rm -rf /tmp/is-not-ready
|
||||
|
||||
if [[ ${SLEEP} ]]; then
|
||||
set +x
|
||||
sleep 1024d
|
||||
fi
|
|
@ -1 +0,0 @@
|
|||
{\\"refstackApiUrl\\": \\"https://${REFSTACK_HOST:-127.0.0.1}/v1\\"}
|
|
@ -1,16 +0,0 @@
|
|||
[DEFAULT]
|
||||
debug = true
|
||||
verbose = true
|
||||
ui_url = https://${REFSTACK_HOST:-127.0.0.1}
|
||||
|
||||
[api]
|
||||
static_root = /home/dev/refstack/refstack-ui/app
|
||||
template_path = /home/dev/refstack/refstack-ui/app
|
||||
app_dev_mode = true
|
||||
api_url = https://${REFSTACK_HOST:-127.0.0.1}
|
||||
|
||||
[database]
|
||||
connection = ${REFSTACK_MYSQL_URL}
|
||||
|
||||
[osid]
|
||||
openstack_openid_endpoint = https://172.17.42.1:8443/accounts/openid2
|
|
@ -1,6 +1,6 @@
|
|||
SQLAlchemy>=0.8.3
|
||||
alembic==0.5.0
|
||||
beaker==1.6.5.post1
|
||||
alembic
|
||||
beaker
|
||||
beautifulsoup4
|
||||
cryptography>=1.0,!=1.3.0 # BSD/Apache-2.0
|
||||
docutils>=0.11
|
||||
|
@ -15,3 +15,4 @@ requests-cache>=0.4.9
|
|||
jsonschema>=2.0.0,<3.0.0
|
||||
PyJWT>=1.0.1 # MIT
|
||||
WebOb>=1.7.1 # MIT
|
||||
PyMySQL>=0.6.2,!=0.6.4
|
||||
|
|
153
run-in-docker
153
run-in-docker
|
@ -1,153 +0,0 @@
|
|||
#!/bin/bash
|
||||
TAG=$(BRANCH=$(git status -bs| grep "##" | awk '{print $2}'); echo ${BRANCH##*/})
|
||||
IMAGE="refstack:${TAG}"
|
||||
CONTAINER="refstack_${TAG}"
|
||||
PROJ_DIR=$(git rev-parse --show-toplevel)
|
||||
|
||||
function usage () {
|
||||
set +x
|
||||
echo "Usage: $0 [OPTIONS] [COMMAND]"
|
||||
echo "Build '${IMAGE}' image if it is does not exist."
|
||||
echo "Run '${CONTAINER}' container and execute COMMAND in it."
|
||||
echo "Default COMMAND is 'api-up'"
|
||||
echo "If container '${CONTAINER}' exists (running or stopped) it will be reused."
|
||||
echo "If you want to get access to your local RefStack not only from localhost, "
|
||||
echo "please specify public RefStack host:port in env[REFSTACK_HOST]."
|
||||
echo "You can customize RefStack API config by editing docker/refstack.conf.tmpl."
|
||||
echo "It is bash template. You can use \${SOME_ENV_VARIABLE} in it."
|
||||
echo "Default is 127.0.0.1:443"
|
||||
echo ""
|
||||
echo " -r Force delete '${CONTAINER}' container and run it again."
|
||||
echo " Main usecase for it - updating config from templates"
|
||||
echo " -b Force delete '${IMAGE}' image and build it again"
|
||||
echo " Main usecase for it - force build new python/js env"
|
||||
echo " -i Run container with isolated MySQL data."
|
||||
echo " By default MySQL data stores in refstack_data_DATA-BASE-REVISON container"
|
||||
echo " It reuses if such container exists. If you want to drop DB data, just execute"
|
||||
echo " sudo docker rm refstack_data_DATA-BASE-REVISON"
|
||||
echo " -d Turn on debug information"
|
||||
echo " -h Print this usage message"
|
||||
echo ""
|
||||
echo ""
|
||||
echo "Using examples:"
|
||||
echo ""
|
||||
echo "Run RefStack API:"
|
||||
echo "$ ./run-in-docker"
|
||||
echo ""
|
||||
echo "Run RefStack API by hands:"
|
||||
echo "$ ./run-in-docker bash"
|
||||
echo "$ activate"
|
||||
echo "$ pecan serve refstack/api/config.py"
|
||||
echo ""
|
||||
echo "Open shell in container:"
|
||||
echo "$ ./run-in-docker bash"
|
||||
echo ""
|
||||
echo "Open mysql console in container:"
|
||||
echo "$ ./run-in-docker bash"
|
||||
echo "$ mysql"
|
||||
}
|
||||
|
||||
build_image () {
|
||||
sudo docker rm -f ${CONTAINER}
|
||||
PREV_ID=$(sudo docker images refstack | grep ${TAG} | awk '{print $3}')
|
||||
echo "Try to build ${IMAGE} image"
|
||||
sudo docker build -t ${IMAGE} -f ${PROJ_DIR}/docker/Dockerfile ${PROJ_DIR} || exit $?
|
||||
NEW_ID=$(sudo docker images refstack | grep ${TAG} | awk '{print $3}')
|
||||
if [[ ${PREV_ID} ]] && [[ ! ${PREV_ID} == ${NEW_ID} ]]; then
|
||||
sudo docker rmi -f ${PREV_ID} && echo "Previous image removed"
|
||||
fi
|
||||
}
|
||||
|
||||
wait_ready() {
|
||||
while true; do
|
||||
echo "Wait while container is not ready"
|
||||
sudo docker exec ${CONTAINER} [ ! -e /tmp/is-not-ready ] && \
|
||||
echo "Container ${CONTAINER} is running!" && break
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
run_container (){
|
||||
echo "Stop all other refstack containers"
|
||||
for id in $(sudo docker ps -q); do
|
||||
NAME=$(sudo docker inspect --format='{{.Name}}' $id)
|
||||
if [[ ${NAME} == /refstack_* ]] && [[ ! ${NAME} == "/${CONTAINER}" ]]; then
|
||||
echo "Stopped container ${NAME}" && sudo docker stop $id
|
||||
fi
|
||||
done
|
||||
if [[ $(sudo docker ps -a | grep "${CONTAINER}") ]]; then
|
||||
echo "Container ${CONTAINER} exists it is reused"
|
||||
sudo docker start ${CONTAINER}
|
||||
wait_ready
|
||||
else
|
||||
echo "Try to run container ${CONTAINER}"
|
||||
sudo docker run -d \
|
||||
-e REFSTACK_HOST=${REFSTACK_HOST:-127.0.0.1} \
|
||||
-e DEBUG_MODE=${DEBUG_MODE} \
|
||||
-v ${PROJ_DIR}:/refstack:ro -p 443:443 --name ${CONTAINER} \
|
||||
${IMAGE} start.sh -s
|
||||
wait_ready
|
||||
if [[ ! ${ISOLATED_DB} ]]; then
|
||||
DB_VERSION=$(sudo docker exec -it ${CONTAINER} api-db-version)
|
||||
DB_CONTAINER=refstack_data_${DB_VERSION::-1}
|
||||
sudo docker rm -f ${CONTAINER}
|
||||
if [[ ! $(sudo docker ps -a | grep "${DB_CONTAINER}") ]]; then
|
||||
sudo docker run -v /home/dev/mysql --name ${DB_CONTAINER} ubuntu /bin/true
|
||||
echo "Container with mysql data ${DB_CONTAINER} created"
|
||||
sudo docker run -d \
|
||||
-e REFSTACK_HOST=${REFSTACK_HOST:-127.0.0.1} \
|
||||
-e DEBUG_MODE=${DEBUG_MODE} \
|
||||
-v ${PROJ_DIR}:/refstack:ro --volumes-from ${DB_CONTAINER} -p 443:443 \
|
||||
--name ${CONTAINER} ${IMAGE}
|
||||
wait_ready
|
||||
sudo docker exec ${CONTAINER} api-init-db
|
||||
echo "DB init done"
|
||||
else
|
||||
sudo docker run -d \
|
||||
-e REFSTACK_HOST=${REFSTACK_HOST:-127.0.0.1} \
|
||||
-e DEBUG_MODE=${DEBUG_MODE} \
|
||||
-v ${PROJ_DIR}:/refstack:ro --volumes-from ${DB_CONTAINER} -p 443:443 \
|
||||
--name ${CONTAINER} ${IMAGE}
|
||||
echo "Container with mysql data ${DB_CONTAINER} attached to ${CONTAINER}"
|
||||
wait_ready
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
COMMAND=""
|
||||
while [[ $1 ]]
|
||||
do
|
||||
case "$1" in
|
||||
-h) usage
|
||||
exit 0;;
|
||||
-r) echo "Try to remove old ${CONTAINER} container"
|
||||
sudo docker rm -f ${CONTAINER}
|
||||
shift;;
|
||||
-i) echo "Run container with isolated MySQL data."
|
||||
echo "By default MySQL data stores in refstack_data_[DATA-BASE-REVISON] container"
|
||||
echo "It reuses if such container exists. If you want to drop DB data, just execute"
|
||||
echo "sudo docker rm ${DB_CONTAINER}"
|
||||
ISOLATED_DB=true
|
||||
shift;;
|
||||
-b) FORCE_BUILD=true
|
||||
shift;;
|
||||
-d) DEBUG_MODE=true
|
||||
shift;;
|
||||
*) COMMAND="${COMMAND} $1"
|
||||
shift;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ ${DEBUG_MODE} ]] && set -x
|
||||
|
||||
#Build proper image if it does not exist of force rebuild fired
|
||||
if [[ ${FORCE_BUILD} ]] || [[ ! $(sudo docker images refstack | grep ${TAG}) ]]; then
|
||||
build_image
|
||||
fi
|
||||
#Run or start(if it exists) proper container
|
||||
[[ ! $(sudo docker ps | grep ${CONTAINER}) ]] && run_container
|
||||
|
||||
sudo docker exec -it ${CONTAINER} ${COMMAND:-api-up}
|
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2017 Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
if [ $EUID -ne 0 ] ; then
|
||||
SUDO='sudo -E'
|
||||
fi
|
||||
|
||||
if type apt-get; then
|
||||
# Install https transport - otherwise apt-get HANGS on https urls
|
||||
# Install curl so the curl commands work
|
||||
# Install gnupg2 so that the apt-key add works
|
||||
$SUDO apt-get update
|
||||
$SUDO apt-get install -y apt-transport-https curl gnupg2
|
||||
# Install recent NodeJS repo
|
||||
curl -sS https://deb.nodesource.com/gpgkey/nodesource.gpg.key | $SUDO apt-key add -
|
||||
echo "deb https://deb.nodesource.com/node_10.x bionic main" | $SUDO tee /etc/apt/sources.list.d/nodesource.list
|
||||
# Install yarn repo
|
||||
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | $SUDO apt-key add -
|
||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | $SUDO tee /etc/apt/sources.list.d/yarn.list
|
||||
$SUDO apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
$SUDO apt-get -q --option "Dpkg::Options::=--force-confold" --assume-yes \
|
||||
install nodejs yarn
|
||||
elif type yum; then
|
||||
$SUDO curl https://dl.yarnpkg.com/rpm/yarn.repo -o /etc/yum.repos.d/yarn.repo
|
||||
$SUDO $(dirname $0)/install-js-repos-rpm.sh
|
||||
$SUDO yum -y install nodejs yarn
|
||||
elif type zypper; then
|
||||
$SUDO zypper install -y nodejs10 npm10
|
||||
$SUDO npm install yarn
|
||||
elif type brew; then
|
||||
brew install nodejs yarn
|
||||
else
|
||||
echo "Unsupported platform"
|
||||
fi
|
Loading…
Reference in New Issue