· ▒██▀ ▀ ▒██▀ ▀ ▀ ▀▒██ ▀ ▀███ ·
: ▒██▀ ▓██ ▒██▀▀██▓ ▓██▀▀▒██▀▀███ ▒██▀▀██▓ ▓██▀ ▒██▀▀███ ▒██▀▀▀▀▀ :
· ··─┼─▓██──███─▓██─▄███─███──▓██──███─▓██──────███──▓██──███─▓██──███─┼─·· ·
│ ███▄▄██▓ ███▄▄▄▄▄▄██▓ ███▄ ███▄███▄▄███ ███▄▄███▄ ███▄███▄▄███ │
· ··──┼─────────·· defacto2.net ··─────────┼──·· ·
│ :
The Defacto2 application is a self-contained web server first devised in 2023. It is built with the Go language and can be easily compiled for significant server operating systems. The application relies on a PostgreSQL database setup for data queries using a PostgreSQL database connection.
All configurations and modifications to this web application's default settings are through system environment variables.
Currently the application is available as a standalone binary for Linux.
Installation instructions are provided for Ubuntu Server.
# download the latest release
wget https://github.com/Defacto2/server/releases/latest/download/defacto2-server_linux.deb
# install (or update) the package
sudo dpkg -i defacto2-server_linux.deb
# confirm the binary is executable
defacto2-server --versionFor other Linux distributions, the binary can be installed manually to a directory in the system's PATH.
# download the latest release
wget https://github.com/Defacto2/server/releases/latest/download/defacto2-server_linux.zip
# unzip the archive
unzip defacto2-server_linux.zip
# make the binary executable
sudo chmod +x defacto2-server
# move the binary to a system path
sudo mv defacto2-server /usr/local/bin
# confirm the binary is executable
defacto2-server --versionThe web server will run with out any arguments and will be available on the localhost with port 1323.
defacto2-serverTo stop the server, press CTRL+C.
The application uses environment variables to configure the database connection and other settings. These are documented in the software package documentation.
There are examples of the environment variables in the example .env and the example .service files found in the init/ directory.
The source code requires a local installation of Go version 1.22 or newer.
$ go version
> go version go1.22.6 linux/amd64Important
While you can compile the application to target Windows environments, it will not function correctly with NTFS file paths. Instead, it is advisable to use Windows Subsystem for Linux.
Clone the source code repository and download the dependencies.
# clone the repository
git clone https://github.com/Defacto2/server.git
# change to the server repository directory
cd server
# optional, download the dependencies
go mod downloadTest the application.
$ go run . --version
> Defacto2 web application version n/a (not a build) for Linux on Intel/AMD 64The repository is configured to use the Task application which needs local installation. The following of tools are expected to be installed on the local machine.
- Task is a task runner / build tool.
- golangci-lint is a Go linters aggregator.
- GoReleaser is a release automation tool for Go projects.
A new cloned repository needs to download a number of developer specific dependencies.
# change to the server repository directory
cd server
# run the initialization task
task _init
# confirm the tools are installed
task verThe list of available tasks can be shown.
$ task # --list-all
task: Available tasks for this project:
* _init: Initialize this project for the first time after a git clone.
* assets: Build, compile and compress the web serve CSS and JS assets.
* build: Build the binary of the web server.
* build-race: Build the binary of the web server with race detection.
* default: Task runner for the Defacto2 web server source code.
* doc: Generate and browse the application module documentation.
* lint: Runs the go formatter and lints the source code.
* lint+: Runs the deadcode and betteralign linters on the source code.
* nil: Run the static analysis techniques to catch Nil dereferences.
* pkg-patch: Update and apply patches to the web server dependencies.
* pkg-release: Build the release binary of the web server embeded with the git version tag.
* pkg-snapshot: Build the release binary of the web server without a git version tag.
* pkg-update: Update the web server dependencies.
* serve-dev: Run the internal web server in development mode with live reload.
* serve-prod: Run the internal web server with live reload.
* test: Run the test suite.
* testr: Run the test suite with the slower race detection.
* ver: Print the versions of the build and compiler tools.As the application relies on environmental variables for configuration, the Taskfile can use a dot-env file to read in variables for use on tasks.
For example, you can configure various variables while running the task serve-dev or task serve-prod tasks to point to the downloads, image screenshots, image thumbnails, and a customized database connection URL.
# change to the server repository directory init directory
cd server/init
# copy the example .env file to the local .env file
cp example.env.local .env.local
# edit the .env file to set the environment variables
nano .env.localAn example, the .env.local file can be configured as follows.
# ==============================================================================
# These are the directory paths serving static files for the artifacts.
# All directories must be absolute paths and any empty values will disable the
# relevent feature. For example, an invalid D2_DIR_DOWNLOAD will disable the
# artifact downloads.
# The directories must be readable and writable by the web server.
# ==============================================================================
# List the directory path that holds the named UUID files for the artifact downloads.
D2_DIR_DOWNLOAD=/home/defacto2/downloads
# List the directory path that holds the named UUID files for the artifact images.
D2_DIR_PREVIEW=/home/defacto2/previews
# List the directory path that holds the named UUID files for the artifact thumbnails.
D2_DIR_THUMBNAIL=/home/defacto2/thumbnails
# List the directory path that holds the generated extra files for the artifacts.
D2_DIR_EXTRA=/home/defacto2/extras
# List the directory path that holds the named UUID files that are not linked to
# any database records.
D2_DIR_ORPHANED=/home/defacto2/orphaned
# ==============================================================================
# These are the PostgreSQL database connection settings.
# The database is required for accessing and displaying the artifact data.
# ==============================================================================
# The connection string to the PostgreSQL database.
D2_DATABASE_URL=postgres://root:example@localhost:5432/defacto2_psRun the internal web server in fast-start, development mode with live reloading of any changes to the Go source code.
task serve-devRun the internal web server in production mode with live reloading of any changes to the Go source code.
task serve-prodJavaScript and CSS assets are found in assets/ and are compiled and compressed into the public/ directory.
ESBuild is used to compile the JavaScript and it needs to be installed on the local machine. But, ESBuild can be installed without the need for npm or node.js.
curl -fsSL https://esbuild.github.io/dl/latest | shChanges to the assets will require the assets task to be run.
task assetsThe source code is linted using the golangci-lint aggregator that runs a number of linters locally.
If you want to optionally lint the CSS and JS assets, you will need to install Stylelint and ESLint which will require node.js and a package manager.
task lintThe source code has a test suite that can be run.
task testOr check for race conditions in the test suite.
task testrThe application can be profiled to check for performance bottlenecks or resource usage.
The configuration D2_LOG_ALL environment variable must be set to true to enable the profiling.
Use the go tool pprof to profile the application.
go tool pprof -http=:8000 -lines -unit=mb https://defacto2.net/debug/pprof/heaphttp=:8000is the port to view the profile in a local web browser.-lineswill show the source code line numbers in the profile.-unit=mbwill show the memory usage in megabytes.https://defacto2.net/debug/pprof/heapis the URL to the profile.
Other profiles can be viewed by changing the URL.
The allocs profile, reports statistics as of the total amount of allocated space.
https://defacto2.net/debug/pprof/allocs
Block profile tracks time spent blocked on synchronization primitives, such as sync.Mutex, sync.RWMutex, sync.WaitGroup, sync.Cond, and channel send/receive/select.
https://defacto2.net/debug/pprof/blockfor the block profile.
The heap profile, it reports statistics as of the most recently completed garbage collection.
https://defacto2.net/debug/pprof/heap
The mutex profile tracks contention on mutexes, such as sync.Mutex, sync.RWMutex, and runtime-internal locks.
-
https://defacto2.net/debug/pprof/mutex -
https://defacto2.net/debug/pprof/cmdlinefor the command line arguments. -
https://defacto2.net/debug/pprof/goroutinefor the goroutine profile. -
https://defacto2.net/debug/pprof/profilefor the CPU profile. -
https://defacto2.net/debug/pprof/symbolfor the symbol profile. -
https://defacto2.net/debug/pprof/threadcreatefor the threadcreate profile. -
https://defacto2.net/debug/pprof/tracefor the trace profile.
The application can be stress tested using the crawley tool.
task build-race
task build-run
crawley -all -brute -depth -1 -headless http://localhost:1323In another terminal, you can view the server's performance using the top command, htop or view the logs.
tail -f ~/defacto2_server_info.logThe application configuration documentation can be modified in doc.go and the changes regenerated and previewed in a web browser.
task doc// Copyright © 2023-2024 Ben Garrett. All rights reserved.
/*
The [Defacto2] application is a self-contained web server first devised in 2023.
It is built with the Go language and can be easily compiled for significant server The source code can be built into a binary for the local machine.
task build
# or to build with race detection
task buildxThe resulting defacto2-server binary is built in the repository root directory.
Or if you want to build the binary for a different operating system and architecture.
# build for macOS on Apple Silicon
GOOS=darwin GOARCH=arm64 go build -o "defacto2-server" server.go
# build for FreeBSD on AMD64
GOOS=freebsd GOARCH=amd64 go build -o "defacto2-server" server.goBuilding the distribution package for the server application is done using a local installation of GoReleaser.
To package a snapshot binary for the local machine without a version tag.
task pkg-snapshotThe resulting binary is in the dist/ directory in the repository root.
# check the configuration file
goreleaser check --config init/.goreleaser.yaml
# create a new, original tag
git tag -a v1.0.1 -m "First update to the release version."
git push origin v1.0.1
# build the release binary
task pkg-releaseThe resulting built package is found in the dist/ directory in the repository root.
The web application relies on an Object-relational mapping (ORM) implementation provided by SQLBoiler to simplify development. If the database schema ever changes with a new table column, a modification of an existing column type, or a name change, the ORM code generation requires a rerun.
After modifying the database schema, confirm the local development database connection settings are correct in the SQLBoiler settings file init/.sqlboiler.toml.
[psql]
schema = "public"
dbname = "defacto2_ps"
host = "localhost"
port = 5432
user = "root"
pass = "example"
sslmode = "disable"
[auto-columns]
created = "createdat"
updated = "updatedat"
deleted = "deletedat"Then in the root of the repository, run go generate.
go generateThe generated code is found in the internal/postgres/model/ directory and is ready for use.