A service for reviewing design decisions made in code.
The inspiration for this service is: I've found it useful over the years to redo simple applications I've written in the past. Relooking over past code and what I just wrote gave me an idea of my progress through evaluating what I now consider important compared to what I used to consider important. I wished there was a better way to remember why I wrote what I did instead of relying on a README.md.
Target Group | Primary Use Case |
---|---|
New developers | Practice creating real-world applications over solving algorithms |
Growing developers | Review your progress through the years by practicing re-writing basic applications |
Technical interviewers | Review design decisions made in code written by candidates |
The backend variables should be present on the service's host system at runtime. If running in a Docker container, remember to add these as environment variables.
Key | Default | Description |
---|---|---|
GITHUB_CLIENT_ID |
"" |
Github application Client ID |
GITHUB_CLIENT_SECRET |
"" |
Github application Client Secret |
GITHUB_REDIRECT_URI |
"" |
Github application Redirect URI that you specified when creating the Github application |
LOGIN_URL |
"" |
Frontend URL |
SERVER_ADDR |
"0.0.0.0" |
Interface address which the server should bind to |
SERVER_PORT |
30000 |
Port which the server should listen on |
The frontend variables are injected at build-time and should be defined in the delivery pipeline.
Key | Default | Description |
---|---|---|
REACT_APP_API_URL_BASE |
"http://localhost:30000" |
Base URL to the API server |
Accounts
Software
Navigate to the Terraform module for this project at ./deploy/do
. All commands assume running make
in that directory and not the project root.
- Setup an SSH key-pair using
make .keys
- Setup the backend configuration using
make .backend-config
- Setup your Digital Ocean token using
make .envrc
and filling up your Digital Ocean API token in the generated.envrc
before runningdirenv allow .
to enable usage of the.envrc
. You can find your API token from https://cloud.digitalocean.com/account/api/tokens. - Run
make init
to initialise the Terraform backend - Run
make plan
to show changes to the infrastructure - Run
make apply
to apply the changes for the first time - Run
make down
for subsequent runs to bring down the API server only - Run
make up
for subsequent runs to bring up the API server only - Run
make destroy
to destroy all infrastructure
Notes
- To debug the userdata setting up, run
make ssh_api
and once inside the server, runsudo tail -f /var/log/cloud-init-output.log
- If renewing droplet, remember to mount the volume using:
mkdir -p /mnt/codeprac_mysql
mount -o discard,defaults,noatime /dev/disk/by-id/scsi-0DO_Volume_codeprac-mysql /mnt/codeprac_mysql
echo '/dev/disk/by-id/scsi-0DO_Volume_codeprac-mysql /mnt/codeprac_mysql ext4 defaults,nofail,discard 0 0' | sudo tee -a /etc/fstab
- If we hit the rate-limit for
certbot
, we might get an error, to fix this:- SSH into the server and scp the certificates over
- Add
ssl_certificate /etc/letsencrypt/live/apiv1.codepr.ac/fullchain.pem; # managed by Certbot
to theapiv1.codepr.ac
server block - Add
ssl_certificate_key /etc/letsencrypt/live/apiv1.codepr.ac/privkey.pem; # managed by Certbot
to theapiv1.codepr.ac
server block - Add
ssl_certificate_key /etc/letsencrypt/live/www.codepr.ac/fullchain.pem; # managed by Certbot
to thewww.codepr.ac
server block - Add
ssl_certificate_key /etc/letsencrypt/live/www.codepr.ac/privkey.pem; # managed by Certbot
to thewww.codepr.ac
server block - Run
nginx -t
to check the configuration - Run
nginx -s reload
to reload the configuration
The supplied user data sets up the server but does not deploy anything. After deployment of the infrastructure, do the following from the ./deploy/do
directory:
- Run
make ssh_api
to gain a shell into the API server - Navigate to
~/src
, run./scripts/init-production.sh
, and fill up the variables - From
~/src
, rundocker-compose up -d
to start the application - Copy the script at
./scripts/update-service.sh
to/opt/scripts/update-service.sh
and set the executable flag on it - Run
sudo crontab -e
(note: usesudo
) and add a new line*/5 * * * * /opt/scripts/update-service.sh
, this enables auto-updating of the production services - Copy the script at
./scripts/update-repo.sh
to~/update-repo.sh
and set the executable flag on it - Run
crontab -e
(note: nosudo
) and add a new line*/5 * * * * cd /home/codeprac/src && /home/codeprac/update-repo.sh
, this enables auto-updating of the production repository
Notes
- To update production instructions, run
make update_repo
- To update production, run
sudo make update_production
- To deploy production, run
sudo make deploy_production
Accounts
Software
The following section assumes commands being run from the project root.
- Clone this repository locally
- Install Node.js dependencies using
npm ci
(ormake ui_deps
) - Install Golang dependencies using
go mod vendor
(ormake api_deps
) - Start the MySQL database by running
docker-compose -f ./deploy/db/docker-compose.yml up -d
(ormake start_db
). You should be able to access it usingmysql -uuser -ppassword -h127.0.0.1 -P33060 database
. - Start the API server by running
go run ./cmd/codeprac start
(ormake start_api
). You should be able to access it at http://localhost:30000.- To test the behaviour with a production build, use
make start_api_production
- To test the behaviour with a production build, use
- Start the web application by running
npm start
(ormake start_ui
). You should be able to access it at http://localhost:3000.- To test the behaviour with a production build, use
make start_ui_production
(this uses thenpm
packageserve
, final production uses a Nginx server)
- To test the behaviour with a production build, use
- Run
make .envrc
and fill up the variables as required in the generated.envrc
file at the project root and rundirenv allow .
. These variables will be consumed by the API server when running locally
- Run
make api_production
ormake api_static_production
to build the application into a binary at./bin/codeprac_${GOOS}_${GOARCH}
. Requiresgo
to be available in your$PATH
. - Run
make ui
to build the web service into a built copy at./build
/ Requiresnode
to be available in your$PATH
.
Notes
- For
make ui
to work properly, ensure that the requiredREACT_APP_*
variables are defined atnpm run build
-time
Docker is used to package the production bundle.
- Run
make api_image
to create the Docker image for the API server - Run
make ui_image
to create the Docker image for the web application
Notes
- Multistage builds are opted for to avoid including files not intended for production, resulting builds from multistage builds also tend to be leaner
The code in this repository is configured to be deployed using Gitlab Pages via Gitlab CI/CD. Sign up for an account at https://gitlab.com.
Infrastructure provisioning scripts use Digital Ocean as a provider. To get started, sign up for an account at https://m.do.co/c/c3b62cf39c7c (that's my referral code so that this project may be slightly easier on my pockets, if you would rather not (cues sad face), you can also sign up from https://digitalocean.com).
The direnv
tool is used in conjunction with Terraform so that API tokens can avoid being checked-in to the repository. To install direnv
, run:
# on ubuntu
apt install direnv;
# on macos
brew install direnv;
# on windows
echo "it's complicated";
See direnv/direnv#343 (comment) for Windows installation instructions
Add the hook script as described at https://github.com/direnv/direnv/blob/master/docs/hook.md.
Verify that direnv
is available in your $PATH
by running which direnv
and direnv version
.
Docker is used to containerise and package the application. To install it, follow the instructions on the following pages:
- Ubuntu: https://docs.docker.com/engine/install/ubuntu/
- MacOS: https://docs.docker.com/docker-for-mac/install/
- Windows: https://docs.docker.com/docker-for-windows/install/
Verify that docker
and docker-compose
are available in your $PATH
by running which docker
, which docker-compose
, docker version
, and docker-compose version
.
Go is used for the backend server. To install it, run:
# on ubuntu (ref: https://github.com/golang/go/wiki/Ubuntu)
sudo add-apt-repository ppa:longsleep/golang-backports;
sudo apt-get install golang-go;
# on macos (ref: https://formulae.brew.sh/formula/go)
brew install go;
# on windows (ref: https://chocolatey.org/packages/golang)
choco install golang;
Verify the go
command is available in your $PATH
by running which go
and go version
.
Node.js is used for frontend work. The official way to install it can be found at https://nodejs.org/en/download/.
The recommended way however is to install NVM which allows you to switch Node versions easily. See the instructions at https://github.com/nvm-sh/nvm/blob/master/README.md#installing-and-updating.
Verify both node
and npm
commands are available in your $PATH
by running which node
, which npm
, node -v
, and npm -v
.
Terraform is used to bring up required infrastructure. To install Terraform,
# on ubuntu
xdg-open 'https://www.terraform.io/downloads.html';
# on macos
brew install terraform;
# on windows
choco install terraform;
Or download it from https://www.terraform.io/downloads.html.
Full instructions can be found at https://learn.hashicorp.com/terraform/getting-started/install.html.
Verify the terraform
command is available in your $PATH
by running which terraform
and terraform version
.
To-be-decided.