docker-compose bootstrap scripts (#1217)

Closes #1216
This commit is contained in:
Sam Darwin
2024-08-30 07:13:26 -06:00
committed by GitHub
parent 161d3b1387
commit 3233fb22c7
9 changed files with 1180 additions and 16 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
docker/* eol=lf

View File

@@ -39,14 +39,14 @@ Then run:
# start our services (and build them if necessary) # start our services (and build them if necessary)
$ docker compose up $ docker compose up
# to create a superuser
$ docker compose run --rm web python manage.py createsuperuser
# to create database migrations # to create database migrations
$ docker compose run --rm web python manage.py makemigrations $ docker compose run --rm web python manage.py makemigrations
# to run database migrations # to run database migrations
$ docker compose run --rm web python manage.py migrate $ docker compose run --rm web python manage.py migrate
# to create a superuser
$ docker compose run --rm web python manage.py createsuperuser
``` ```
This will create the Docker image, install dependencies, start the services This will create the Docker image, install dependencies, start the services
@@ -66,7 +66,7 @@ npm install -g yarn
``` ```
# Each time - rebuild styles.css # Each time - rebuild styles.css
yarn yarn
yarn build yarn build # or on windows: yarn dev-windows
cp static/css/styles.css static_deploy/css/styles.css cp static/css/styles.css static_deploy/css/styles.css
``` ```

View File

@@ -1,5 +1,3 @@
version: "3.7"
services: services:
db: db:

View File

@@ -1,17 +1,94 @@
## Development Setup Notes ## Development Setup Notes
The procedure to configure a development environment is mainly covered in the top-level README.md. This document will contain more details about installing prerequisites: Just, Python 3.11, Docker, and Docker Compose. The procedure to configure a development environment is mainly covered in the top-level README.md. This document will contain more details about installing prerequisites: Just, Python, Docker, and Docker Compose.
- [Development Setup Notes](#development-setup-notes) - [Development Setup Notes](#development-setup-notes)
- [Windows](#windows) - [Windows](#windows)
- [Ubuntu 22.04](#ubuntu-2204) - [Ubuntu 22.04](#ubuntu-2204)
- [macOS](#macOS)
- [Local Development](#local-development) - [Local Development](#local-development)
- [Social Login with django-allauth](#social-login-with-django-allauth) - [Social Login with django-allauth](#social-login-with-django-allauth)
## Windows ## Windows
(Tested on: Windows 2022 Server) There are multiple alternatives to choose from.
Method 1:
The script dev-bootstrap-win.ps1 will automatically install prerequisites, and with the -all or -launch flag will also run docker-compose.
Open a Powershell terminal (Admin mode).
Enable Powershell scripts with `Set-ExecutionPolicy Bypass`.
Clone your fork of the repo, and run the script `.\docs\scripts\dev-bootstrap-win.ps1`, or just download a copy of the script by itself, and run it.
```
curl -o dev-bootstrap-win.ps1 https://raw.githubusercontent.com/boostorg/website-v2/develop/docs/scripts/dev-bootstrap-win.ps1
.\dev-bootstrap-win.ps1
```
Method 2:
Or, instead of running the script, manually install the necessary packages as discussed below. It's only necessary to run each command if that package is missing.
Install choco
```
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
# refresh environment
$env:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.."
Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
refreshenv
```
Install git
```
choco install -y --no-progress git
```
Install python
```
choco install -y --no-progress python
```
Install just
```
choco install -y --no-progress just
```
Install nvm, npm, and yarn
```
choco install -y --no-progress nvm
# close and open the powershell terminal (admin)
nvm install 20
nvm use 20
npm install -g yarn
```
Install Docker Desktop
```
choco install -y --no-progress docker-desktop
```
In a desktop GUI window, run Docker Desktop, and complete the installation.
Clone the repository and switch to that directory.
```
mkdir -p $HOME\github\_your_user_name_
cd $HOME\github\_your_user_name_
git clone https://github.com/_your_user_name_/website-v2
cd website-v2
cp env.template .env
```
Edit the .env, adding AWS keys.
Continue to the instructions in the top-level README.md file.
Method 3:
This is a more complicated WSL method.
In Powershell, install WSL: In Powershell, install WSL:
``` ```
@@ -43,15 +120,25 @@ Continue (as root) to the instructions in the top-level README.md file.
## Ubuntu 22.04 ## Ubuntu 22.04
Check if python3 is installed. Method 1:
```
python3 --version
```
or The script dev-bootstrap-linux.sh will automatically install prerequisites, and with the --all or --launch flag will also run docker-compose.
While the dev-bootstrap-linux.sh script should be run as a standard user, after it has been all set up, later you will generally run "docker compose" as root. This is to assure that the permissions match inside the container where the user is also root. Another option is to eventually add a Docker Desktop method for linux to the script.
``` ```
apt-get install -y python3 curl -o dev-bootstrap-linux.sh https://raw.githubusercontent.com/boostorg/website-v2/develop/docs/scripts/dev-bootstrap-linux.sh
chmod 755 dev-bootstrap-linux.sh
./dev-bootstrap-linux.sh
```
Method 2:
Or, instead of running the script, manually install the necessary packages as discussed below. It's only necessary to run each command if that package is missing.
Install python
```
sudo apt-get install -y python3
``` ```
Install `makedeb` (as a standard user, not root). Install `makedeb` (as a standard user, not root).
@@ -72,6 +159,15 @@ cd just
makedeb -si makedeb -si
``` ```
Install nvm, npm, and yarn, if not installed.
```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
. ~/.bashrc
nvm install 20
nvm use 20
npm install -g yarn
```
Install docker and docker-compose. Install docker and docker-compose.
``` ```
sudo apt-get update sudo apt-get update
@@ -100,9 +196,87 @@ cd website-v2
cp env.template .env cp env.template .env
``` ```
Edit the .env, adding AWS keys.
Continue (as the root user) to the instructions in the top-level README.md file. Or if using WSL, review the last few steps in that section again. Continue (as the root user) to the instructions in the top-level README.md file. Or if using WSL, review the last few steps in that section again.
The advantage of running `docker compose` as root is the userid (0) will match the containers and the shared files. On Linux, the advantage of running `docker compose` as root is the userid (0) will match the containers and the shared files. Another option is
to install Docker Desktop, which would allow you to stay as a regular user.
## macOS
Method 1:
The script dev-bootstrap-macos.sh will automatically install prerequisites, and with the --all or --launch flag will also run docker-compose.
As a standard user account, clone your fork of the repo, and run the script `docs/scripts/dev-bootstrap-macos.ps1`, or just download a copy of the script by itself, and run it.
```
curl -o dev-bootstrap-macos.sh https://raw.githubusercontent.com/boostorg/website-v2/develop/docs/scripts/dev-bootstrap-macos.sh
chmod 755 dev-bootstrap-macos.sh
./dev-bootstrap-macos.sh
```
Method 2:
Or, instead of running the script, manually install the necessary packages as discussed below. It's only necessary to run each command if that package is missing.
Install brew
```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
Install rosetta
```
sudo softwareupdate --install-rosetta --agree-to-license
```
Install git
```
brew install git
```
Install python
```
brew install python3
```
Install just
```
brew install just
```
Install nvm, npm, and yarn
```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
. ~/.zprofile
nvm install 20
nvm use 20
npm install -g yarn
```
Install docker and docker-compose
```
curl -o /tmp/Docker.dmg https://desktop.docker.com/mac/main/arm64/160616/Docker.dmg
sudo hdiutil attach /tmp/Docker.dmg
sudo /Volumes/Docker/Docker.app/Contents/MacOS/install
sudo hdiutil detach /Volumes/Docker
```
In a desktop GUI window, run Docker Desktop, and complete the installation.
Clone the repository and switch to that directory.
```
mkdir -p ~/github/_your_user_name_
cd ~/github/_your_user_name_
git clone https://github.com/_your_user_name_/website-v2
cd website-v2
cp env.template .env
```
Edit the .env, adding AWS keys.
Continue to the instructions in the top-level README.md file.
## Local Development ## Local Development

View File

@@ -1,4 +1,4 @@
## Mailman ## Mailman
Information about mailman3 server instances is covered in https://github.com/cppalliance/temp-site-documentation Information about mailman3 server instances is covered in https://github.com/cppalliance/website-v2-operations

View File

@@ -0,0 +1,298 @@
#!/bin/bash
# Copyright 2024 Sam Darwin
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
set -e
# set -x
scriptname="dev-bootstrap-linux.sh"
# set defaults:
prereqsoption="yes"
# docker_mode either "native" or "desktop" (Docker Desktop). Only support "native" currently.
docker_mode="native"
docker_explanation="On Linux, there are two ways to run Docker. Either the standard native docker installation, or Docker Desktop, which runs inside a virtual machine. The most common installation is standard docker, so that is what is supported by this script currently. In the future, Docker Desktop support could be added. Each method has pros and cons. It's important that the user inside the Django containers is the same as the user on the host machine outside the containers, so that file ownership matches up. Since the user is 'root' inside the containers, it should be 'root' on the host machine. Therefore, after getting set up with this script, any development work should be done as 'root'. That means, run 'sudo su -' before using docker-compose. Docker Desktop would be an alternative to that requirement, and allow running as a regular user account. But with some downside, that it is not a typical Docker installation, as found on a server."
if [[ ${docker_mode} == "native" ]]; then
repo_path_base="/opt/github"
completion_message_1="When doing development work, switch to the root user 'sudo su -', cd to that directory location, and run 'docker compose up -d'. While this script works as a normal user, you should be 'root' when running docker compose."
possible_sudo="sudo"
shell_initialization_file=/root/.bashrc
fi
if [[ ${docker_mode} == "desktop" ]]; then
repo_path_base="${HOME}/github"
completion_message_1="When doing development work, cd to that directory location, and run 'docker compose up -d'"
possible_sudo=""
shell_initialization_file=~/.bashrc
fi
# READ IN COMMAND-LINE OPTIONS
TEMP=$(getopt -o h:: --long repo:,help::,launch::,prereqs::,all:: -- "$@")
eval set -- "$TEMP"
# extract options and their arguments into variables.
while true ; do
case "$1" in
-h|--help)
helpmessage="""
usage: $scriptname [-h] [--repo REPO] [--launch] [--all]
Install all required packages (this is the default action), launch docker-compose, or both.
optional arguments:
-h, --help Show this help message and exit
--repo REPO Name of repository to set up. Example: https://github.com/boostorg/website-v2. You should specify your own fork.
--launch Run docker-compose. No packages.
--all Both packages and launch.
"""
echo ""
echo "$helpmessage" ;
echo ""
exit 0
;;
--repo)
case "$2" in
"") repooption="" ; shift 2 ;;
*) repooption=$2 ; shift 2 ;;
esac ;;
--launch)
launchoption="yes" ; prereqsoption="no" ; shift 2 ;;
--all)
prereqsoption="yes" ; launchoption="yes" ; shift 2 ;;
--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done
echo "Chosen options: pre: $prereqsoption launch: $launchoption repo: $repooption"
# Determine git repo
detected_repo_url=$(git config --get remote.origin.url 2> /dev/null || echo "empty")
detected_repo_name=$(basename -s .git "$(git config --get remote.origin.url)" 2> /dev/null || echo "empty")
# Currently unused. Could be uncommented if needed:
# detected_repo_org=$(basename $(dirname "${detected_repo_url}"))
detected_repo_path=$(git rev-parse --show-toplevel 2> /dev/null || echo "nofolder")
detected_repo_path_base=$(dirname "${detected_repo_path}")
if [[ -n "${detected_repo_path}" && "${detected_repo_path}" != "nofolder" ]]; then
detected_repo_user=$(stat -c "%U" "${detected_repo_path}")
fi
if [[ -n "${detected_repo_url}" && "${detected_repo_url}" != "empty" && -n "${repooption}" ]]; then
echo "You have specified a repo, but you are also running this script from within a repo."
echo "This is indeterminate. Choose one or the other. Exiting."
exit 1
elif [[ -n "${detected_repo_url}" && "${detected_repo_url}" != "empty" ]]; then
# existing repo
if [[ "${docker_mode}" == "native" && "${detected_repo_user}" != "root" ]]; then
echo ""
echo "${docker_explanation}"
echo ""
echo "The script is currently running in 'native' mode, however a non-root user owns the repository folder."
echo "The choices are:"
echo "1. cd outside the current repo folder, and re-run the script, so that it can set things up as 'root'"
echo "2. Install 'Docker Desktop', and switch the mode of this script to 'Docker Desktop' mode. (Not yet supported)."
echo ""
echo "Exiting"
exit 1
fi
repo_url=${detected_repo_url}
repo_name=${detected_repo_name}
repo_path=${detected_repo_path}
repo_path_base=${detected_repo_path_base}
echo "The repo path is ${repo_path}"
cd "${repo_path}"
if [ ! -f .env ]; then
cp env.template .env
fi
else
if [ -n "${repooption}" ]; then
echo "You have specified a repository on the command line. That will be preferred. ${repooption}"
repo_url=${repooption}
else
echo "Please enter a full git repository url with a format such as https:://github.com/_your_name_/website-v2"
read -r repo_url
fi
repo_name=$(basename -s .git "$repo_url" 2> /dev/null || echo "empty")
repo_org_part_1=$(dirname "${repo_url}")
repo_org=$(basename "$repo_org_part_1")
repo_path_base="${repo_path_base}/${repo_org}"
repo_path="${repo_path_base}/${repo_name}"
echo "The path will be ${repo_path}"
${possible_sudo} mkdir -p "${repo_path_base}"
cd "${repo_path_base}"
if [ ! -d "${repo_name}" ]; then
${possible_sudo} git clone "${repo_url}"
fi
cd "${repo_name}"
if [ ! -f .env ]; then
${possible_sudo} cp env.template .env
fi
fi
# Check .env file
if grep STATIC_CONTENT_AWS_ACCESS_KEY_ID .env | grep changeme; then
unsetawskey="yes"
fi
if grep STATIC_CONTENT_AWS_SECRET_ACCESS_KEY .env | grep changeme; then
unsetawskey="yes"
fi
if [[ $unsetawskey == "yes" ]]; then
echo "There appears to be aws keys in your .env file that says 'changeme'. Please set them before proceeding."
echo "Talk to an administrator or other developer to get the keys."
read -r -p "Do you want to continue? " -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo "we are continuing"
else
echo "did not receive a Yy. Exiting."
exit 1
fi
fi
if [[ "$prereqsoption" == "yes" ]]; then
# sudo apt-get update
x="\$nrconf{restart} = 'a';"
echo "$x" | sudo tee /etc/needrestart/conf.d/90-autorestart.conf 1>/dev/null
if ! command -v makedeb &> /dev/null
then
echo "Installing makdeb"
MAKEDEB_RELEASE=makedeb bash -ci "$(wget -qO - 'https://shlink.makedeb.org/install')"
fi
if ! command -v git &> /dev/null
then
echo "Installing git"
sudo apt-get install -y git
fi
if ! command -v python3 &> /dev/null
then
echo "Installing python3"
sudo apt-get install -y python3
fi
if ! command -v just &> /dev/null
then
echo "Installing just"
startdir=$(pwd)
sudo mkdir -p /opt/justinstall
CURRENTUSER=$(whoami)
sudo chown "$CURRENTUSER" /opt/justinstall
chmod 777 /opt/justinstall
cd /opt/justinstall
git clone 'https://mpr.makedeb.org/just'
cd just
makedeb -si
cd "$startdir"
fi
if [[ ${docker_mode} == "native" ]]; then
if ! sudo bash -i -c 'command -v nvm &> /dev/null'
then
sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | sudo bash
# shellcheck source=/dev/null
sudo bash -i -c 'nvm install 20; nvm use 20'
echo "Run . ${shell_initialization_file} to enable nvm"
fi
else
if ! command -v nvm &> /dev/null
then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
# shellcheck source=/dev/null
. ${shell_initialization_file}
nvm install 20
nvm use 20
echo "Run . ${shell_initialization_file} to enable nvm"
fi
fi
if [[ ${docker_mode} == "native" ]]; then
if ! sudo bash -i -c 'command -v yarn &> /dev/null'
then
sudo bash -i -c 'npm install -g yarn'
fi
else
if ! command -v yarn &> /dev/null
then
npm install -g yarn
fi
fi
if ! docker compose &> /dev/null ; then
echo "Installing docker-compose"
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# shellcheck disable=SC1091
echo \
deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
fi
# "Add current user to docker group"
sudo usermod -aG docker "$USER"
if [[ ${docker_mode} == "desktop" ]]; then
if ! id | grep docker 1>/dev/null
then
echo "Your user account has just been added to the 'docker' group. Please log out and log in again. Check groups with the id command."
echo "The installation section of this script is complete. After logging in again, you may proceed to manually running docker compose."
echo "Or run this script again with --launch to start containers."
fi
fi
echo "The 'installation' section of this script is complete."
echo "The location of your docker compose installation is ${repo_path}."
echo ""
if [[ "$launchoption" != "yes" ]]; then
echo "You may run this script again with the --launch option, to launch docker compose and run db migrations".
echo ""
fi
echo "${completion_message_1}"
fi
if [[ "$launchoption" == "yes" ]]; then
if [[ "${docker_mode}" == "desktop" ]]; then
if ! command -v nvm &> /dev/null
then
# shellcheck source=/dev/null
. ${shell_initialization_file}
fi
fi
cd "${repo_path}"
echo "Launching docker compose"
echo "Let's wait for that to run. Sleeping 60 seconds."
${possible_sudo} docker compose up -d
sleep 60
echo "Creating superuser"
${possible_sudo} docker compose run --rm web python manage.py makemigrations
echo "running database migrations"
${possible_sudo} docker compose run --rm web python manage.py migrate
echo "Creating superuser"
${possible_sudo} docker compose run --rm web python manage.py createsuperuser
echo "Running yarn"
if [[ "${possible_sudo}" == "sudo" ]]; then
sudo bash -i -c 'yarn; yarn build; cp static/css/styles.css static_deploy/css/styles.css'
else
yarn
yarn build
cp static/css/styles.css static_deploy/css/styles.css
fi
echo "In your browser, visit http://localhost:8000"
echo "Later, to shut down: docker compose down"
fi

View File

@@ -0,0 +1,284 @@
#!/bin/bash
# Copyright 2024 Sam Darwin
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
set -e
# set -x
scriptname="dev-bootstrap-macos.sh"
if [[ "$(uname -p)" =~ "arm" ]]; then
echo "Running on arm processor"
homebrew_base_path="/opt/homebrew"
else
echo "Not running on arm processor"
homebrew_base_path="/usr/local"
fi
# set defaults:
prereqsoption="yes"
# docker_mode either "native" or "desktop" (Docker Desktop). macos only support "desktop" currently.
docker_mode="desktop"
if [[ ${docker_mode} == "native" ]]; then
# Not supported on macos currently, or ever.
repo_path_base="/opt/github"
completion_message_1="When doing development work, switch to the root user 'sudo su -', cd to that directory location, and run 'docker compose up -d'"
possible_sudo="sudo"
shell_initialization_file=/Users/root/.zprofile
fi
if [[ ${docker_mode} == "desktop" ]]; then
repo_path_base="${HOME}/github"
completion_message_1="When doing development work, cd to that directory location, and run 'docker compose up -d'"
possible_sudo=""
shell_initialization_file=~/.zprofile
fi
# git and getopt are required. If they are not installed, moving that part of the installation process
# to an earlier part of the script:
# Install brew
export PATH=/usr/local/bin:/opt/homebrew/bin:$PATH
if ! command -v brew &> /dev/null
then
echo "Installing brew. Check the instructions that are shown."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
# Brew initialization
shell_initialization_file=~/.zprofile
if grep "brew" ${shell_initialization_file}; then
echo "brew already in startup"
else
echo "adding brew to startup"
# shellcheck disable=SC2016
(echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> ${shell_initialization_file}
fi
eval "$(/opt/homebrew/bin/brew shellenv)"
if ! command -v git &> /dev/null
then
echo "Installing git"
brew install git
fi
# check apple silicon.
if ! command -v ${homebrew_base_path}/opt/gnu-getopt/bin/getopt &> /dev/null
then
echo "Installing gnu-getopt"
brew install gnu-getopt
fi
export PATH="${homebrew_base_path}/opt/gnu-getopt/bin:$PATH"
# READ IN COMMAND-LINE OPTIONS
TEMP=$(getopt -o h:: --long repo:,help::,launch::,prereqs::,all:: -- "$@")
eval set -- "$TEMP"
# extract options and their arguments into variables.
while true ; do
case "$1" in
-h|--help)
helpmessage="""
usage: $scriptname [-h] [--repo REPO] [--launch] [--all]
Install all required packages (this is the default action), launch docker-compose, or both.
optional arguments:
-h, --help Show this help message and exit
--repo REPO Name of repository to set up. Example: https://github.com/boostorg/website-v2. You should specify your own fork.
--launch Run docker-compose. No packages.
--all Both packages and launch.
"""
echo ""
echo "$helpmessage" ;
echo ""
exit 0
;;
--repo)
case "$2" in
"") repooption="" ; shift 2 ;;
*) repooption=$2 ; shift 2 ;;
esac ;;
--launch)
launchoption="yes" ; prereqsoption="no" ; shift 2 ;;
--all)
prereqsoption="yes" ; launchoption="yes" ; shift 2 ;;
--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done
echo "Chosen options: pre: $prereqsoption launch: $launchoption repo: $repooption"
# Determine git repo
detected_repo_url=$(git config --get remote.origin.url 2> /dev/null || echo "empty")
detected_repo_name=$(basename -s .git "$(git config --get remote.origin.url)" 2> /dev/null || echo "empty")
# Currently unused. Could be uncommented if needed:
# detected_repo_org=$(basename $(dirname "${detected_repo_url}"))
detected_repo_path=$(git rev-parse --show-toplevel 2> /dev/null || echo "nofolder")
detected_repo_path_base=$(dirname "${detected_repo_path}")
if [[ -n "${detected_repo_url}" && "${detected_repo_url}" != "empty" && -n "${repooption}" ]]; then
echo "You have specified a repo, but you are also running this script from within a repo."
echo "This is indeterminate. Choose one or the other. Exiting."
exit 1
elif [[ -n "${detected_repo_url}" && "${detected_repo_url}" != "empty" ]]; then
echo "You are running the script from an existing repository. That will be used."
repo_url=${detected_repo_url}
repo_name=${detected_repo_name}
repo_path=${detected_repo_path}
repo_path_base=${detected_repo_path_base}
echo "The repo path is ${repo_path}"
cd "${repo_path}"
if [ ! -f .env ]; then
cp env.template .env
fi
else
if [ -n "${repooption}" ]; then
echo "You have specified a repository on the command line. That will be preferred. ${repooption}"
repo_url=${repooption}
else
echo "Please enter a full git repository url with a format such as https:://github.com/_your_name_/website-v2"
read -r repo_url
fi
repo_name=$(basename -s .git "$repo_url" 2> /dev/null || echo "empty")
repo_org_part_1=$(dirname "${repo_url}")
repo_org=$(basename "$repo_org_part_1")
repo_path_base="${repo_path_base}/${repo_org}"
repo_path="${repo_path_base}/${repo_name}"
echo "The path will be ${repo_path}"
${possible_sudo} mkdir -p "${repo_path_base}"
cd "${repo_path_base}"
if [ ! -d "${repo_name}" ]; then
${possible_sudo} git clone "${repo_url}"
fi
cd "${repo_name}"
if [ ! -f .env ]; then
${possible_sudo} cp env.template .env
fi
fi
# Check .env file
if grep STATIC_CONTENT_AWS_ACCESS_KEY_ID .env | grep changeme; then
unsetawskey="yes"
fi
if grep STATIC_CONTENT_AWS_SECRET_ACCESS_KEY .env | grep changeme; then
unsetawskey="yes"
fi
if [[ $unsetawskey == "yes" ]]; then
echo "There appears to be aws keys in your .env file that says 'changeme'. Please set them before proceeding."
echo "Talk to an administrator or other developer to get the keys."
read -r -p "Do you want to continue? y/n" -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo "we are continuing"
else
echo "did not receive a Yy. Exiting."
exit 1
fi
fi
if [[ "$prereqsoption" == "yes" ]]; then
# Install rosetta
if ! pgrep oahd; then
echo "Installing rosetta"
sudo softwareupdate --install-rosetta --agree-to-license
fi
if ! command -v curl &> /dev/null
then
echo "Installing curl"
brew install curl
fi
if ! command -v just &> /dev/null
then
echo "Installing just"
brew install just
fi
if ! command -v python3 &> /dev/null
then
echo "Installing python3"
brew install python3
fi
if ! command -v nvm &> /dev/null
then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
# shellcheck source=/dev/null
. ~/.zprofile
nvm install 20
nvm use 20
echo "Run . ~/.zprofile to enable nvm"
fi
if ! command -v yarn &> /dev/null
then
npm install -g yarn
fi
if ! docker compose &> /dev/null ; then
echo "Installing Docker Desktop"
curl -o /tmp/Docker.dmg https://desktop.docker.com/mac/main/arm64/160616/Docker.dmg
sudo hdiutil attach /tmp/Docker.dmg
sudo /Volumes/Docker/Docker.app/Contents/MacOS/install
sudo hdiutil detach /Volumes/Docker
echo "The Docker Desktop dmg package has been installed."
echo "The next step is to go to a desktop GUI window on the Mac, run Docker Desktop, and complete the installation."
echo "Then return here."
read -r -p "Do you want to continue? y/n" -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo "we are continuing"
else
echo "did not receive a Yy. Exiting. You may re-run the script."
exit 1
fi
fi
echo "The installation section of this script is complete."
echo "The location of your docker compose installation is ${repo_path}."
echo ""
if [[ "$launchoption" != "yes" ]]; then
echo "You may run this script again with the --launch option, to launch docker compose and run db migrations".
echo ""
fi
echo "${completion_message_1}"
fi
if [[ "$launchoption" == "yes" ]]; then
if ! command -v nvm &> /dev/null
then
# shellcheck source=/dev/null
. ~/.zprofile
fi
cd "${repo_path}"
echo "Launching docker compose"
echo "Let's wait for that to run. Sleeping 60 seconds."
docker compose up -d
sleep 60
echo "Creating database migrations"
docker compose run --rm web python manage.py makemigrations
echo "running database migrations"
docker compose run --rm web python manage.py migrate
echo "Creating superuser"
docker compose run --rm web python manage.py createsuperuser
echo "Running yarn"
yarn
yarn build
cp static/css/styles.css static_deploy/css/styles.css
echo "In your browser, visit http://localhost:8000"
echo "Later, to shut down: docker compose down"
fi

View File

@@ -0,0 +1,408 @@
# TODO: remember repo in a file, in case you restart the script
# Copyright 2024 Sam Darwin
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '')]
#Requires -RunAsAdministrator
param (
[Parameter(Mandatory=$false)][alias("repo")][string]$repooption = "",
[switch]$help = $false,
[switch]${launch} = $false,
[switch]${all} = $false
)
# set defaults:
${prereqsoption}="yes"
$scriptname="dev-bootstrap-win.ps1"
# Skip 1.1.12, has a bug. Go to 1.1.13 or later.
$nvm_install_version="1.1.11"
$node_version="20.17.0"
# docker_mode either "native" or "desktop" (Docker Desktop). win only support "desktop" currently.
$docker_mode="desktop"
${sleep_longer}=60
${sleep_shorter}=30
${cached_url_file}="tmp-dev-bootstrap-url.cfg"
${git_branch}="develop"
if (${docker_mode} -eq "native")
{
# Not supported on win currently, or ever.
${repo_path_base}="\opt\github"
${completion_message_1}="When doing development work, switch to the root user 'sudo su -', Set-Location to that directory location, and run 'docker compose up -d'"
}
if (${docker_mode} -eq "desktop")
{
${repo_path_base}="${HOME}\github"
${completion_message_1}="When doing development work, Set-Location to that directory location, and run 'docker compose up -d'"
}
# Set-PSDebug -Trace 1
if ($help)
{
$helpmessage="
usage: $scriptname [-help] [-repo REPO] [-launch] [-all]
Builds library documentation.
optional arguments:
-help Show this help message and exit
-repo REPO Name of repository to set up. Example: https://github.com/boostorg/website-v2. You should specify your own fork.
-launch Run docker-compose. No packages.
-all Both packages and launch.
"
Write-Output $helpmessage
exit 0
}
if ($launch)
{
${launchoption} = "yes"
${prereqsoption}="no"
}
if ($all)
{
${launchoption} = "yes"
${prereqsoption}="yes"
}
function refenv
{
# Make `refreshenv` available right away, by defining the $env:ChocolateyInstall
# variable and importing the Chocolatey profile module.
# Note: Using `. $PROFILE` instead *may* work, but isn't guaranteed to.
$env:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.."
Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
# refreshenv (Update-SessionEnvironment) might delete path entries. Return those to the path.
$originalpath=$env:PATH
Update-SessionEnvironment
$joinedpath="${originalpath};$env:PATH"
$joinedpath=$joinedpath.replace(';;',';')
$env:PATH = ($joinedpath -split ';' | Select-Object -Unique) -join ';'
}
# git is required. In the unlikely case it's not yet installed, moving that part of the package install process
# here to an earlier part of the script:
if ( -Not (Get-Command choco -errorAction SilentlyContinue) )
{
Write-Output "Install chocolatey"
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
refenv
}
if ( -Not (Get-Command git -errorAction SilentlyContinue) )
{
Write-Output "Install git"
choco install -y --no-progress git
refenv
}
Write-Output "Chosen options: pre: ${prereqsoption} launch: ${launchoption} repo: ${repooption}"
# Determine git repo
$originurl=git config --get remote.origin.url 2>$null
if ($LASTEXITCODE -eq 0)
{
${detected_repo_url}=[io.path]::ChangeExtension($originurl, [NullString]::Value)
}
else
{
${detected_repo_url}="empty"
}
## detected_repo_org=$(basename $(dirname "${detected_repo_url}"))
$repopath=git rev-parse --show-toplevel 2>$null
if ($LASTEXITCODE -eq 0)
{
${detected_repo_path}=$repopath | ForEach-Object {$_ -replace '/','\'}
}
else
{
${detected_repo_path}="nofolder"
}
${detected_repo_path_base}=[io.path]::GetDirectoryName($detected_repo_path)
if (Test-Path ${cached_url_file})
{
$detected_cached_url = Get-Content ${cached_url_file} -Raw
$detected_cached_url = $detected_cached_url.Trim()
}
if ( ${detected_repo_url} -and -not (${detected_repo_url} -eq "empty") -and ${repooption} )
{
Write-Output "You have specified a repo, but you are also running this script from within a repo."
Write-Output "This is indeterminate. Choose one or the other. Exiting."
exit 1
}
elseif ( ${detected_repo_url} -and -not (${detected_repo_url} -eq "empty") )
{
Write-Output "You are running the script from an existing repository. That will be used."
${repo_url}=${detected_repo_url}
${repo_name}=${detected_repo_name}
${repo_path}=${detected_repo_path}
${repo_path_base}=${detected_repo_path_base}
Write-Output "The repo path is ${repo_path}"
Set-Location "${repo_path}"
if ( !(Test-Path .env ) )
{
Copy-Item env.template .env
}
}
else
{
if (${repooption})
{
Write-Output "You have specified a repository on the command line. That will be preferred. ${repooption}"
${repo_url}=${repooption}
Write-Output "${repo_url}" | Out-File ${cached_url_file}
}
else
{
if (${detected_cached_url})
{
$extra_text="[Hit enter to accept default value ${detected_cached_url}]"
$default_value=${detected_cached_url}
}
else
{
$extra_text=""
$default_value=""
}
$repo_url = Read-Host "Please enter a full git repository url with a format such as https:://github.com/_your_name_/website-v2 ${extra_text}"
if (!$repo_url)
{
$repo_url=$default_value
}
if (!$repo_url)
{
Write-Output "You did not provide a git url. Exiting"
exit 1
}
else
{
Write-Output "repo url is now $repo_url"
Write-Output "${repo_url}" | Out-File ${cached_url_file}
}
}
if ($repo_url)
{
${repo_name}=[io.path]::GetFileNameWithoutExtension($repo_url)
}
else
{
${repo_name}="empty"
}
${repo_org_part_1}=[io.path]::GetDirectoryName($repo_url)
${repo_org}=[io.path]::GetFileNameWithoutExtension($repo_org_part_1)
${repo_path_base}="${repo_path_base}\${repo_org}"
${repo_path}="${repo_path_base}\${repo_name}"
Write-Output "The path will be ${repo_path}"
mkdir -Force "${repo_path_base}"
Set-Location "${repo_path_base}"
if ( !(Test-Path -Path ${repo_path}))
{
git clone -b ${git_branch} "${repo_url}"
}
Set-Location "${repo_name}"
if ( !(Test-Path .env))
{
Copy-Item env.template .env
}
}
# On windows, the docker/ folder needs to have EOL=lf.
$a_docker_filename=".\docker\compose-start.sh"
if ((Get-Content $a_docker_filename -Raw) -match "\r\n$")
{
Write-Output "${a_docker_filename} has windows line endings. The docker/ folder needs to have unix line endings."
Write-Output "The .gitattributes file should already fix this. Check out a new copy of the repository "
Write-Output "and then re-run this script."
exit 1
}
# Check .env file
$searchresults = Select-String -pattern "STATIC_CONTENT_AWS_ACCESS_KEY_ID" .env | Select-String -pattern "changeme"
if ($null -eq $searchresults)
{
# "No matches found"
ForEach-Object 'foo'
}
else
{
$unsetawskey="yes"
}
$searchresults = Select-String -pattern "STATIC_CONTENT_AWS_SECRET_ACCESS_KEY" .env | Select-String -pattern "changeme"
if ($null -eq $searchresults)
{
# "No matches found"
ForEach-Object 'foo'
}
else
{
$unsetawskey="yes"
}
if ($unsetawskey)
{
Write-Output "There appears to be aws keys in your .env file that says 'changeme'. Please set them before proceeding."
Write-Output "Talk to an administrator or other developer to get the keys."
$REPLY = Read-Host "Do you want to continue? y/n"
if (($REPLY -eq "y") -or ($REPLY -eq "Y"))
{
Write-Output "Continuing"
}
else
{
Write-Output "did not receive a Yy. Exiting."
exit 1
}
}
if ($prereqsoption -eq "yes")
{
if ( -Not (Get-Command just -errorAction SilentlyContinue) )
{
choco install -y --no-progress just
}
if ( -Not (Get-Command python -errorAction SilentlyContinue) )
{
choco install -y --no-progress python
}
if ( -Not (Get-Command nvm -errorAction SilentlyContinue) )
{
# 1.1.12 doesn't allow reading stdout. Will be fixed in 1.1.13 supposedly.
choco install -y --no-progress nvm.install --version ${nvm_install_version}
Write-Output "NVM was just installed. Close this terminal window, and then restart the script."
Write-Output "The process has not finished. Please open a new terminal window. And restart the script."
exit 0
}
if (nvm list | Select-String "${node_version}")
{
# Node already installed
ForEach-Object 'foo'
}
else
{
nvm install 20
nvm use 20
}
if ( -Not (Get-Command yarn -errorAction SilentlyContinue) )
{
npm install -g yarn
}
refenv
# Check if wsl is installed
$console = ([console]::OutputEncoding)
[console]::OutputEncoding = New-Object System.Text.UnicodeEncoding
if (wsl --status | oss | select-string -pattern "Ubuntu")
{
$wslinstalled="yes"
}
else
{
$wslinstalled="no"
}
[console]::OutputEncoding = $console
if ($wslinstalled -eq "no")
{
wsl --install
Write-Output "WSL was just installed. Rebooting in ${sleep_shorter} seconds. Then complete the WSL steps if they appear, and re-run this script."
Start-Sleep ${sleep_shorter}
Restart-Computer
}
else
{
wsl --update
}
if ( -Not (Get-Command docker -errorAction SilentlyContinue) )
{
Write-Output "Installing Docker Desktop"
choco install -y --no-progress docker-desktop -ia --quiet --accept-license
refenv
Write-Output "Docker-Desktop was just installed. Rebooting in ${sleep_shorter} seconds. Then launch Docker Desktop to complete the installation."
Write-Output "After that, you may choose to either re-run this script with -launch,"
Write-Output "or run the necessary 'docker compose' steps directly to launch a local environment."
Write-Output ""
Write-Output "When the system comes back up, click the Docker Desktop icon to accept the license and complete the installation."
Start-Sleep ${sleep_shorter}
Restart-Computer
}
Write-Output "The 'installation' section of this script is complete."
Write-Output "The location of your docker compose installation is ${repo_path}."
Write-Output ""
if ( ! ( "launchption" -eq "yes"))
{
Write-Output "You may run this script again with the -launch option, to launch docker compose and run db migrations".
Write-Output ""
}
Write-Output ${completion_message_1}
}
if ("$launchoption" -eq "yes")
{
# is something like this needed on windows? how does it work?
# if ! command -v nvm &> /dev/null
# then
# . ~/.zprofile
# fi
Set-Location "${repo_path}"
Write-Output "Starting the docker compose steps"
Write-Output "running docker compose pull"
docker compose pull
Write-Output "docker compose up -d"
Write-Output "Let's wait for that to run. Sleeping ${sleep_longer} seconds."
docker compose up -d
Start-Sleep ${sleep_longer}
Write-Output "running makemigrations"
docker compose run --rm web python manage.py makemigrations
Write-Output "running database migrations"
docker compose run --rm web python manage.py migrate
Write-Output "Creating superuser"
docker compose run --rm web python manage.py createsuperuser
# collectstatic already done, by celery
# Write-Output "running collectstatic"
# docker compose run --rm web python manage.py collectstatic
Write-Output "Running yarn"
yarn
yarn dev-windows
Copy-Item static/css/styles.css static_deploy/css/styles.css
Write-Output "In your browser, visit http://localhost:8000"
Write-Output "Later, to shut down: docker compose down"
}

View File

@@ -7,6 +7,7 @@
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"dev": "tailwindcss -i frontend/styles.css -o static/css/styles.css --watch", "dev": "tailwindcss -i frontend/styles.css -o static/css/styles.css --watch",
"dev-windows": "tailwindcss -i frontend/styles.css -o static/css/styles.css",
"build": "NODE_ENV=production tailwindcss -i frontend/styles.css -o static/css/styles.css --minify", "build": "NODE_ENV=production tailwindcss -i frontend/styles.css -o static/css/styles.css --minify",
"builddocs": "NODE_ENV=production tailwindcss -c ./docstailwind.config.js -i frontend/docsstyles.css -o static/css/docsstyles.css --minify", "builddocs": "NODE_ENV=production tailwindcss -c ./docstailwind.config.js -i frontend/docsstyles.css -o static/css/docsstyles.css --minify",
"builduserguide": "NODE_ENV=production tailwindcss -c ./userguidetailwind.config.js -i frontend/userguidestyles.css -o static/css/userguidestyles.css --minify" "builduserguide": "NODE_ENV=production tailwindcss -c ./userguidetailwind.config.js -i frontend/userguidestyles.css -o static/css/userguidestyles.css --minify"