Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
334e4898
Unverified
Commit
334e4898
authored
Feb 08, 2024
by
Lincoln Nogueira
Committed by
GitHub
Feb 08, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: improve docker-compose.dev (#2938)
parent
c7822515
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
320 additions
and
55 deletions
+320
-55
docker-compose.dev.yaml
scripts/docker-compose.dev.yaml
+320
-55
No files found.
scripts/docker-compose.dev.yaml
View file @
334e4898
# > Memos development environment <
#
# Available profiles: sqlite, mysql, postgres.
# Use `docker compose --profile PROFILE_NAME up` to launch only services within the profile.
#
# Services in the `tools` profile are used for running one-off tasks like linting, generating code, etc.
#
# Services started in all database profiles:
# Front-end: http://localhost:3001
# API: http://localhost:8081
# Adminer: http://localhost:8091
#
# On Windows, run this before using docker-compose on a new terminal:
# $Env:HOME=$Env:USERPROFILE
#
# > Start Memos in development mode:
# docker compose -f ./scripts/docker-compose.dev.yaml --profile [sqlite|mysql|postgres] up --detach
#
# > Stop all services:
# docker compose -f ./scripts/docker-compose.dev.yaml --profile sqlite --profile postgres --profile mysql down
#
# > Remove related volumes: (all other files are mapped to ./air/docker/ directory)
# docker volume rm memos-dev_pnpm-store memos-dev_node-modules
#
# One-off tasks:
# > pnpm:
# docker compose -f ./scripts/docker-compose.dev.yaml run --rm pnpm [add|remove|update] [PACKAGE_NAME] [--save-dev]
#
# > buf: (run this after modifying .proto files)
# docker compose -f ./scripts/docker-compose.dev.yaml run --rm buf generate
#
# > go:
# docker compose -f ./scripts/docker-compose.dev.yaml run --rm go mod tidy -go=1.22
#
# > golangci-lint: (run this before submitting Pull Requests affecting Go code)
# docker compose -f ./scripts/docker-compose.dev.yaml run --rm golangci-lint run
#
# > goimports: (run this if golangci-lint shows "File is not `goimports`-ed"
# docker compose -f ./scripts/docker-compose.dev.yaml run --rm goimports -local https://github.com/usememos/memos -w [FILE|.]
#
version
:
"
3.0"
name
:
memos-dev
volumes
:
# pnpm uses hard links and node_modules uses symlinks.
# Using volumes make things work properly on any host OS.
node-modules
:
pnpm-store
:
services
:
db
:
image
:
mysql
volumes
:
-
./../.air/mysql:/var/lib/mysql
environment
:
MYSQL_ALLOW_EMPTY_PASSWORD
:
yes
MYSQL_DATABASE
:
memos
api
:
image
:
cosmtrek/air
working_dir
:
/work
command
:
[
"
-c"
,
"
./scripts/.air.toml"
]
environment
:
-
"
MEMOS_DSN=root@tcp(db)/memos"
-
"
MEMOS_DRIVER=mysql"
volumes
:
-
./..:/work/
-
./../.air/go-build:/root/.cache/go-build
-
$HOME/go/pkg/:/go/pkg/
# Cache for go mod shared with the host
web
:
profiles
:
[
"
sqlite"
,
"
mysql"
,
"
postgres"
]
image
:
node:20-alpine
working_dir
:
/work
depends_on
:
[
"
api"
]
ports
:
[
"
3001:3001"
]
environment
:
[
"
DEV_PROXY_SERVER=http://api:8081/"
]
ports
:
[
3001
:
3001
]
environment
:
DEV_PROXY_SERVER
:
http://api:8081/
NPM_CONFIG_UPDATE_NOTIFIER
:
false
working_dir
:
&web-working-dir
/work/web
entrypoint
:
[
"
/bin/sh"
,
"
-c"
]
command
:
[
"
corepack
enable
&&
pnpm
i
--frozen-lockfile
&&
pnpm
dev"
]
tmpfs
:
/work/node_modules/:exec
# To avoid pnpm ERR_PNPM_LINKING_FAILED error
volumes
:
-
./../web:/work
tmpfs
:
&web-tmpfs
/work/node_modules/:exec
# avoid ERR_PNPM_LINKING_FAILED
volumes
:
&web-volumes
-
node-modules:/work/web/node_modules
-
pnpm-store:/work/web/.pnpm-store
-
../proto:/work/proto
-
../web:/work/web
healthcheck
:
test
:
[
"
CMD"
,
"
wget"
,
"
-qO"
,
"
-"
,
"
http://localhost:3001"
]
interval
:
10s
timeout
:
5s
api
:
profiles
:
[
"
sqlite"
]
image
:
&api-image
golang:1.22-alpine
ports
:
&api-ports
[
8081
:
8081
]
environment
:
MEMOS_DRIVER
:
sqlite
MEMOS_DATA
:
/var/opt/memos
working_dir
:
&api-working-dir
/work
volumes
:
&api-volumes
-
$HOME/go/pkg/:/go/pkg/
# Share go mod cache with host
-
../.air/docker/go-build:/root/.cache/go-build
-
../.air/docker/go/bin:/go/bin
-
../.air/docker/memosdata:/var/opt/memos
-
..:/work/
configs
:
&api-configs
-
source
:
air-entrypoint.sh
target
:
/usr/local/bin/entrypoint.sh
entrypoint
:
&api-entrypoint
[
"
/bin/sh"
,
"
/usr/local/bin/entrypoint.sh"
]
command
:
&api-command
[
"
-c"
,
"
./scripts/.air.toml"
]
healthcheck
:
&api-healthcheck
test
:
[
"
CMD"
,
"
wget"
,
"
-qO"
,
"
-"
,
"
http://localhost:8081/api/v1/ping"
]
interval
:
10s
timeout
:
5s
# Services below are used for developers to run once
#
# You can just run `docker compose run --rm SERVICE_NAME` to use
# For example:
# To regenerate typescript code of gRPC proto
# Just run `docker compose run --rm buf`
#
# All of theses services belongs to profile 'tools'
# This will prevent to launch by normally `docker compose up` unexpectly
api-mysql
:
profiles
:
[
"
mysql"
]
depends_on
:
{
mysql
:
{
condition
:
service_healthy
}
}
hostname
:
api
environment
:
{
MEMOS_DRIVER
:
mysql
,
MEMOS_DSN
:
memos
:
memos@tcp(mysql)/memos
}
image
:
*api-image
ports
:
*api-ports
working_dir
:
*api-working-dir
volumes
:
*api-volumes
configs
:
*api-configs
entrypoint
:
*api-entrypoint
command
:
*api-command
healthcheck
:
*api-healthcheck
api-postgres
:
profiles
:
[
"
postgres"
]
depends_on
:
{
postgres
:
{
condition
:
service_healthy
}
}
hostname
:
api
environment
:
MEMOS_DSN
:
"
postgresql://memos:memos@postgres:5432/memos?sslmode=disable"
MEMOS_DRIVER
:
postgres
image
:
*api-image
ports
:
*api-ports
working_dir
:
*api-working-dir
volumes
:
*api-volumes
configs
:
*api-configs
entrypoint
:
*api-entrypoint
command
:
*api-command
healthcheck
:
*api-healthcheck
mysql
:
profiles
:
[
"
mysql"
]
image
:
mysql
environment
:
MYSQL_USER
:
memos
MYSQL_PASSWORD
:
memos
MYSQL_DATABASE
:
memos
MYSQL_ALLOW_EMPTY_PASSWORD
:
"
yes"
volumes
:
[
../.air/docker/mysql
:
/var/lib/mysql
]
healthcheck
:
test
:
[
"
CMD"
,
"
mysqladmin"
,
"
ping"
,
"
-h"
,
"
localhost"
]
interval
:
10s
timeout
:
5s
postgres
:
profiles
:
[
"
postgres"
]
image
:
postgres:alpine
hostname
:
postgres
volumes
:
[
../.air/docker/postgres
:
/var/lib/postgresql/data
]
environment
:
{
POSTGRES_DB
:
memos
,
POSTGRES_USER
:
memos
,
POSTGRES_PASSWORD
:
memos
}
healthcheck
:
test
:
[
"
CMD-SHELL"
,
"
pg_isready
-d
$${POSTGRES_DB}
-U
$${POSTGRES_USER}"
]
interval
:
10s
timeout
:
5s
pnpm
:
profiles
:
[
"
tools"
]
image
:
node:20-alpine
environment
:
{
NPM_CONFIG_UPDATE_NOTIFIER
:
false
}
working_dir
:
*web-working-dir
volumes
:
*web-volumes
tmpfs
:
*web-tmpfs
configs
:
-
source
:
pnpm-entrypoint.sh
target
:
/usr/local/bin/entrypoint.sh
entrypoint
:
[
"
sh"
,
"
/usr/local/bin/entrypoint.sh"
]
# Generate typescript code of gRPC proto
buf
:
profiles
:
[
"
tools"
]
image
:
bufbuild/buf
working_dir
:
/work/proto
command
:
generate
volumes
:
-
.
/.
./proto:/work/proto
-
.
/.
./web/src/types/:/work/web/src/types/
-
../proto:/work/proto
-
../web/src/types/:/work/web/src/types/
# Do golang static code check before create PR
golangci-lint
:
go
:
profiles
:
[
"
tools"
]
image
:
golangci/golangci-lint:v1.54.2
working_dir
:
/work/
entrypoint
:
golangci-lint
command
:
run -v
volumes
:
-
$HOME/go/pkg/:/go/pkg/
# Cache for go mod shared with the host
-
./../.air/go-build:/root/.cache/go-build
-
./..:/work/
image
:
*api-image
working_dir
:
*api-working-dir
volumes
:
*api-volumes
entrypoint
:
[
"
go"
]
# run npm
npm
:
goimports
:
profiles
:
[
"
tools"
]
image
:
node:20-alpine
working_dir
:
/work
environment
:
[
"
NPM_CONFIG_UPDATE_NOTIFIER=false"
]
entrypoint
:
"
npm"
volumes
:
-
./../web:/work
image
:
*api-image
working_dir
:
*api-working-dir
volumes
:
*api-volumes
configs
:
-
source
:
goimports-entrypoint.sh
target
:
/usr/local/bin/entrypoint.sh
entrypoint
:
[
"
/bin/sh"
,
"
/usr/local/bin/entrypoint.sh"
]
golangci-lint
:
profiles
:
[
"
tools"
]
image
:
*api-image
working_dir
:
*api-working-dir
volumes
:
*api-volumes
configs
:
-
source
:
golangci-lint-entrypoint.sh
target
:
/usr/local/bin/entrypoint.sh
entrypoint
:
[
"
/bin/sh"
,
"
/usr/local/bin/entrypoint.sh"
]
adminer-mysql
:
profiles
:
[
"
mysql"
]
depends_on
:
{
mysql
:
{
condition
:
service_healthy
}
}
image
:
adminer
environment
:
&adminer-environment
ADMINER_DEFAULT_DRIVER
:
server
# "server" is mysql
ADMINER_DEFAULT_SERVER
:
mysql
ADMINER_DEFAULT_USERNAME
:
memos
ADMINER_DEFAULT_PASSWORD
:
memos
ADMINER_DEFAULT_DB
:
memos
ADMINER_DESIGN
:
dracula
# light: pepa-linha | https://www.adminer.org/#extras
ADMINER_PLUGINS
:
tables-filter table-structure edit-textarea dump-json
# https://www.adminer.org/en/plugins/
ports
:
&adminer-ports
[
127.0.0.1
:
8091
:
8080
]
healthcheck
:
&adminer-healthcheck
test
:
'
php
-r
"exit(strpos(file_get_contents(\"http://localhost:8080/\"),
\"Adminer\")
!==
false
?
0
:
1);"'
interval
:
10s
timeout
:
5s
configs
:
&adminer-configs
-
source
:
adminer-index.php
target
:
/var/www/html/index.php
adminer-postgres
:
profiles
:
[
"
postgres"
]
depends_on
:
{
postgres
:
{
condition
:
service_healthy
}
}
image
:
adminer
ports
:
*adminer-ports
healthcheck
:
*adminer-healthcheck
configs
:
*adminer-configs
environment
:
<<
:
*adminer-environment
ADMINER_DEFAULT_DRIVER
:
pgsql
ADMINER_DEFAULT_SERVER
:
postgres
adminer-sqlite
:
profiles
:
[
"
sqlite"
]
image
:
adminer
ports
:
*adminer-ports
healthcheck
:
*adminer-healthcheck
configs
:
*adminer-configs
environment
:
<<
:
*adminer-environment
ADMINER_DEFAULT_PASSWORD
:
"
"
ADMINER_DEFAULT_DRIVER
:
sqlite
ADMINER_DEFAULT_DB
:
/data/memos_dev.db
volumes
:
[
../.air/docker/memosdata
:
/data
]
configs
:
# Patched version of adminer index.php to fill the login form with default values
# and allow passwordless login whenever ADMINER_DEFAULT_DRIVER is sqlite.
adminer-index.php
:
content
:
|
<?php
namespace docker {
function adminer_object() {
require_once('plugins/plugin.php');
class Adminer extends \AdminerPlugin {
function _callParent($$function, $$args) {
if ($$function === 'loginForm') {
ob_start();
$$return = \Adminer::loginForm();
$$form = ob_get_clean();
$$driver = $$_ENV["ADMINER_DEFAULT_DRIVER"] ?: "server";
$$server = $$_ENV["ADMINER_DEFAULT_SERVER"] ?: "db";
$$username = $$_ENV["ADMINER_DEFAULT_USERNAME"];
$$password = $$_ENV["ADMINER_DEFAULT_PASSWORD"];
$$db = $$_ENV["ADMINER_DEFAULT_DB"];
$$form = preg_replace('/ name="auth\[server\]" value="(.*)"/', ' name="auth[server]" value="' . $$server . '"', $$form);
$$form = str_replace(' id="username" value="" ', ' id="username" value="' . $$username . '" ', $$form);
$$form = str_replace('name="auth[db]" value=""', 'name="auth[db]" value="' . $$db . '" ', $$form);
$$form = str_replace('type="password"', 'type="password" value="' . $$password . '"', $$form);
$$form = preg_replace('/<option value="(.*)" selected/', '/<option value="$$1"/', $$form);
$$form = preg_replace('/<option value="' . $$driver . '"/', '<option value="' . $$driver . '" selected', $$form);
echo $$form;
return $$return;
}
return parent::_callParent($$function, $$args);
}
}
$$plugins = [];
foreach (glob('plugins-enabled/*.php') as $$plugin) {
$$plugins[] = require($$plugin);
}
class AdminerSoftware extends Adminer {
function login($$login, $$password) {
return substr($$_ENV["ADMINER_DEFAULT_DRIVER"], 0, 6) == 'sqlite' ? true : parent::login($$login, $$password);
}
}
return new AdminerSoftware($$plugins);
}
}
namespace {
if (basename($$_SERVER['DOCUMENT_URI'] ?? $$_SERVER['REQUEST_URI']) === 'adminer.css' && is_readable('adminer.css')) {
header('Content-Type: text/css');
readfile('adminer.css');
exit;
}
function adminer_object() {
return \docker\adminer_object();
}
require('adminer.php');
}
# Patched version of node's container entrypoint to run commands with pnpm by default.
pnpm-entrypoint.sh
:
content
:
|
set -eu
corepack enable pnpm
pnpm "$$@"
# Entrypoint for air container. Installs air and run passed commands.
air-entrypoint.sh
:
content
:
|
set -eu
if [ -z $$(command -v "air") ]; then
echo "Installing air..."
wget -O- -nv https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b \
$$(go env GOPATH)/bin v1.49.0
fi
cd /work
/go/bin/air "$$@"
# Entrypoint for goimports container.
goimports-entrypoint.sh
:
content
:
|
set -eu
if [ -z $$(command -v "goimports") ]; then
echo "Installing goimports..."
go install golang.org/x/tools/cmd/goimports@latest
fi
cd /work
echo "Running goimports..."
goimports "$$@"
# Entrypoint for golangci-lint container.
golangci-lint-entrypoint.sh
:
content
:
|
set -eu
if [ -z $$(command -v "golangci-lint") ]; then
echo "Installing golangci-lint..."
wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b \
$$(go env GOPATH)/bin v1.55.2
fi
cd /work
golangci-lint --version
golangci-lint "$$@"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment