feat: 修改app readme, 修改app详情页

This commit is contained in:
zhengkunwang223 2023-01-30 17:24:46 +08:00 committed by zhengkunwang223
parent ccf2e77fe2
commit 71b17a0930
37 changed files with 2200 additions and 128 deletions

View File

@ -24,104 +24,112 @@
"name": "MySQL",
"tags": ["Database"],
"versions": ["5.7.39","8.0.30"],
"short_desc": "开源关系型数据库管理系统",
"author": "Oracle",
"shortDesc": "开源关系型数据库管理系统",
"type": "runtime",
"required": [],
"crossVersionUpdate": false,
"limit": 1,
"source": "https://www.mysql.com"
"website": "https://www.mysql.com",
"github": "https://github.com/mysql/mysql-server",
"document": "https://dev.mysql.com/doc/"
},
{
"key": "nginx",
"name": "OpenResty",
"tags": ["Server"],
"versions": ["1.21.4"],
"short_desc": "基于 Nginx 和 LuaJIT 的高性能 Web 平台",
"author": "OpenResty",
"shortDesc": "基于 Nginx 和 LuaJIT 的高性能 Web 平台",
"type": "runtime",
"required": [],
"limit": 1,
"crossVersionUpdate": true,
"source": "https://openresty.org/"
"website": "https://openresty.org",
"github": "https://github.com/openresty/openresty",
"document": "http://openresty.org/cn/getting-started.html"
},
{
"key": "wordpress",
"name": "WordPress",
"tags": ["WebSite"],
"versions": ["6.0.1","6.0.2"],
"short_desc": "开源博客软件和内容管理系统",
"author": "Wordpress",
"shortDesc": "开源博客软件和内容管理系统",
"type": "website",
"required": ["mysql"],
"limit": 0,
"crossVersionUpdate": true,
"source": "http://wordpress.org/"
"website": "https://wordpress.org/",
"github": "https://github.com/WordPress/WordPress",
"document": "https://cn.wordpress.org/support/"
},
{
"key": "redis",
"name": "Redis",
"tags": ["Database"],
"versions": ["7.0.5","6.0.16"],
"short_desc": "高性能的 key-value 数据库",
"author": "Salvatore Sanfilippo",
"shortDesc": "高性能的 key-value 数据库",
"type": "runtime",
"required": [],
"limit": 1,
"crossVersionUpdate": true,
"source": "https://redis.io/"
"website": "https://redis.io/",
"github": "https://github.com/redis/redis",
"document": "https://redis.io/docs/"
},
{
"key": "halo",
"name": "Halo",
"tags": ["WebSite"],
"versions": ["1.6.0"],
"short_desc": "好用又强大的开源建站工具",
"author": "Halo",
"shortDesc": "好用又强大的开源建站工具",
"type": "website",
"required": ["mysql"],
"limit": 0,
"crossVersionUpdate": true,
"source": "https://halo.run/"
"website": "https://halo.run/",
"github": "https://github.com/halo-dev/halo",
"document": "https://docs.halo.run/"
},
{
"key": "phpmyadmin",
"name": "phpMyAdmin",
"tags": ["Tool"],
"versions": ["5.2.0"],
"short_desc": "MySQL 数据库管理工具",
"author": "phpmyadmin",
"shortDesc": "MySQL 数据库管理工具",
"type": "tool",
"required": ["mysql"],
"limit": 1,
"crossVersionUpdate": true,
"source": "https://www.phpmyadmin.net/"
"website": "https://www.phpmyadmin.net/",
"github": "https://github.com/phpmyadmin/phpmyadmin",
"document": "https://www.phpmyadmin.net/docs/"
},
{
"key": "redis-commander",
"name": "Redis-Commander",
"tags": ["Tool"],
"versions": ["0.8.0"],
"short_desc": "Redis web 管理工具",
"author": "redis-commander",
"shortDesc": "Redis web 管理工具",
"type": "tool",
"required": ["redis"],
"limit": 1,
"crossVersionUpdate": true,
"source": "https://github.com/joeferner/redis-commander"
"website": "http://joeferner.github.io/redis-commander/",
"github": "https://github.com/joeferner/redis-commander",
"document": "https://github.com/joeferner/redis-commander/blob/master/docs/configuration.md"
},
{
"key": "minio",
"name": "MinIO",
"tags": ["Tool"],
"versions": ["RELEASE.2022-08-13T21-54-44Z"],
"short_desc": "开源的对象存储服务器",
"author": "minio",
"shortDesc": "开源的对象存储服务器",
"type": "tool",
"required": [],
"limit": 1,
"crossVersionUpdate": true,
"source": "https://github.com/minio/minio"
"website": "https://min.io/download",
"github": "https://github.com/minio/minio",
"document": "https://min.io/docs/minio/kubernetes/upstream"
}
]
}

View File

@ -0,0 +1,266 @@
# MinIO Quickstart Guide
[![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![license](https://img.shields.io/badge/license-AGPL%20V3-blue)](https://github.com/minio/minio/blob/master/LICENSE)
[![MinIO](https://raw.githubusercontent.com/minio/minio/master/.github/logo.svg?sanitize=true)](https://min.io)
MinIO is a High Performance Object Storage released under GNU Affero General Public License v3.0. It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance infrastructure for machine learning, analytics and application data workloads.
This README provides quickstart instructions on running MinIO on bare metal hardware, including container-based installations. For Kubernetes environments, use the [MinIO Kubernetes Operator](https://github.com/minio/operator/blob/master/README.md).
## Container Installation
Use the following commands to run a standalone MinIO server as a container.
Standalone MinIO servers are best suited for early development and evaluation. Certain features such as versioning, object locking, and bucket replication
require distributed deploying MinIO with Erasure Coding. For extended development and production, deploy MinIO with Erasure Coding enabled - specifically,
with a *minimum* of 4 drives per MinIO server. See [MinIO Erasure Code Overview](https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html)
for more complete documentation.
### Stable
Run the following command to run the latest stable image of MinIO as a container using an ephemeral data volume:
```
podman run -p 9000:9000 -p 9001:9001 \
quay.io/minio/minio server /data --console-address ":9001"
```
The MinIO deployment starts using default root credentials `minioadmin:minioadmin`. You can test the deployment using the MinIO Console, an embedded
object browser built into MinIO Server. Point a web browser running on the host machine to <http://127.0.0.1:9000> and log in with the
root credentials. You can use the Browser to create buckets, upload objects, and browse the contents of the MinIO server.
You can also connect using any S3-compatible tool, such as the MinIO Client `mc` commandline tool. See
[Test using MinIO Client `mc`](#test-using-minio-client-mc) for more information on using the `mc` commandline tool. For application developers,
see <https://min.io/docs/minio/linux/developers/minio-drivers.html> to view MinIO SDKs for supported languages.
> NOTE: To deploy MinIO on with persistent storage, you must map local persistent directories from the host OS to the container using the `podman -v` option. For example, `-v /mnt/data:/data` maps the host OS drive at `/mnt/data` to `/data` on the container.
## macOS
Use the following commands to run a standalone MinIO server on macOS.
Standalone MinIO servers are best suited for early development and evaluation. Certain features such as versioning, object locking, and bucket replication require distributed deploying MinIO with Erasure Coding. For extended development and production, deploy MinIO with Erasure Coding enabled - specifically, with a *minimum* of 4 drives per MinIO server. See [MinIO Erasure Code Overview](https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html) for more complete documentation.
### Homebrew (recommended)
Run the following command to install the latest stable MinIO package using [Homebrew](https://brew.sh/). Replace ``/data`` with the path to the drive or directory in which you want MinIO to store data.
```
brew install minio/stable/minio
minio server /data
```
> NOTE: If you previously installed minio using `brew install minio` then it is recommended that you reinstall minio from `minio/stable/minio` official repo instead.
```
brew uninstall minio
brew install minio/stable/minio
```
The MinIO deployment starts using default root credentials `minioadmin:minioadmin`. You can test the deployment using the MinIO Console, an embedded web-based object browser built into MinIO Server. Point a web browser running on the host machine to <http://127.0.0.1:9000> and log in with the root credentials. You can use the Browser to create buckets, upload objects, and browse the contents of the MinIO server.
You can also connect using any S3-compatible tool, such as the MinIO Client `mc` commandline tool. See [Test using MinIO Client `mc`](#test-using-minio-client-mc) for more information on using the `mc` commandline tool. For application developers, see <https://min.io/docs/minio/linux/developers/minio-drivers.html/> to view MinIO SDKs for supported languages.
### Binary Download
Use the following command to download and run a standalone MinIO server on macOS. Replace ``/data`` with the path to the drive or directory in which you want MinIO to store data.
```
wget https://dl.min.io/server/minio/release/darwin-amd64/minio
chmod +x minio
./minio server /data
```
The MinIO deployment starts using default root credentials `minioadmin:minioadmin`. You can test the deployment using the MinIO Console, an embedded web-based object browser built into MinIO Server. Point a web browser running on the host machine to <http://127.0.0.1:9000> and log in with the root credentials. You can use the Browser to create buckets, upload objects, and browse the contents of the MinIO server.
You can also connect using any S3-compatible tool, such as the MinIO Client `mc` commandline tool. See [Test using MinIO Client `mc`](#test-using-minio-client-mc) for more information on using the `mc` commandline tool. For application developers, see <https://min.io/docs/minio/linux/developers/minio-drivers.html> to view MinIO SDKs for supported languages.
## GNU/Linux
Use the following command to run a standalone MinIO server on Linux hosts running 64-bit Intel/AMD architectures. Replace ``/data`` with the path to the drive or directory in which you want MinIO to store data.
```
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
./minio server /data
```
Replace ``/data`` with the path to the drive or directory in which you want MinIO to store data.
The following table lists supported architectures. Replace the `wget` URL with the architecture for your Linux host.
| Architecture | URL |
| -------- | ------ |
| 64-bit Intel/AMD | <https://dl.min.io/server/minio/release/linux-amd64/minio> |
| 64-bit ARM | <https://dl.min.io/server/minio/release/linux-arm64/minio> |
| 64-bit PowerPC LE (ppc64le) | <https://dl.min.io/server/minio/release/linux-ppc64le/minio> |
| IBM Z-Series (S390X) | <https://dl.min.io/server/minio/release/linux-s390x/minio> |
The MinIO deployment starts using default root credentials `minioadmin:minioadmin`. You can test the deployment using the MinIO Console, an embedded web-based object browser built into MinIO Server. Point a web browser running on the host machine to <http://127.0.0.1:9000> and log in with the root credentials. You can use the Browser to create buckets, upload objects, and browse the contents of the MinIO server.
You can also connect using any S3-compatible tool, such as the MinIO Client `mc` commandline tool. See [Test using MinIO Client `mc`](#test-using-minio-client-mc) for more information on using the `mc` commandline tool. For application developers, see <https://min.io/docs/minio/linux/developers/minio-drivers.html> to view MinIO SDKs for supported languages.
> NOTE: Standalone MinIO servers are best suited for early development and evaluation. Certain features such as versioning, object locking, and bucket replication require distributed deploying MinIO with Erasure Coding. For extended development and production, deploy MinIO with Erasure Coding enabled - specifically, with a *minimum* of 4 drives per MinIO server. See [MinIO Erasure Code Overview](https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html#) for more complete documentation.
## Microsoft Windows
To run MinIO on 64-bit Windows hosts, download the MinIO executable from the following URL:
```
https://dl.min.io/server/minio/release/windows-amd64/minio.exe
```
Use the following command to run a standalone MinIO server on the Windows host. Replace ``D:\`` with the path to the drive or directory in which you want MinIO to store data. You must change the terminal or powershell directory to the location of the ``minio.exe`` executable, *or* add the path to that directory to the system ``$PATH``:
```
minio.exe server D:\
```
The MinIO deployment starts using default root credentials `minioadmin:minioadmin`. You can test the deployment using the MinIO Console, an embedded web-based object browser built into MinIO Server. Point a web browser running on the host machine to <http://127.0.0.1:9000> and log in with the root credentials. You can use the Browser to create buckets, upload objects, and browse the contents of the MinIO server.
You can also connect using any S3-compatible tool, such as the MinIO Client `mc` commandline tool. See [Test using MinIO Client `mc`](#test-using-minio-client-mc) for more information on using the `mc` commandline tool. For application developers, see <https://min.io/docs/minio/linux/developers/minio-drivers.html> to view MinIO SDKs for supported languages.
> NOTE: Standalone MinIO servers are best suited for early development and evaluation. Certain features such as versioning, object locking, and bucket replication require distributed deploying MinIO with Erasure Coding. For extended development and production, deploy MinIO with Erasure Coding enabled - specifically, with a *minimum* of 4 drives per MinIO server. See [MinIO Erasure Code Overview](https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html#) for more complete documentation.
## Install from Source
Use the following commands to compile and run a standalone MinIO server from source. Source installation is only intended for developers and advanced users. If you do not have a working Golang environment, please follow [How to install Golang](https://golang.org/doc/install). Minimum version required is [go1.19](https://golang.org/dl/#stable)
```
go install github.com/minio/minio@latest
```
The MinIO deployment starts using default root credentials `minioadmin:minioadmin`. You can test the deployment using the MinIO Console, an embedded web-based object browser built into MinIO Server. Point a web browser running on the host machine to <http://127.0.0.1:9000> and log in with the root credentials. You can use the Browser to create buckets, upload objects, and browse the contents of the MinIO server.
You can also connect using any S3-compatible tool, such as the MinIO Client `mc` commandline tool. See [Test using MinIO Client `mc`](#test-using-minio-client-mc) for more information on using the `mc` commandline tool. For application developers, see <https://min.io/docs/minio/linux/developers/minio-drivers.html> to view MinIO SDKs for supported languages.
> NOTE: Standalone MinIO servers are best suited for early development and evaluation. Certain features such as versioning, object locking, and bucket replication require distributed deploying MinIO with Erasure Coding. For extended development and production, deploy MinIO with Erasure Coding enabled - specifically, with a *minimum* of 4 drives per MinIO server. See [MinIO Erasure Code Overview](https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html) for more complete documentation.
MinIO strongly recommends *against* using compiled-from-source MinIO servers for production environments.
## Deployment Recommendations
### Allow port access for Firewalls
By default MinIO uses the port 9000 to listen for incoming connections. If your platform blocks the port by default, you may need to enable access to the port.
### ufw
For hosts with ufw enabled (Debian based distros), you can use `ufw` command to allow traffic to specific ports. Use below command to allow access to port 9000
```
ufw allow 9000
```
Below command enables all incoming traffic to ports ranging from 9000 to 9010.
```
ufw allow 9000:9010/tcp
```
### firewall-cmd
For hosts with firewall-cmd enabled (CentOS), you can use `firewall-cmd` command to allow traffic to specific ports. Use below commands to allow access to port 9000
```
firewall-cmd --get-active-zones
```
This command gets the active zone(s). Now, apply port rules to the relevant zones returned above. For example if the zone is `public`, use
```
firewall-cmd --zone=public --add-port=9000/tcp --permanent
```
Note that `permanent` makes sure the rules are persistent across firewall start, restart or reload. Finally reload the firewall for changes to take effect.
```
firewall-cmd --reload
```
### iptables
For hosts with iptables enabled (RHEL, CentOS, etc), you can use `iptables` command to enable all traffic coming to specific ports. Use below command to allow
access to port 9000
```
iptables -A INPUT -p tcp --dport 9000 -j ACCEPT
service iptables restart
```
Below command enables all incoming traffic to ports ranging from 9000 to 9010.
```
iptables -A INPUT -p tcp --dport 9000:9010 -j ACCEPT
service iptables restart
```
## Test MinIO Connectivity
### Test using MinIO Console
MinIO Server comes with an embedded web based object browser. Point your web browser to <http://127.0.0.1:9000> to ensure your server has started successfully.
> NOTE: MinIO runs console on random port by default if you wish choose a specific port use `--console-address` to pick a specific interface and port.
### Things to consider
MinIO redirects browser access requests to the configured server port (i.e. `127.0.0.1:9000`) to the configured Console port. MinIO uses the hostname or IP address specified in the request when building the redirect URL. The URL and port *must* be accessible by the client for the redirection to work.
For deployments behind a load balancer, proxy, or ingress rule where the MinIO host IP address or port is not public, use the `MINIO_BROWSER_REDIRECT_URL` environment variable to specify the external hostname for the redirect. The LB/Proxy must have rules for directing traffic to the Console port specifically.
For example, consider a MinIO deployment behind a proxy `https://minio.example.net`, `https://console.minio.example.net` with rules for forwarding traffic on port :9000 and :9001 to MinIO and the MinIO Console respectively on the internal network. Set `MINIO_BROWSER_REDIRECT_URL` to `https://console.minio.example.net` to ensure the browser receives a valid reachable URL.
Similarly, if your TLS certificates do not have the IP SAN for the MinIO server host, the MinIO Console may fail to validate the connection to the server. Use the `MINIO_SERVER_URL` environment variable and specify the proxy-accessible hostname of the MinIO server to allow the Console to use the MinIO server API using the TLS certificate.
For example: `export MINIO_SERVER_URL="https://minio.example.net"`
| Dashboard | Creating a bucket |
| ------------- | ------------- |
| ![Dashboard](https://github.com/minio/minio/blob/master/docs/screenshots/pic1.png?raw=true) | ![Dashboard](https://github.com/minio/minio/blob/master/docs/screenshots/pic2.png?raw=true) |
## Test using MinIO Client `mc`
`mc` provides a modern alternative to UNIX commands like ls, cat, cp, mirror, diff etc. It supports filesystems and Amazon S3 compatible cloud storage services. Follow the MinIO Client [Quickstart Guide](https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart) for further instructions.
## Upgrading MinIO
Upgrades require zero downtime in MinIO, all upgrades are non-disruptive, all transactions on MinIO are atomic. So upgrading all the servers simultaneously is the recommended way to upgrade MinIO.
> NOTE: requires internet access to update directly from <https://dl.min.io>, optionally you can host any mirrors at <https://my-artifactory.example.com/minio/>
- For deployments that installed the MinIO server binary by hand, use [`mc admin update`](https://min.io/docs/minio/linux/reference/minio-mc-admin/mc-admin-update.html)
```
mc admin update <minio alias, e.g., myminio>
```
- For deployments without external internet access (e.g. airgapped environments), download the binary from <https://dl.min.io> and replace the existing MinIO binary let's say for example `/opt/bin/minio`, apply executable permissions `chmod +x /opt/bin/minio` and proceed to perform `mc admin service restart alias/`.
- For installations using Systemd MinIO service, upgrade via RPM/DEB packages **parallelly** on all servers or replace the binary lets say `/opt/bin/minio` on all nodes, apply executable permissions `chmod +x /opt/bin/minio` and process to perform `mc admin service restart alias/`.
### Upgrade Checklist
- Test all upgrades in a lower environment (DEV, QA, UAT) before applying to production. Performing blind upgrades in production environments carries significant risk.
- Read the release notes for MinIO *before* performing any upgrade, there is no forced requirement to upgrade to latest releases upon every releases. Some releases may not be relevant to your setup, avoid upgrading production environments unnecessarily.
- If you plan to use `mc admin update`, MinIO process must have write access to the parent directory where the binary is present on the host system.
- `mc admin update` is not supported and should be avoided in kubernetes/container environments, please upgrade containers by upgrading relevant container images.
- **We do not recommend upgrading one MinIO server at a time, the product is designed to support parallel upgrades please follow our recommended guidelines.**
## Explore Further
- [MinIO Erasure Code Overview](https://min.io/docs/minio/linux/operations/concepts/erasure-coding.html)
- [Use `mc` with MinIO Server](https://min.io/docs/minio/linux/reference/minio-mc.html)
- [Use `minio-go` SDK with MinIO Server](https://min.io/docs/minio/linux/developers/go/minio-go.html)
- [The MinIO documentation website](https://min.io/docs/minio/linux/index.html)
## Contribute to MinIO Project
Please follow MinIO [Contributor's Guide](https://github.com/minio/minio/blob/master/CONTRIBUTING.md)
## License
- MinIO source is licensed under the GNU AGPLv3 license that can be found in the [LICENSE](https://github.com/minio/minio/blob/master/LICENSE) file.
- MinIO [Documentation](https://github.com/minio/minio/tree/master/docs) © 2021 by MinIO, Inc is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
- [License Compliance](https://github.com/minio/minio/blob/master/COMPLIANCE.md)

View File

@ -1,5 +1,146 @@
# What is nginx?
- - -
Nginx (pronounced "engine-x") is an open source reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer, HTTP cache, and a web server (origin server). The nginx project started with a strong focus on high concurrency, high performance and low memory usage. It is licensed under the 2-clause BSD-like license and it runs on Linux, BSD variants, Mac OS X, Solaris, AIX, HP-UX, as well as on other *nix flavors. It also has a proof of concept port for Microsoft Windows.
Name
====
OpenResty - Turning Nginx into a Full-Fledged Scriptable Web Platform
Table of Contents
=================
* [Name](#name)
* [Description](#description)
* [For Users](#for-users)
* [For Bundle Maintainers](#for-bundle-maintainers)
* [Additional Features](#additional-features)
* [resolv.conf parsing](#resolvconf-parsing)
* [Mailing List](#mailing-list)
* [Report Bugs](#report-bugs)
* [Copyright & License](#copyright--license)
Description
===========
OpenResty is a full-fledged web application server by bundling the standard nginx core,
lots of 3rd-party nginx modules, as well as most of their external dependencies.
This bundle is maintained by Yichun Zhang (agentzh).
Because most of the nginx modules are developed by the bundle maintainers, it can ensure
that all these modules are played well together.
The bundled software components are copyrighted by the respective copyright holders.
The homepage for this project is on [openresty.org](https://openresty.org/).
For Users
---------
Visit the [download page](https://openresty.org/en/download.html) on the `openresty.org` web site
to download the latest bundle tarball, and
follow the installation instructions in the [installation page](https://openresty.org/en/installation.html).
For Bundle Maintainers
----------------------
The bundle's source is at the following git repository:
https://github.com/openresty/openresty
To reproduce the bundle tarball, just do
```
make
```
at the top of the bundle source tree.
Please note that you may need to install some extra dependencies, like `perl`, `dos2unix`, and `mercurial`.
On Fedora 22, for example, installing the dependencies
is as simple as running the following commands:
```
sudo dnf install perl dos2unix mercurial
```
[Back to TOC](#table-of-contents)
Additional Features
===================
In additional to the standard nginx core features, this bundle also supports the following:
[Back to TOC](#table-of-contents)
resolv.conf parsing
--------------------
**syntax:** *resolver address ... [valid=time] [ipv6=on|off] [local=on|off|path]*
**default:** *-*
**context:** *http, stream, server, location*
Similar to the [`resolver` directive](https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver)
in standard nginx core with additional support for parsing additional resolvers from the `resolv.conf` file
format.
When `local=on`, the standard path of `/etc/resolv.conf` will be used. You may also specify arbitrary
path to be used for parsing, for example: `local=/tmp/test.conf`.
When `local=off`, parsing will be disabled (this is the default).
This feature is not available on Windows platforms.
[Back to TOC](#table-of-contents)
Mailing List
============
You're very welcome to join the English OpenResty mailing list hosted on Google Groups:
https://groups.google.com/group/openresty-en
The Chinese mailing list is here:
https://groups.google.com/group/openresty
[Back to TOC](#table-of-contents)
Report Bugs
===========
You're very welcome to report issues on GitHub:
https://github.com/openresty/openresty/issues
[Back to TOC](#table-of-contents)
Copyright & License
===================
The bundle itself is licensed under the 2-clause BSD license.
Copyright (c) 2011-2019, Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, OpenResty Inc.
This module is licensed under the terms of the BSD license.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[Back to TOC](#table-of-contents)
[wikipedia.org/wiki/Nginx](http://wikipedia.org/wiki/Nginx)

View File

@ -0,0 +1,52 @@
phpMyAdmin - Readme
===================
Version 5.3.0-dev
A web interface for MySQL and MariaDB.
https://www.phpmyadmin.net/
Summary
-------
phpMyAdmin is intended to handle the administration of MySQL over the web.
For a summary of features, list of requirements, and installation instructions,
please see the documentation in the ./doc/ folder or at https://docs.phpmyadmin.net/
Copyright
---------
Copyright © 1998 onwards -- the phpMyAdmin team
Certain libraries are copyrighted by their respective authors;
see the full copyright list for details.
For full copyright information, please see ./doc/copyright.rst
License
-------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License version 2, as published by the
Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Licensing of current contributions
----------------------------------
Beginning on 2013-12-01, new contributions to this codebase are all licensed
under terms compatible with GPLv2-or-later. phpMyAdmin is currently
transitioning older code to GPLv2-or-later, but work is not yet complete.
Enjoy!
------
The phpMyAdmin team

View File

@ -0,0 +1,336 @@
# Redis Commander
Redis web management tool written in node.js
# Install and Run
```
$ npm install -g redis-commander
$ redis-commander
```
Installation via `yarn` is currently not supported. Please use `npm` as package manager.
Or run Redis Commander as Docker image `ghcr.io/joeferner/redis-commander` ~~rediscommander/redis-commander~~ (instructions see below).
Multi-Arch images built are available at `ghcr.io/joeferner/redis-commander:latest`.
(https://github.com/joeferner/redis-commander/pkgs/container/redis-commander)
Remark: new version are not published to Dockerhub right now.
# Features
Web-UI to display and edit data within multiple different Redis servers.
It has support for the following data types to view, add, update and delete data:
* Strings
* Lists
* Sets
* Sorted Set
* Streams (Basic support based on HFXBus project from https://github.com/exocet-engineering/hfx-bus, only view/add/delete data)
* ReJSON documents (Basic support, only for viewing values of ReJSON type keys)
# Usage
```
$ redis-commander --help
Options:
--redis-port The port to find redis on. [string]
--redis-host The host to find redis on. [string]
--redis-socket The unix-socket to find redis on. [string]
--redis-username The redis username. [string]
--redis-password The redis password. [string]
--redis-db The redis database. [string]
--redis-label The label to display for the connection. [string]
--redis-tls Use TLS for connection to redis server or sentinel. [boolean] [default: false]
--redis-optional Set to true if no permanent auto-reconnect shall be done if server is down [boolean] [default: false]
--sentinel-port The port to find redis sentinel on. [string]
--sentinel-host The host to find redis sentinel on. [string]
--sentinels Comma separated list of sentinels with host:port. [string]
--sentinel-name The redis sentinel group name to use. [string] [default: mymaster]
--sentinel-username The username for sentinel instance. [string]
--sentinel-password The password for sentinel instance. [string]
--http-auth-username, --http-u The http authorisation username. [string]
--http-auth-password, --http-p The http authorisation password. [string]
--http-auth-password-hash, --http-h The http authorisation password hash. [string]
--address, -a The address to run the server on. [string] [default: 0.0.0.0]
--port, -p The port to run the server on. [string] [default: 8081]
--url-prefix, -u The url prefix to respond on. [string] [default: ""]
--root-pattern, --rp The root pattern of the redis keys. [string] [default: "*"]
--read-only Start app in read-only mode. [boolean] [default: false]
--trust-proxy App is run behind proxy (enable Express "trust proxy") [boolean|string] [default: false]
--nosave, --ns Do not save new connections to config file. [boolean] [default: true]
--noload, --nl Do not load connections from config. [boolean] [default: false]
--use-scan, --sc Use scan instead of keys. [boolean] [default: false]
--clear-config, --cc Clear configuration file.
--migrate-config Migrate old configuration file in $HOME to new style.
--scan-count, --sc The size of each separate scan. [integer] [default: 100]
--no-log-data Do not log data values from redis store. [boolean] [default: false]
--open Open web-browser with Redis-Commander. [boolean] [default: false]
--folding-char, --fc Character to fold keys at in tree view. [character] [default: ":"]
--test, -t Test final configuration (file, env-vars, command line)
```
The connection can be established either via direct connection to redis server or indirect
via a sentinel instance. Most of this command line parameters map onto configuration params read from
the config file - see [docs/configuration.md](docs/configuration.md) and [docs/connections.md](docs/connections.md).
## Configuration
Redis Commander can be configured by configuration files, environment variables or using command line
parameters. The different types of config values overwrite each other, only the last (most important)
value is used.
For configuration files the `node-config` module (https://github.com/lorenwest/node-config) is used, with default to json syntax.
The order of precedence for all configuration values (from least to most important) is:
- Configuration files
`default.json` - this file contains all default values and SHOULD NOT be changed
`local.json` - optional file, all local overwrites for values inside default.json should be placed here as well
as a list of redis connections to use at startup
`local-<NODE_ENV>.json` - Do not add anything else than connections to this file! Redis Commander will overwrite this whenever a
connection is added or removed via user interface. Inside docker container this file is used to store
all connections parsed from REDIS_HOSTS env var.
This file overwrites all connections defined inside `local.json`
There are some more possible files available to use - please check the node-config Wiki
for an complete list of all possible file names (https://github.com/lorenwest/node-config/wiki/Configuration-Files)
- Environment variables - the full list of env vars possible (except the docker specific ones)
can be get from the file `config/custom-environment-variables.json` together with their mapping
to the respective configuration key.
- Command line parameters - Overwrites everything
To check the final configuration created from files, env-vars set and command line param overwrites
start redis commander with additional param "--test". All invalid configuration keys will be listed
in the output. The config test does not check if hostnames or ip addresses can be resolved.
More information can be found in the documentation at [docs/configuration.md](docs/configuration.md)
and [docs/connections.md](docs/connections.md).
## Environment Variables
These environment variables can be used starting Redis Commander as normal
application or inside docker container (defined inside file `config/custom-environment-variables.json`)
and at [docs/configuration.md](docs/configuration.md):
```
HTTP_USER
HTTP_PASSWORD
HTTP_PASSWORD_HASH
ADDRESS
PORT
READ_ONLY
URL_PREFIX
SIGNIN_PATH
ROOT_PATTERN
NOSAVE
NO_LOG_DATA
FOLDING_CHAR
VIEW_JSON_DEFAULT
USE_SCAN
SCAN_COUNT
FLUSH_ON_IMPORT
REDIS_CONNECTION_NAME
REDIS_LABEL
CLIENT_MAX_BODY_SIZE
BINARY_AS_HEX
```
## Docker
All environment variables listed at "Environment Variables" can be used running image
with Docker. The following additional environment variables are available too (defined inside
docker startup script):
```
HTTP_PASSWORD_FILE
HTTP_PASSWORD_HASH_FILE
REDIS_PORT
REDIS_HOST
REDIS_SOCKET
REDIS_TLS
REDIS_USERNAME
REDIS_PASSWORD
REDIS_PASSWORD_FILE
REDIS_DB
REDIS_HOSTS
REDIS_OPTIONAL
SENTINEL_PORT
SENTINEL_HOST
SENTINEL_NAME
SENTINEL_USERNAME
SENTINEL_PASSWORD
SENTINEL_PASSWORD_FILE
SENTINELS
K8S_SIGTERM
```
A (partial) description for the mapping onto the cli params and into the config files can be found
at the [docs/connections.md](docs/connections.md) file.
The `K8S_SIGTERM` variable (default "0") can be set to "1" to work around kubernetes specifics
to allow pod replacement with zero downtime. More information on how kubernetes handles termination of old pods and the
setup of new ones can be found within the thread [https://github.com/kubernetes/contrib/issues/1140#issuecomment-290836405]
Hosts can be optionally specified with a comma separated string by setting the `REDIS_HOSTS` environment variable.
After running the container, `redis-commander` will be available at [localhost:8081](http://localhost:8081).
### Valid host strings
the `REDIS_HOSTS` environment variable is a comma separated list of host definitions,
where each host should follow one of these templates:
`hostname`
`label:hostname`
`label:hostname:port`
`label:hostname:port:dbIndex`
`label:hostname:port:dbIndex:password`
Connection strings defined with `REDIS_HOSTS` variable do not support TLS connections.
If remote redis server needs TLS write all connections into a config file instead
of using `REDIS_HOSTS` (see [docs/connections.md](docs/connections.md) at the end
within the more complex examples).
### With docker-compose
```
version: '3'
services:
redis:
container_name: redis
hostname: redis
image: redis
redis-commander:
container_name: redis-commander
hostname: redis-commander
image: ghcr.io/joeferner/redis-commander:latest
restart: always
environment:
- REDIS_HOSTS=local:redis:6379
ports:
- "8081:8081"
```
### Without docker-compose
#### Simplest
If you're running redis on `localhost:6379`, this is all you need to get started.
```
docker run --rm --name redis-commander -d -p 8081:8081 \
ghcr.io/joeferner/redis-commander:latest
```
#### Specify single host
```
docker run --rm --name redis-commander -d -p 8081:8081 \
--env REDIS_HOSTS=10.10.20.30 \
ghcr.io/joeferner/redis-commander:latest
```
#### Specify multiple hosts with labels
```
docker run --rm --name redis-commander -d -p 8081:8081 \
--env REDIS_HOSTS=local:localhost:6379,myredis:10.10.20.30 \
ghcr.io/joeferner/redis-commander:latest
```
## Kubernetes
An example deployment can be found at [k8s/redis-commander/deployment.yaml](k8s/redis-commander/deployment.yaml).
If you already have a cluster running with `redis` in the default namespace, deploy `redis-commander` with `kubectl apply -f k8s/redis-commander`. If you don't have `redis` running yet, you can deploy a simple pod with `kubectl apply -f k8s/redis`.
Alternatively, you can add a container to a deployment's spec like this:
```
containers:
- name: redis-commander
image: ghcr.io/joeferner/redis-commander
env:
- name: REDIS_HOSTS
value: instance1:redis:6379
ports:
- name: redis-commander
containerPort: 8081
```
known issues with Kubernetes:
* using REDIS_HOSTS works only with a password-less redis db. You must specify REDIS_HOST on a password
protected redis db
## Helm chart
You can install the application on any Kubernetes cluster using Helm.
There is no helm repo available currently, therefore local checkout of helm sources inside
this repo is needed:
```
helm -n myspace install redis-web-ui ./k8s/helm-chart/redis-commander
```
More [Documentation](k8s/helm-chart/README.md) about this Helm chart and its values.
## OpenShift V3
To use the stock Node.js image builder do the following.
1. Open Catalog and select the Node.js template
1. Specify the name of the application and the URL to the [redis-command github repository](https://github.com/joeferner/redis-commander.git)
1. Click the ```advanced options``` link
1. (optional) specify the hostname for the route - _if one is not specified it will be generated_
1. In the Deployment Configuration section
* Add ```REDIS_HOST``` environment variable whose value is the name of the redis service - e.g., ```redis```
* Add ```REDIS_PORT``` environment variable whose value is the port exposed of the redis service - e.g., ```6379```
* Add value from secret generated by the [redis template](https://github.com/sclorg/redis-container/blob/master/examples/redis-persistent-template.json):
* name: ```REDIS_PASSWORD```
* resource: ```redis```
* key: ```database-password```
1. (optional) specify a label such as ```appl=redis-commander-dev1```
* _this label will be applied on all objects created allowing for easy deletion later via:_
```
oc delete all --selector appl=redis-commander-dev1
```
## Helper Scripts
### Generate BCrypted password hash
Redis commander allows setting either a plain text password for http authentication or an already bcrypted
password hash.
To generate a hashed password the script `bin/bcrypt-password.js` can be used. The parameter "-p" to set password should be given.
Usage example:
```
$ git clone https://github.com/joeferner/redis-commander.git
$ cd redis-commander/bin
$ node bcrypt-password.js -p myplainpass
$2b$10BQPbC8dlxeEqB/nXOkyjr.tlafGZ28J3ug8sWIMRoeq5LSVOXpl3W
```
This generated hash can be set inside the config file as "server.httpAuth.passwordHash", as env var "HTTP_PASSWORD_HASH"
or on the command line as `--http-auth-password-hash`.
Running inside docker image a file containing this password hash can be set via env var
`HTTP_PASSWORD_HASH_FILE`
## Build images based on this one
To use this images as a base image for other images you need to call "apk update" inside your Dockerfile
before adding other apk packages with "apk add foo". Afterwards, to reduce your image size, you may
remove all temporary apk configs too again as this Dockerfile does.

View File

@ -0,0 +1,506 @@
This README is just a fast *quick start* document. You can find more detailed documentation at [redis.io](https://redis.io).
What is Redis?
--------------
Redis is often referred to as a *data structures* server. What this means is that Redis provides access to mutable data structures via a set of commands, which are sent using a *server-client* model with TCP sockets and a simple protocol. So different processes can query and modify the same data structures in a shared way.
Data structures implemented into Redis have a few special properties:
* Redis cares to store them on disk, even if they are always served and modified into the server memory. This means that Redis is fast, but that it is also non-volatile.
* The implementation of data structures emphasizes memory efficiency, so data structures inside Redis will likely use less memory compared to the same data structure modelled using a high-level programming language.
* Redis offers a number of features that are natural to find in a database, like replication, tunable levels of durability, clustering, and high availability.
Another good example is to think of Redis as a more complex version of memcached, where the operations are not just SETs and GETs, but operations that work with complex data types like Lists, Sets, ordered data structures, and so forth.
If you want to know more, this is a list of selected starting points:
* Introduction to Redis data types. https://redis.io/topics/data-types-intro
* Try Redis directly inside your browser. https://try.redis.io
* The full list of Redis commands. https://redis.io/commands
* There is much more inside the official Redis documentation. https://redis.io/documentation
Building Redis
--------------
Redis can be compiled and used on Linux, OSX, OpenBSD, NetBSD, FreeBSD.
We support big endian and little endian architectures, and both 32 bit
and 64 bit systems.
It may compile on Solaris derived systems (for instance SmartOS) but our
support for this platform is *best effort* and Redis is not guaranteed to
work as well as in Linux, OSX, and \*BSD.
It is as simple as:
% make
To build with TLS support, you'll need OpenSSL development libraries (e.g.
libssl-dev on Debian/Ubuntu) and run:
% make BUILD_TLS=yes
To build with systemd support, you'll need systemd development libraries (such
as libsystemd-dev on Debian/Ubuntu or systemd-devel on CentOS) and run:
% make USE_SYSTEMD=yes
To append a suffix to Redis program names, use:
% make PROG_SUFFIX="-alt"
You can build a 32 bit Redis binary using:
% make 32bit
After building Redis, it is a good idea to test it using:
% make test
If TLS is built, running the tests with TLS enabled (you will need `tcl-tls`
installed):
% ./utils/gen-test-certs.sh
% ./runtest --tls
Fixing build problems with dependencies or cached build options
---------
Redis has some dependencies which are included in the `deps` directory.
`make` does not automatically rebuild dependencies even if something in
the source code of dependencies changes.
When you update the source code with `git pull` or when code inside the
dependencies tree is modified in any other way, make sure to use the following
command in order to really clean everything and rebuild from scratch:
% make distclean
This will clean: jemalloc, lua, hiredis, linenoise and other dependencies.
Also if you force certain build options like 32bit target, no C compiler
optimizations (for debugging purposes), and other similar build time options,
those options are cached indefinitely until you issue a `make distclean`
command.
Fixing problems building 32 bit binaries
---------
If after building Redis with a 32 bit target you need to rebuild it
with a 64 bit target, or the other way around, you need to perform a
`make distclean` in the root directory of the Redis distribution.
In case of build errors when trying to build a 32 bit binary of Redis, try
the following steps:
* Install the package libc6-dev-i386 (also try g++-multilib).
* Try using the following command line instead of `make 32bit`:
`make CFLAGS="-m32 -march=native" LDFLAGS="-m32"`
Allocator
---------
Selecting a non-default memory allocator when building Redis is done by setting
the `MALLOC` environment variable. Redis is compiled and linked against libc
malloc by default, with the exception of jemalloc being the default on Linux
systems. This default was picked because jemalloc has proven to have fewer
fragmentation problems than libc malloc.
To force compiling against libc malloc, use:
% make MALLOC=libc
To compile against jemalloc on Mac OS X systems, use:
% make MALLOC=jemalloc
Monotonic clock
---------------
By default, Redis will build using the POSIX clock_gettime function as the
monotonic clock source. On most modern systems, the internal processor clock
can be used to improve performance. Cautions can be found here:
http://oliveryang.net/2015/09/pitfalls-of-TSC-usage/
To build with support for the processor's internal instruction clock, use:
% make CFLAGS="-DUSE_PROCESSOR_CLOCK"
Verbose build
-------------
Redis will build with a user-friendly colorized output by default.
If you want to see a more verbose output, use the following:
% make V=1
Running Redis
-------------
To run Redis with the default configuration, just type:
% cd src
% ./redis-server
If you want to provide your redis.conf, you have to run it using an additional
parameter (the path of the configuration file):
% cd src
% ./redis-server /path/to/redis.conf
It is possible to alter the Redis configuration by passing parameters directly
as options using the command line. Examples:
% ./redis-server --port 9999 --replicaof 127.0.0.1 6379
% ./redis-server /etc/redis/6379.conf --loglevel debug
All the options in redis.conf are also supported as options using the command
line, with exactly the same name.
Running Redis with TLS:
------------------
Please consult the [TLS.md](TLS.md) file for more information on
how to use Redis with TLS.
Playing with Redis
------------------
You can use redis-cli to play with Redis. Start a redis-server instance,
then in another terminal try the following:
% cd src
% ./redis-cli
redis> ping
PONG
redis> set foo bar
OK
redis> get foo
"bar"
redis> incr mycounter
(integer) 1
redis> incr mycounter
(integer) 2
redis>
You can find the list of all the available commands at https://redis.io/commands.
Installing Redis
-----------------
In order to install Redis binaries into /usr/local/bin, just use:
% make install
You can use `make PREFIX=/some/other/directory install` if you wish to use a
different destination.
`make install` will just install binaries in your system, but will not configure
init scripts and configuration files in the appropriate place. This is not
needed if you just want to play a bit with Redis, but if you are installing
it the proper way for a production system, we have a script that does this
for Ubuntu and Debian systems:
% cd utils
% ./install_server.sh
_Note_: `install_server.sh` will not work on Mac OSX; it is built for Linux only.
The script will ask you a few questions and will setup everything you need
to run Redis properly as a background daemon that will start again on
system reboots.
You'll be able to stop and start Redis using the script named
`/etc/init.d/redis_<portnumber>`, for instance `/etc/init.d/redis_6379`.
Code contributions
-----------------
Note: By contributing code to the Redis project in any form, including sending
a pull request via Github, a code fragment or patch via private email or
public discussion groups, you agree to release your code under the terms
of the BSD license that you can find in the [COPYING][1] file included in the Redis
source distribution.
Please see the [CONTRIBUTING.md][2] file in this source distribution for more
information. For security bugs and vulnerabilities, please see [SECURITY.md][3].
[1]: https://github.com/redis/redis/blob/unstable/COPYING
[2]: https://github.com/redis/redis/blob/unstable/CONTRIBUTING.md
[3]: https://github.com/redis/redis/blob/unstable/SECURITY.md
Redis internals
===
If you are reading this README you are likely in front of a Github page
or you just untarred the Redis distribution tar ball. In both the cases
you are basically one step away from the source code, so here we explain
the Redis source code layout, what is in each file as a general idea, the
most important functions and structures inside the Redis server and so forth.
We keep all the discussion at a high level without digging into the details
since this document would be huge otherwise and our code base changes
continuously, but a general idea should be a good starting point to
understand more. Moreover most of the code is heavily commented and easy
to follow.
Source code layout
---
The Redis root directory just contains this README, the Makefile which
calls the real Makefile inside the `src` directory and an example
configuration for Redis and Sentinel. You can find a few shell
scripts that are used in order to execute the Redis, Redis Cluster and
Redis Sentinel unit tests, which are implemented inside the `tests`
directory.
Inside the root are the following important directories:
* `src`: contains the Redis implementation, written in C.
* `tests`: contains the unit tests, implemented in Tcl.
* `deps`: contains libraries Redis uses. Everything needed to compile Redis is inside this directory; your system just needs to provide `libc`, a POSIX compatible interface and a C compiler. Notably `deps` contains a copy of `jemalloc`, which is the default allocator of Redis under Linux. Note that under `deps` there are also things which started with the Redis project, but for which the main repository is not `redis/redis`.
There are a few more directories but they are not very important for our goals
here. We'll focus mostly on `src`, where the Redis implementation is contained,
exploring what there is inside each file. The order in which files are
exposed is the logical one to follow in order to disclose different layers
of complexity incrementally.
Note: lately Redis was refactored quite a bit. Function names and file
names have been changed, so you may find that this documentation reflects the
`unstable` branch more closely. For instance, in Redis 3.0 the `server.c`
and `server.h` files were named `redis.c` and `redis.h`. However the overall
structure is the same. Keep in mind that all the new developments and pull
requests should be performed against the `unstable` branch.
server.h
---
The simplest way to understand how a program works is to understand the
data structures it uses. So we'll start from the main header file of
Redis, which is `server.h`.
All the server configuration and in general all the shared state is
defined in a global structure called `server`, of type `struct redisServer`.
A few important fields in this structure are:
* `server.db` is an array of Redis databases, where data is stored.
* `server.commands` is the command table.
* `server.clients` is a linked list of clients connected to the server.
* `server.master` is a special client, the master, if the instance is a replica.
There are tons of other fields. Most fields are commented directly inside
the structure definition.
Another important Redis data structure is the one defining a client.
In the past it was called `redisClient`, now just `client`. The structure
has many fields, here we'll just show the main ones:
```
struct client {
int fd;
sds querybuf;
int argc;
robj **argv;
redisDb *db;
int flags;
list *reply;
// ... many other fields ...
char buf[PROTO_REPLY_CHUNK_BYTES];
}
```
The client structure defines a *connected client*:
* The `fd` field is the client socket file descriptor.
* `argc` and `argv` are populated with the command the client is executing, so that functions implementing a given Redis command can read the arguments.
* `querybuf` accumulates the requests from the client, which are parsed by the Redis server according to the Redis protocol and executed by calling the implementations of the commands the client is executing.
* `reply` and `buf` are dynamic and static buffers that accumulate the replies the server sends to the client. These buffers are incrementally written to the socket as soon as the file descriptor is writable.
As you can see in the client structure above, arguments in a command
are described as `robj` structures. The following is the full `robj`
structure, which defines a *Redis object*:
```
struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
* and most significant 16 bits access time). */
int refcount;
void *ptr;
};
```
Basically this structure can represent all the basic Redis data types like
strings, lists, sets, sorted sets and so forth. The interesting thing is that
it has a `type` field, so that it is possible to know what type a given
object has, and a `refcount`, so that the same object can be referenced
in multiple places without allocating it multiple times. Finally the `ptr`
field points to the actual representation of the object, which might vary
even for the same type, depending on the `encoding` used.
Redis objects are used extensively in the Redis internals, however in order
to avoid the overhead of indirect accesses, recently in many places
we just use plain dynamic strings not wrapped inside a Redis object.
server.c
---
This is the entry point of the Redis server, where the `main()` function
is defined. The following are the most important steps in order to startup
the Redis server.
* `initServerConfig()` sets up the default values of the `server` structure.
* `initServer()` allocates the data structures needed to operate, setup the listening socket, and so forth.
* `aeMain()` starts the event loop which listens for new connections.
There are two special functions called periodically by the event loop:
1. `serverCron()` is called periodically (according to `server.hz` frequency), and performs tasks that must be performed from time to time, like checking for timed out clients.
2. `beforeSleep()` is called every time the event loop fired, Redis served a few requests, and is returning back into the event loop.
Inside server.c you can find code that handles other vital things of the Redis server:
* `call()` is used in order to call a given command in the context of a given client.
* `activeExpireCycle()` handles eviction of keys with a time to live set via the `EXPIRE` command.
* `performEvictions()` is called when a new write command should be performed but Redis is out of memory according to the `maxmemory` directive.
* The global variable `redisCommandTable` defines all the Redis commands, specifying the name of the command, the function implementing the command, the number of arguments required, and other properties of each command.
commands.c
---
This file is auto generated by utils/generate-command-code.py, the content is based on the JSON files in the src/commands folder.
These are meant to be the single source of truth about the Redis commands, and all the metadata about them.
These JSON files are not meant to be used by anyone directly, instead that metadata can be obtained via the `COMMAND` command.
networking.c
---
This file defines all the I/O functions with clients, masters and replicas
(which in Redis are just special clients):
* `createClient()` allocates and initializes a new client.
* The `addReply*()` family of functions are used by command implementations in order to append data to the client structure, that will be transmitted to the client as a reply for a given command executed.
* `writeToClient()` transmits the data pending in the output buffers to the client and is called by the *writable event handler* `sendReplyToClient()`.
* `readQueryFromClient()` is the *readable event handler* and accumulates data read from the client into the query buffer.
* `processInputBuffer()` is the entry point in order to parse the client query buffer according to the Redis protocol. Once commands are ready to be processed, it calls `processCommand()` which is defined inside `server.c` in order to actually execute the command.
* `freeClient()` deallocates, disconnects and removes a client.
aof.c and rdb.c
---
As you can guess from the names, these files implement the RDB and AOF
persistence for Redis. Redis uses a persistence model based on the `fork()`
system call in order to create a process with the same (shared) memory
content of the main Redis process. This secondary process dumps the content
of the memory on disk. This is used by `rdb.c` to create the snapshots
on disk and by `aof.c` in order to perform the AOF rewrite when the
append only file gets too big.
The implementation inside `aof.c` has additional functions in order to
implement an API that allows commands to append new commands into the AOF
file as clients execute them.
The `call()` function defined inside `server.c` is responsible for calling
the functions that in turn will write the commands into the AOF.
db.c
---
Certain Redis commands operate on specific data types; others are general.
Examples of generic commands are `DEL` and `EXPIRE`. They operate on keys
and not on their values specifically. All those generic commands are
defined inside `db.c`.
Moreover `db.c` implements an API in order to perform certain operations
on the Redis dataset without directly accessing the internal data structures.
The most important functions inside `db.c` which are used in many command
implementations are the following:
* `lookupKeyRead()` and `lookupKeyWrite()` are used in order to get a pointer to the value associated to a given key, or `NULL` if the key does not exist.
* `dbAdd()` and its higher level counterpart `setKey()` create a new key in a Redis database.
* `dbDelete()` removes a key and its associated value.
* `emptyDb()` removes an entire single database or all the databases defined.
The rest of the file implements the generic commands exposed to the client.
object.c
---
The `robj` structure defining Redis objects was already described. Inside
`object.c` there are all the functions that operate with Redis objects at
a basic level, like functions to allocate new objects, handle the reference
counting and so forth. Notable functions inside this file:
* `incrRefCount()` and `decrRefCount()` are used in order to increment or decrement an object reference count. When it drops to 0 the object is finally freed.
* `createObject()` allocates a new object. There are also specialized functions to allocate string objects having a specific content, like `createStringObjectFromLongLong()` and similar functions.
This file also implements the `OBJECT` command.
replication.c
---
This is one of the most complex files inside Redis, it is recommended to
approach it only after getting a bit familiar with the rest of the code base.
In this file there is the implementation of both the master and replica role
of Redis.
One of the most important functions inside this file is `replicationFeedSlaves()` that writes commands to the clients representing replica instances connected
to our master, so that the replicas can get the writes performed by the clients:
this way their data set will remain synchronized with the one in the master.
This file also implements both the `SYNC` and `PSYNC` commands that are
used in order to perform the first synchronization between masters and
replicas, or to continue the replication after a disconnection.
Script
---
The script unit is composed of 3 units:
* `script.c` - integration of scripts with Redis (commands execution, set replication/resp, ...)
* `script_lua.c` - responsible to execute Lua code, uses script.c to interact with Redis from within the Lua code.
* `function_lua.c` - contains the Lua engine implementation, uses script_lua.c to execute the Lua code.
* `functions.c` - contains Redis Functions implementation (FUNCTION command), uses functions_lua.c if the function it wants to invoke needs the Lua engine.
* `eval.c` - contains the `eval` implementation using `script_lua.c` to invoke the Lua code.
Other C files
---
* `t_hash.c`, `t_list.c`, `t_set.c`, `t_string.c`, `t_zset.c` and `t_stream.c` contains the implementation of the Redis data types. They implement both an API to access a given data type, and the client command implementations for these data types.
* `ae.c` implements the Redis event loop, it's a self contained library which is simple to read and understand.
* `sds.c` is the Redis string library, check https://github.com/antirez/sds for more information.
* `anet.c` is a library to use POSIX networking in a simpler way compared to the raw interface exposed by the kernel.
* `dict.c` is an implementation of a non-blocking hash table which rehashes incrementally.
* `cluster.c` implements the Redis Cluster. Probably a good read only after being very familiar with the rest of the Redis code base. If you want to read `cluster.c` make sure to read the [Redis Cluster specification][4].
[4]: https://redis.io/topics/cluster-spec
Anatomy of a Redis command
---
All the Redis commands are defined in the following way:
```
void foobarCommand(client *c) {
printf("%s",c->argv[1]->ptr); /* Do something with the argument. */
addReply(c,shared.ok); /* Reply something to the client. */
}
```
The command function is referenced by a JSON file, together with its metadata, see `commands.c` described above for details.
The command flags are documented in the comment above the `struct redisCommand` in `server.h`.
For other details, please refer to the `COMMAND` command. https://redis.io/commands/command/
After the command operates in some way, it returns a reply to the client,
usually using `addReply()` or a similar function defined inside `networking.c`.
There are tons of command implementations inside the Redis source code
that can serve as examples of actual commands implementations (e.g. pingCommand). Writing
a few toy commands can be a good exercise to get familiar with the code base.
There are also many other files not described here, but it is useless to
cover everything. We just want to help you with the first steps.
Eventually you'll find your way inside the Redis code base :-)
Enjoy!

View File

@ -0,0 +1,506 @@
This README is just a fast *quick start* document. You can find more detailed documentation at [redis.io](https://redis.io).
What is Redis?
--------------
Redis is often referred to as a *data structures* server. What this means is that Redis provides access to mutable data structures via a set of commands, which are sent using a *server-client* model with TCP sockets and a simple protocol. So different processes can query and modify the same data structures in a shared way.
Data structures implemented into Redis have a few special properties:
* Redis cares to store them on disk, even if they are always served and modified into the server memory. This means that Redis is fast, but that it is also non-volatile.
* The implementation of data structures emphasizes memory efficiency, so data structures inside Redis will likely use less memory compared to the same data structure modelled using a high-level programming language.
* Redis offers a number of features that are natural to find in a database, like replication, tunable levels of durability, clustering, and high availability.
Another good example is to think of Redis as a more complex version of memcached, where the operations are not just SETs and GETs, but operations that work with complex data types like Lists, Sets, ordered data structures, and so forth.
If you want to know more, this is a list of selected starting points:
* Introduction to Redis data types. https://redis.io/topics/data-types-intro
* Try Redis directly inside your browser. https://try.redis.io
* The full list of Redis commands. https://redis.io/commands
* There is much more inside the official Redis documentation. https://redis.io/documentation
Building Redis
--------------
Redis can be compiled and used on Linux, OSX, OpenBSD, NetBSD, FreeBSD.
We support big endian and little endian architectures, and both 32 bit
and 64 bit systems.
It may compile on Solaris derived systems (for instance SmartOS) but our
support for this platform is *best effort* and Redis is not guaranteed to
work as well as in Linux, OSX, and \*BSD.
It is as simple as:
% make
To build with TLS support, you'll need OpenSSL development libraries (e.g.
libssl-dev on Debian/Ubuntu) and run:
% make BUILD_TLS=yes
To build with systemd support, you'll need systemd development libraries (such
as libsystemd-dev on Debian/Ubuntu or systemd-devel on CentOS) and run:
% make USE_SYSTEMD=yes
To append a suffix to Redis program names, use:
% make PROG_SUFFIX="-alt"
You can build a 32 bit Redis binary using:
% make 32bit
After building Redis, it is a good idea to test it using:
% make test
If TLS is built, running the tests with TLS enabled (you will need `tcl-tls`
installed):
% ./utils/gen-test-certs.sh
% ./runtest --tls
Fixing build problems with dependencies or cached build options
---------
Redis has some dependencies which are included in the `deps` directory.
`make` does not automatically rebuild dependencies even if something in
the source code of dependencies changes.
When you update the source code with `git pull` or when code inside the
dependencies tree is modified in any other way, make sure to use the following
command in order to really clean everything and rebuild from scratch:
% make distclean
This will clean: jemalloc, lua, hiredis, linenoise and other dependencies.
Also if you force certain build options like 32bit target, no C compiler
optimizations (for debugging purposes), and other similar build time options,
those options are cached indefinitely until you issue a `make distclean`
command.
Fixing problems building 32 bit binaries
---------
If after building Redis with a 32 bit target you need to rebuild it
with a 64 bit target, or the other way around, you need to perform a
`make distclean` in the root directory of the Redis distribution.
In case of build errors when trying to build a 32 bit binary of Redis, try
the following steps:
* Install the package libc6-dev-i386 (also try g++-multilib).
* Try using the following command line instead of `make 32bit`:
`make CFLAGS="-m32 -march=native" LDFLAGS="-m32"`
Allocator
---------
Selecting a non-default memory allocator when building Redis is done by setting
the `MALLOC` environment variable. Redis is compiled and linked against libc
malloc by default, with the exception of jemalloc being the default on Linux
systems. This default was picked because jemalloc has proven to have fewer
fragmentation problems than libc malloc.
To force compiling against libc malloc, use:
% make MALLOC=libc
To compile against jemalloc on Mac OS X systems, use:
% make MALLOC=jemalloc
Monotonic clock
---------------
By default, Redis will build using the POSIX clock_gettime function as the
monotonic clock source. On most modern systems, the internal processor clock
can be used to improve performance. Cautions can be found here:
http://oliveryang.net/2015/09/pitfalls-of-TSC-usage/
To build with support for the processor's internal instruction clock, use:
% make CFLAGS="-DUSE_PROCESSOR_CLOCK"
Verbose build
-------------
Redis will build with a user-friendly colorized output by default.
If you want to see a more verbose output, use the following:
% make V=1
Running Redis
-------------
To run Redis with the default configuration, just type:
% cd src
% ./redis-server
If you want to provide your redis.conf, you have to run it using an additional
parameter (the path of the configuration file):
% cd src
% ./redis-server /path/to/redis.conf
It is possible to alter the Redis configuration by passing parameters directly
as options using the command line. Examples:
% ./redis-server --port 9999 --replicaof 127.0.0.1 6379
% ./redis-server /etc/redis/6379.conf --loglevel debug
All the options in redis.conf are also supported as options using the command
line, with exactly the same name.
Running Redis with TLS:
------------------
Please consult the [TLS.md](TLS.md) file for more information on
how to use Redis with TLS.
Playing with Redis
------------------
You can use redis-cli to play with Redis. Start a redis-server instance,
then in another terminal try the following:
% cd src
% ./redis-cli
redis> ping
PONG
redis> set foo bar
OK
redis> get foo
"bar"
redis> incr mycounter
(integer) 1
redis> incr mycounter
(integer) 2
redis>
You can find the list of all the available commands at https://redis.io/commands.
Installing Redis
-----------------
In order to install Redis binaries into /usr/local/bin, just use:
% make install
You can use `make PREFIX=/some/other/directory install` if you wish to use a
different destination.
`make install` will just install binaries in your system, but will not configure
init scripts and configuration files in the appropriate place. This is not
needed if you just want to play a bit with Redis, but if you are installing
it the proper way for a production system, we have a script that does this
for Ubuntu and Debian systems:
% cd utils
% ./install_server.sh
_Note_: `install_server.sh` will not work on Mac OSX; it is built for Linux only.
The script will ask you a few questions and will setup everything you need
to run Redis properly as a background daemon that will start again on
system reboots.
You'll be able to stop and start Redis using the script named
`/etc/init.d/redis_<portnumber>`, for instance `/etc/init.d/redis_6379`.
Code contributions
-----------------
Note: By contributing code to the Redis project in any form, including sending
a pull request via Github, a code fragment or patch via private email or
public discussion groups, you agree to release your code under the terms
of the BSD license that you can find in the [COPYING][1] file included in the Redis
source distribution.
Please see the [CONTRIBUTING.md][2] file in this source distribution for more
information. For security bugs and vulnerabilities, please see [SECURITY.md][3].
[1]: https://github.com/redis/redis/blob/unstable/COPYING
[2]: https://github.com/redis/redis/blob/unstable/CONTRIBUTING.md
[3]: https://github.com/redis/redis/blob/unstable/SECURITY.md
Redis internals
===
If you are reading this README you are likely in front of a Github page
or you just untarred the Redis distribution tar ball. In both the cases
you are basically one step away from the source code, so here we explain
the Redis source code layout, what is in each file as a general idea, the
most important functions and structures inside the Redis server and so forth.
We keep all the discussion at a high level without digging into the details
since this document would be huge otherwise and our code base changes
continuously, but a general idea should be a good starting point to
understand more. Moreover most of the code is heavily commented and easy
to follow.
Source code layout
---
The Redis root directory just contains this README, the Makefile which
calls the real Makefile inside the `src` directory and an example
configuration for Redis and Sentinel. You can find a few shell
scripts that are used in order to execute the Redis, Redis Cluster and
Redis Sentinel unit tests, which are implemented inside the `tests`
directory.
Inside the root are the following important directories:
* `src`: contains the Redis implementation, written in C.
* `tests`: contains the unit tests, implemented in Tcl.
* `deps`: contains libraries Redis uses. Everything needed to compile Redis is inside this directory; your system just needs to provide `libc`, a POSIX compatible interface and a C compiler. Notably `deps` contains a copy of `jemalloc`, which is the default allocator of Redis under Linux. Note that under `deps` there are also things which started with the Redis project, but for which the main repository is not `redis/redis`.
There are a few more directories but they are not very important for our goals
here. We'll focus mostly on `src`, where the Redis implementation is contained,
exploring what there is inside each file. The order in which files are
exposed is the logical one to follow in order to disclose different layers
of complexity incrementally.
Note: lately Redis was refactored quite a bit. Function names and file
names have been changed, so you may find that this documentation reflects the
`unstable` branch more closely. For instance, in Redis 3.0 the `server.c`
and `server.h` files were named `redis.c` and `redis.h`. However the overall
structure is the same. Keep in mind that all the new developments and pull
requests should be performed against the `unstable` branch.
server.h
---
The simplest way to understand how a program works is to understand the
data structures it uses. So we'll start from the main header file of
Redis, which is `server.h`.
All the server configuration and in general all the shared state is
defined in a global structure called `server`, of type `struct redisServer`.
A few important fields in this structure are:
* `server.db` is an array of Redis databases, where data is stored.
* `server.commands` is the command table.
* `server.clients` is a linked list of clients connected to the server.
* `server.master` is a special client, the master, if the instance is a replica.
There are tons of other fields. Most fields are commented directly inside
the structure definition.
Another important Redis data structure is the one defining a client.
In the past it was called `redisClient`, now just `client`. The structure
has many fields, here we'll just show the main ones:
```
struct client {
int fd;
sds querybuf;
int argc;
robj **argv;
redisDb *db;
int flags;
list *reply;
// ... many other fields ...
char buf[PROTO_REPLY_CHUNK_BYTES];
}
```
The client structure defines a *connected client*:
* The `fd` field is the client socket file descriptor.
* `argc` and `argv` are populated with the command the client is executing, so that functions implementing a given Redis command can read the arguments.
* `querybuf` accumulates the requests from the client, which are parsed by the Redis server according to the Redis protocol and executed by calling the implementations of the commands the client is executing.
* `reply` and `buf` are dynamic and static buffers that accumulate the replies the server sends to the client. These buffers are incrementally written to the socket as soon as the file descriptor is writable.
As you can see in the client structure above, arguments in a command
are described as `robj` structures. The following is the full `robj`
structure, which defines a *Redis object*:
```
struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
* and most significant 16 bits access time). */
int refcount;
void *ptr;
};
```
Basically this structure can represent all the basic Redis data types like
strings, lists, sets, sorted sets and so forth. The interesting thing is that
it has a `type` field, so that it is possible to know what type a given
object has, and a `refcount`, so that the same object can be referenced
in multiple places without allocating it multiple times. Finally the `ptr`
field points to the actual representation of the object, which might vary
even for the same type, depending on the `encoding` used.
Redis objects are used extensively in the Redis internals, however in order
to avoid the overhead of indirect accesses, recently in many places
we just use plain dynamic strings not wrapped inside a Redis object.
server.c
---
This is the entry point of the Redis server, where the `main()` function
is defined. The following are the most important steps in order to startup
the Redis server.
* `initServerConfig()` sets up the default values of the `server` structure.
* `initServer()` allocates the data structures needed to operate, setup the listening socket, and so forth.
* `aeMain()` starts the event loop which listens for new connections.
There are two special functions called periodically by the event loop:
1. `serverCron()` is called periodically (according to `server.hz` frequency), and performs tasks that must be performed from time to time, like checking for timed out clients.
2. `beforeSleep()` is called every time the event loop fired, Redis served a few requests, and is returning back into the event loop.
Inside server.c you can find code that handles other vital things of the Redis server:
* `call()` is used in order to call a given command in the context of a given client.
* `activeExpireCycle()` handles eviction of keys with a time to live set via the `EXPIRE` command.
* `performEvictions()` is called when a new write command should be performed but Redis is out of memory according to the `maxmemory` directive.
* The global variable `redisCommandTable` defines all the Redis commands, specifying the name of the command, the function implementing the command, the number of arguments required, and other properties of each command.
commands.c
---
This file is auto generated by utils/generate-command-code.py, the content is based on the JSON files in the src/commands folder.
These are meant to be the single source of truth about the Redis commands, and all the metadata about them.
These JSON files are not meant to be used by anyone directly, instead that metadata can be obtained via the `COMMAND` command.
networking.c
---
This file defines all the I/O functions with clients, masters and replicas
(which in Redis are just special clients):
* `createClient()` allocates and initializes a new client.
* The `addReply*()` family of functions are used by command implementations in order to append data to the client structure, that will be transmitted to the client as a reply for a given command executed.
* `writeToClient()` transmits the data pending in the output buffers to the client and is called by the *writable event handler* `sendReplyToClient()`.
* `readQueryFromClient()` is the *readable event handler* and accumulates data read from the client into the query buffer.
* `processInputBuffer()` is the entry point in order to parse the client query buffer according to the Redis protocol. Once commands are ready to be processed, it calls `processCommand()` which is defined inside `server.c` in order to actually execute the command.
* `freeClient()` deallocates, disconnects and removes a client.
aof.c and rdb.c
---
As you can guess from the names, these files implement the RDB and AOF
persistence for Redis. Redis uses a persistence model based on the `fork()`
system call in order to create a process with the same (shared) memory
content of the main Redis process. This secondary process dumps the content
of the memory on disk. This is used by `rdb.c` to create the snapshots
on disk and by `aof.c` in order to perform the AOF rewrite when the
append only file gets too big.
The implementation inside `aof.c` has additional functions in order to
implement an API that allows commands to append new commands into the AOF
file as clients execute them.
The `call()` function defined inside `server.c` is responsible for calling
the functions that in turn will write the commands into the AOF.
db.c
---
Certain Redis commands operate on specific data types; others are general.
Examples of generic commands are `DEL` and `EXPIRE`. They operate on keys
and not on their values specifically. All those generic commands are
defined inside `db.c`.
Moreover `db.c` implements an API in order to perform certain operations
on the Redis dataset without directly accessing the internal data structures.
The most important functions inside `db.c` which are used in many command
implementations are the following:
* `lookupKeyRead()` and `lookupKeyWrite()` are used in order to get a pointer to the value associated to a given key, or `NULL` if the key does not exist.
* `dbAdd()` and its higher level counterpart `setKey()` create a new key in a Redis database.
* `dbDelete()` removes a key and its associated value.
* `emptyDb()` removes an entire single database or all the databases defined.
The rest of the file implements the generic commands exposed to the client.
object.c
---
The `robj` structure defining Redis objects was already described. Inside
`object.c` there are all the functions that operate with Redis objects at
a basic level, like functions to allocate new objects, handle the reference
counting and so forth. Notable functions inside this file:
* `incrRefCount()` and `decrRefCount()` are used in order to increment or decrement an object reference count. When it drops to 0 the object is finally freed.
* `createObject()` allocates a new object. There are also specialized functions to allocate string objects having a specific content, like `createStringObjectFromLongLong()` and similar functions.
This file also implements the `OBJECT` command.
replication.c
---
This is one of the most complex files inside Redis, it is recommended to
approach it only after getting a bit familiar with the rest of the code base.
In this file there is the implementation of both the master and replica role
of Redis.
One of the most important functions inside this file is `replicationFeedSlaves()` that writes commands to the clients representing replica instances connected
to our master, so that the replicas can get the writes performed by the clients:
this way their data set will remain synchronized with the one in the master.
This file also implements both the `SYNC` and `PSYNC` commands that are
used in order to perform the first synchronization between masters and
replicas, or to continue the replication after a disconnection.
Script
---
The script unit is composed of 3 units:
* `script.c` - integration of scripts with Redis (commands execution, set replication/resp, ...)
* `script_lua.c` - responsible to execute Lua code, uses script.c to interact with Redis from within the Lua code.
* `function_lua.c` - contains the Lua engine implementation, uses script_lua.c to execute the Lua code.
* `functions.c` - contains Redis Functions implementation (FUNCTION command), uses functions_lua.c if the function it wants to invoke needs the Lua engine.
* `eval.c` - contains the `eval` implementation using `script_lua.c` to invoke the Lua code.
Other C files
---
* `t_hash.c`, `t_list.c`, `t_set.c`, `t_string.c`, `t_zset.c` and `t_stream.c` contains the implementation of the Redis data types. They implement both an API to access a given data type, and the client command implementations for these data types.
* `ae.c` implements the Redis event loop, it's a self contained library which is simple to read and understand.
* `sds.c` is the Redis string library, check https://github.com/antirez/sds for more information.
* `anet.c` is a library to use POSIX networking in a simpler way compared to the raw interface exposed by the kernel.
* `dict.c` is an implementation of a non-blocking hash table which rehashes incrementally.
* `cluster.c` implements the Redis Cluster. Probably a good read only after being very familiar with the rest of the Redis code base. If you want to read `cluster.c` make sure to read the [Redis Cluster specification][4].
[4]: https://redis.io/topics/cluster-spec
Anatomy of a Redis command
---
All the Redis commands are defined in the following way:
```
void foobarCommand(client *c) {
printf("%s",c->argv[1]->ptr); /* Do something with the argument. */
addReply(c,shared.ok); /* Reply something to the client. */
}
```
The command function is referenced by a JSON file, together with its metadata, see `commands.c` described above for details.
The command flags are documented in the comment above the `struct redisCommand` in `server.h`.
For other details, please refer to the `COMMAND` command. https://redis.io/commands/command/
After the command operates in some way, it returns a reply to the client,
usually using `addReply()` or a similar function defined inside `networking.c`.
There are tons of command implementations inside the Redis source code
that can serve as examples of actual commands implementations (e.g. pingCommand). Writing
a few toy commands can be a good exercise to get familiar with the code base.
There are also many other files not described here, but it is useless to
cover everything. We just want to help you with the first steps.
Eventually you'll find your way inside the Redis code base :-)
Enjoy!

View File

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WordPress &#8250; ReadMe</title>
<link rel="stylesheet" href="wp-admin/css/install.css?ver=20100228" type="text/css" />
</head>
<body>
<h1 id="logo">
<a href="https://wordpress.org/"><img alt="WordPress" src="wp-admin/images/wordpress-logo.png" /></a>
</h1>
<p style="text-align: center">Semantic Personal Publishing Platform</p>
<h2>First Things First</h2>
<p>Welcome. WordPress is a very special project to me. Every developer and contributor adds something unique to the mix, and together we create something beautiful that I am proud to be a part of. Thousands of hours have gone into WordPress, and we are dedicated to making it better every day. Thank you for making it part of your world.</p>
<p style="text-align: right">&#8212; Matt Mullenweg</p>
<h2>Installation: Famous 5-minute install</h2>
<ol>
<li>Unzip the package in an empty directory and upload everything.</li>
<li>Open <span class="file"><a href="wp-admin/install.php">wp-admin/install.php</a></span> in your browser. It will take you through the process to set up a <code>wp-config.php</code> file with your database connection details.
<ol>
<li>If for some reason this does not work, do not worry. It may not work on all web hosts. Open up <code>wp-config-sample.php</code> with a text editor like WordPad or similar and fill in your database connection details.</li>
<li>Save the file as <code>wp-config.php</code> and upload it.</li>
<li>Open <span class="file"><a href="wp-admin/install.php">wp-admin/install.php</a></span> in your browser.</li>
</ol>
</li>
<li>Once the configuration file is set up, the installer will set up the tables needed for your site. If there is an error, double check your <code>wp-config.php</code> file, and try again. If it fails again, please go to the <a href="https://wordpress.org/support/forums/">WordPress support forums</a> with as much data as you can gather.</li>
<li><strong>If you did not enter a password, note the password given to you.</strong> If you did not provide a username, it will be <code>admin</code>.</li>
<li>The installer should then send you to the <a href="wp-login.php">login page</a>. Sign in with the username and password you chose during the installation. If a password was generated for you, you can then click on &#8220;Profile&#8221; to change the password.</li>
</ol>
<h2>Updating</h2>
<h3>Using the Automatic Updater</h3>
<ol>
<li>Open <span class="file"><a href="wp-admin/update-core.php">wp-admin/update-core.php</a></span> in your browser and follow the instructions.</li>
<li>You wanted more, perhaps? That&#8217;s it!</li>
</ol>
<h3>Updating Manually</h3>
<ol>
<li>Before you update anything, make sure you have backup copies of any files you may have modified such as <code>index.php</code>.</li>
<li>Delete your old WordPress files, saving ones you&#8217;ve modified.</li>
<li>Upload the new files.</li>
<li>Point your browser to <span class="file"><a href="wp-admin/upgrade.php">/wp-admin/upgrade.php</a>.</span></li>
</ol>
<h2>Migrating from other systems</h2>
<p>WordPress can <a href="https://wordpress.org/support/article/importing-content/">import from a number of systems</a>. First you need to get WordPress installed and working as described above, before using <a href="wp-admin/import.php">our import tools</a>.</p>
<h2>System Requirements</h2>
<ul>
<li><a href="https://secure.php.net/">PHP</a> version <strong>5.6.20</strong> or greater.</li>
<li><a href="https://www.mysql.com/">MySQL</a> version <strong>5.0</strong> or greater.</li>
</ul>
<h3>Recommendations</h3>
<ul>
<li><a href="https://secure.php.net/">PHP</a> version <strong>7.4</strong> or greater.</li>
<li><a href="https://www.mysql.com/">MySQL</a> version <strong>5.7</strong> or greater OR <a href="https://mariadb.org/">MariaDB</a> version <strong>10.3</strong> or greater.</li>
<li>The <a href="https://httpd.apache.org/docs/2.2/mod/mod_rewrite.html">mod_rewrite</a> Apache module.</li>
<li><a href="https://wordpress.org/news/2016/12/moving-toward-ssl/">HTTPS</a> support.</li>
<li>A link to <a href="https://wordpress.org/">wordpress.org</a> on your site.</li>
</ul>
<h2>Online Resources</h2>
<p>If you have any questions that are not addressed in this document, please take advantage of WordPress&#8217; numerous online resources:</p>
<dl>
<dt><a href="https://wordpress.org/support/">HelpHub</a></dt>
<dd>HelpHub is the encyclopedia of all things WordPress. It is the most comprehensive source of information for WordPress available.</dd>
<dt><a href="https://wordpress.org/news/">The WordPress Blog</a></dt>
<dd>This is where you&#8217;ll find the latest updates and news related to WordPress. Recent WordPress news appears in your administrative dashboard by default.</dd>
<dt><a href="https://planet.wordpress.org/">WordPress Planet</a></dt>
<dd>The WordPress Planet is a news aggregator that brings together posts from WordPress blogs around the web.</dd>
<dt><a href="https://wordpress.org/support/forums/">WordPress Support Forums</a></dt>
<dd>If you&#8217;ve looked everywhere and still cannot find an answer, the support forums are very active and have a large community ready to help. To help them help you be sure to use a descriptive thread title and describe your question in as much detail as possible.</dd>
<dt><a href="https://make.wordpress.org/support/handbook/appendix/other-support-locations/introduction-to-irc/">WordPress <abbr>IRC</abbr> (Internet Relay Chat) Channel</a></dt>
<dd>There is an online chat channel that is used for discussion among people who use WordPress and occasionally support topics. The above wiki page should point you in the right direction. (<a href="https://web.libera.chat/#wordpress">irc.libera.chat #wordpress</a>)</dd>
</dl>
<h2>Final Notes</h2>
<ul>
<li>If you have any suggestions, ideas, or comments, or if you (gasp!) found a bug, join us in the <a href="https://wordpress.org/support/forums/">Support Forums</a>.</li>
<li>WordPress has a robust plugin <abbr>API</abbr> (Application Programming Interface) that makes extending the code easy. If you are a developer interested in utilizing this, see the <a href="https://developer.wordpress.org/plugins/">Plugin Developer Handbook</a>. You shouldn&#8217;t modify any of the core code.</li>
</ul>
<h2>Share the Love</h2>
<p>WordPress has no multi-million dollar marketing campaign or celebrity sponsors, but we do have something even better&#8212;you. If you enjoy WordPress please consider telling a friend, setting it up for someone less knowledgeable than yourself, or writing the author of a media article that overlooks us.</p>
<p>WordPress is the official continuation of <a href="https://cafelog.com/">b2/caf&#233;log</a>, which came from Michel V. The work has been continued by the <a href="https://wordpress.org/about/">WordPress developers</a>. If you would like to support WordPress, please consider <a href="https://wordpress.org/donate/">donating</a>.</p>
<h2>License</h2>
<p>WordPress is free software, and is released under the terms of the <abbr>GPL</abbr> (GNU General Public License) version 2 or (at your option) any later version. See <a href="license.txt">license.txt</a>.</p>
</body>
</html>

View File

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WordPress &#8250; ReadMe</title>
<link rel="stylesheet" href="wp-admin/css/install.css?ver=20100228" type="text/css" />
</head>
<body>
<h1 id="logo">
<a href="https://wordpress.org/"><img alt="WordPress" src="wp-admin/images/wordpress-logo.png" /></a>
</h1>
<p style="text-align: center">Semantic Personal Publishing Platform</p>
<h2>First Things First</h2>
<p>Welcome. WordPress is a very special project to me. Every developer and contributor adds something unique to the mix, and together we create something beautiful that I am proud to be a part of. Thousands of hours have gone into WordPress, and we are dedicated to making it better every day. Thank you for making it part of your world.</p>
<p style="text-align: right">&#8212; Matt Mullenweg</p>
<h2>Installation: Famous 5-minute install</h2>
<ol>
<li>Unzip the package in an empty directory and upload everything.</li>
<li>Open <span class="file"><a href="wp-admin/install.php">wp-admin/install.php</a></span> in your browser. It will take you through the process to set up a <code>wp-config.php</code> file with your database connection details.
<ol>
<li>If for some reason this does not work, do not worry. It may not work on all web hosts. Open up <code>wp-config-sample.php</code> with a text editor like WordPad or similar and fill in your database connection details.</li>
<li>Save the file as <code>wp-config.php</code> and upload it.</li>
<li>Open <span class="file"><a href="wp-admin/install.php">wp-admin/install.php</a></span> in your browser.</li>
</ol>
</li>
<li>Once the configuration file is set up, the installer will set up the tables needed for your site. If there is an error, double check your <code>wp-config.php</code> file, and try again. If it fails again, please go to the <a href="https://wordpress.org/support/forums/">WordPress support forums</a> with as much data as you can gather.</li>
<li><strong>If you did not enter a password, note the password given to you.</strong> If you did not provide a username, it will be <code>admin</code>.</li>
<li>The installer should then send you to the <a href="wp-login.php">login page</a>. Sign in with the username and password you chose during the installation. If a password was generated for you, you can then click on &#8220;Profile&#8221; to change the password.</li>
</ol>
<h2>Updating</h2>
<h3>Using the Automatic Updater</h3>
<ol>
<li>Open <span class="file"><a href="wp-admin/update-core.php">wp-admin/update-core.php</a></span> in your browser and follow the instructions.</li>
<li>You wanted more, perhaps? That&#8217;s it!</li>
</ol>
<h3>Updating Manually</h3>
<ol>
<li>Before you update anything, make sure you have backup copies of any files you may have modified such as <code>index.php</code>.</li>
<li>Delete your old WordPress files, saving ones you&#8217;ve modified.</li>
<li>Upload the new files.</li>
<li>Point your browser to <span class="file"><a href="wp-admin/upgrade.php">/wp-admin/upgrade.php</a>.</span></li>
</ol>
<h2>Migrating from other systems</h2>
<p>WordPress can <a href="https://wordpress.org/support/article/importing-content/">import from a number of systems</a>. First you need to get WordPress installed and working as described above, before using <a href="wp-admin/import.php">our import tools</a>.</p>
<h2>System Requirements</h2>
<ul>
<li><a href="https://secure.php.net/">PHP</a> version <strong>5.6.20</strong> or greater.</li>
<li><a href="https://www.mysql.com/">MySQL</a> version <strong>5.0</strong> or greater.</li>
</ul>
<h3>Recommendations</h3>
<ul>
<li><a href="https://secure.php.net/">PHP</a> version <strong>7.4</strong> or greater.</li>
<li><a href="https://www.mysql.com/">MySQL</a> version <strong>5.7</strong> or greater OR <a href="https://mariadb.org/">MariaDB</a> version <strong>10.3</strong> or greater.</li>
<li>The <a href="https://httpd.apache.org/docs/2.2/mod/mod_rewrite.html">mod_rewrite</a> Apache module.</li>
<li><a href="https://wordpress.org/news/2016/12/moving-toward-ssl/">HTTPS</a> support.</li>
<li>A link to <a href="https://wordpress.org/">wordpress.org</a> on your site.</li>
</ul>
<h2>Online Resources</h2>
<p>If you have any questions that are not addressed in this document, please take advantage of WordPress&#8217; numerous online resources:</p>
<dl>
<dt><a href="https://wordpress.org/support/">HelpHub</a></dt>
<dd>HelpHub is the encyclopedia of all things WordPress. It is the most comprehensive source of information for WordPress available.</dd>
<dt><a href="https://wordpress.org/news/">The WordPress Blog</a></dt>
<dd>This is where you&#8217;ll find the latest updates and news related to WordPress. Recent WordPress news appears in your administrative dashboard by default.</dd>
<dt><a href="https://planet.wordpress.org/">WordPress Planet</a></dt>
<dd>The WordPress Planet is a news aggregator that brings together posts from WordPress blogs around the web.</dd>
<dt><a href="https://wordpress.org/support/forums/">WordPress Support Forums</a></dt>
<dd>If you&#8217;ve looked everywhere and still cannot find an answer, the support forums are very active and have a large community ready to help. To help them help you be sure to use a descriptive thread title and describe your question in as much detail as possible.</dd>
<dt><a href="https://make.wordpress.org/support/handbook/appendix/other-support-locations/introduction-to-irc/">WordPress <abbr>IRC</abbr> (Internet Relay Chat) Channel</a></dt>
<dd>There is an online chat channel that is used for discussion among people who use WordPress and occasionally support topics. The above wiki page should point you in the right direction. (<a href="https://web.libera.chat/#wordpress">irc.libera.chat #wordpress</a>)</dd>
</dl>
<h2>Final Notes</h2>
<ul>
<li>If you have any suggestions, ideas, or comments, or if you (gasp!) found a bug, join us in the <a href="https://wordpress.org/support/forums/">Support Forums</a>.</li>
<li>WordPress has a robust plugin <abbr>API</abbr> (Application Programming Interface) that makes extending the code easy. If you are a developer interested in utilizing this, see the <a href="https://developer.wordpress.org/plugins/">Plugin Developer Handbook</a>. You shouldn&#8217;t modify any of the core code.</li>
</ul>
<h2>Share the Love</h2>
<p>WordPress has no multi-million dollar marketing campaign or celebrity sponsors, but we do have something even better&#8212;you. If you enjoy WordPress please consider telling a friend, setting it up for someone less knowledgeable than yourself, or writing the author of a media article that overlooks us.</p>
<p>WordPress is the official continuation of <a href="https://cafelog.com/">b2/caf&#233;log</a>, which came from Michel V. The work has been continued by the <a href="https://wordpress.org/about/">WordPress developers</a>. If you would like to support WordPress, please consider <a href="https://wordpress.org/donate/">donating</a>.</p>
<h2>License</h2>
<p>WordPress is free software, and is released under the terms of the <abbr>GPL</abbr> (GNU General Public License) version 2 or (at your option) any later version. See <a href="license.txt">license.txt</a>.</p>
</body>
</html>

View File

@ -42,13 +42,14 @@ type AppDefine struct {
Name string `json:"name"`
Tags []string `json:"tags"`
Versions []string `json:"versions"`
Author string `json:"author"`
Source string `json:"source"`
ShortDesc string `json:"short_desc"`
ShortDesc string `json:"shortDesc"`
Type string `json:"type"`
Required []string `json:"Required"`
CrossVersionUpdate bool `json:"crossVersionUpdate"`
Limit int `json:"limit"`
Website string `json:"website"`
Github string `json:"github"`
Document string `json:"document"`
}
func (define AppDefine) GetRequired() string {

View File

@ -6,13 +6,14 @@ type App struct {
Key string `json:"key" gorm:"type:varchar(64);not null;uniqueIndex"`
ShortDesc string `json:"shortDesc" gorm:"type:longtext;"`
Icon string `json:"icon" gorm:"type:longtext;"`
Author string `json:"author" gorm:"type:varchar(64);not null"`
Source string `json:"source" gorm:"type:varchar(64);not null"`
Type string `json:"type" gorm:"type:varchar(64);not null"`
Status string `json:"status" gorm:"type:varchar(64);not null"`
Required string `json:"required" gorm:"type:varchar(64);not null"`
CrossVersionUpdate bool `json:"crossVersionUpdate"`
Limit int `json:"limit" gorm:"type:Integer;not null"`
Website string `json:"website" gorm:"type:varchar(64);not null"`
Github string `json:"github" gorm:"type:varchar(64);not null"`
Document string `json:"document" gorm:"type:varchar(64);not null"`
Details []AppDetail `json:"-"`
TagsKey []string `json:"-" gorm:"-"`
AppTags []AppTag `json:"-" `

View File

@ -468,8 +468,9 @@ func getApps(oldApps []model.App, items []dto.AppDefine) map[string]model.App {
app.Limit = item.Limit
app.Key = item.Key
app.ShortDesc = item.ShortDesc
app.Author = item.Author
app.Source = item.Source
app.Website = item.Website
app.Document = item.Document
app.Github = item.Github
app.Type = item.Type
app.CrossVersionUpdate = item.CrossVersionUpdate
app.Required = item.GetRequired()

View File

@ -44,6 +44,7 @@ declare module 'vue' {
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElFooter: typeof import('element-plus/es')['ElFooter']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormColumn: typeof import('element-plus/es')['ElFormColumn']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']

View File

@ -813,7 +813,7 @@ export default {
installed: '已安装',
all: '全部',
version: '版本',
detail: '详情',
detail: '应用详情',
install: '安装',
author: '作者',
source: '来源',
@ -864,6 +864,11 @@ export default {
hour: '小时',
minute: '分钟',
less1Minute: '小于1分钟',
appWebsite: '官网',
appOfficeWebsite: '官方网站',
github: '开源社区',
doc: '文档',
document: '文档说明',
},
website: {
website: '网站',
@ -879,6 +884,7 @@ export default {
remark: '备注',
group: '分组',
groupSetting: '分组管理',
createGroup: '新建分组',
app: '应用',
appNew: '新装应用',
appInstalled: '已装应用',
@ -904,14 +910,14 @@ export default {
dnsAccount: 'DNS账号',
applySSL: '证书申请',
SSLList: '证书列表',
createDnsAccount: 'DNS账',
createDnsAccount: 'DNS账',
aliyun: '阿里云DNS',
manual: '手动解析',
key: '密钥',
check: '查看',
acmeAccountManage: 'Acme 账户管理',
acmeAccountManage: 'Acme 账户',
email: '邮箱',
addAccount: '账户',
addAccount: '账户',
acmeAccount: 'Acme 账户',
provider: '验证方式',
dnsCommon: '手动解析',
@ -920,7 +926,7 @@ export default {
deploySSL: '部署',
deploySSLHelper: '确定部署证书',
ssl: '证书',
dnsAccountManage: 'DNS 账户管理',
dnsAccountManage: 'DNS 账户',
renewSSL: '续签',
renewHelper: '确定续签证书',
renewSuccess: '续签证书',
@ -1040,6 +1046,7 @@ export default {
saveAndReload: '保存并重载',
},
ssl: {
create: '新建证书',
provider: '类型',
manualCreate: '手动创建',
acmeAccount: 'Acme 账号',
@ -1059,6 +1066,7 @@ export default {
autoRenewHelper: '距离到期时间7天自动续签',
renewSuccess: '续签成功',
renewWebsite: '该证书已经和以下网站关联续签会同步应用到这些网站',
createAcme: '新建账户',
},
firewall: {
ccDeny: 'CC 防护',

View File

@ -9,6 +9,12 @@
<div class="content-container__toolbar" v-if="slots.toolbar">
<slot name="toolbar"></slot>
</div>
<div class="content-container__search" v-if="slots.search">
<el-card>
<slot name="search"></slot>
</el-card>
</div>
<div class="content-container_form">
<slot name="form">
<form-button>
@ -43,11 +49,15 @@
<slot v-if="slots.rightButton" name="rightButton"></slot>
</span>
</span>
<div v-if="prop.divider">
<div class="divider"></div>
</div>
</slot>
</div>
<div v-if="slots.prompt">
<slot name="prompt"></slot>
</div>
<slot name="main"></slot>
</el-card>
</div>
@ -67,6 +77,7 @@ const prop = defineProps({
backName: String,
backTo: Object,
reload: Boolean,
divider: Boolean,
});
const showBack = computed(() => {
@ -105,11 +116,9 @@ const showBack = computed(() => {
margin-top: 20px;
}
.el-divider--horizontal {
display: block;
height: 1px;
width: 100%;
margin: 10px 0;
border-top: 1px var(--el-border-color) var(--el-border-style);
.divider {
margin-top: 20px;
border: 0;
border-top: 1px solid #f2f2f2;
}
</style>

View File

@ -152,7 +152,7 @@ html.dark {
}
}
// el-drawer
// el-drawer :close-on-click-modal="false"
.el-drawer {
.el-drawer__header {
border-bottom: var(--panel-border-light) !important;

View File

@ -1,5 +1,5 @@
<template>
<LayoutContent v-loading="loading" v-if="!showDetail" :title="$t('app.app')">
<LayoutContent v-loading="loading" v-if="!showDetail" :title="$t('app.app')" :divider="true">
<template #toolbar>
<el-row :gutter="5">
<el-col :span="20">
@ -36,7 +36,6 @@
<el-button @click="sync" type="text" :plain="true">{{ $t('app.syncAppList') }}</el-button>
</template>
<template #main>
<div class="divider"></div>
<el-row :gutter="5">
<el-col v-for="(app, index) in apps" :key="index" :span="8">
<div class="app-card">
@ -223,14 +222,4 @@ onMounted(() => {
.tag-button {
margin-left: 10px;
}
.divider {
margin-top: 5px;
border: 0;
border-top: 1px solid #f2f2f2;
}
.el-avatar {
--el-avatar-bg-color: #ffffff;
}
</style>

View File

@ -1,26 +1,23 @@
<template>
<LayoutContent :title="$t('app.detail')" :reload="true" :v-loading="loadingDetail">
<LayoutContent :title="$t('app.detail')" :reload="true" :v-loading="loadingDetail" :divider="true">
<template #main>
<div class="brief">
<el-row :gutter="20">
<el-col :span="4">
<div class="icon">
<el-image class="image" :src="'data:image/png;base64,' + app.icon"></el-image>
</div>
<el-col :span="3">
<el-avatar shape="square" :size="180" :src="'data:image/png;base64,' + app.icon" />
</el-col>
<el-col :span="20">
<div class="a-detail">
<div class="a-name">
<span style="font-weight: 500; font-size: 18px">{{ app.name }}</span>
<div class="detail">
<div class="name">
<span>{{ app.name }}</span>
</div>
<div class="a-description">
<div class="description">
<span>
{{ app.shortDesc }}
</span>
</div>
<br />
<el-descriptions :column="1">
<el-descriptions-item :label="$t('app.version')">
<div class="version">
<el-form-item :label="$t('app.version')">
<el-select v-model="version" @change="getDetail(version)">
<el-option
v-for="(v, index) in app.versions"
@ -31,19 +28,9 @@
{{ v }}
</el-option>
</el-select>
</el-descriptions-item>
<el-descriptions-item :label="$t('app.source')">
<el-link @click="toLink(app.source)">
<el-icon><Link /></el-icon>
</el-link>
</el-descriptions-item>
<el-descriptions-item :label="$t('app.author')">{{ app.author }}</el-descriptions-item>
</el-descriptions>
<div>
<el-button v-if="appDetail.enable" @click="openInstall" type="primary">
{{ $t('app.install') }}
</el-button>
</el-form-item>
</div>
<br />
<div>
<el-alert
@ -55,12 +42,43 @@
:closable="false"
/>
</div>
<div>
<el-button round v-if="appDetail.enable" @click="openInstall" type="primary">
{{ $t('app.install') }}
</el-button>
</div>
</div>
</el-col>
</el-row>
<div class="divider"></div>
<el-row>
<el-col :span="12">
<div class="descriptions">
<el-descriptions direction="vertical">
<el-descriptions-item :label="$t('app.appWebsite')">
<el-link @click="toLink(app.website)">
<el-icon><OfficeBuilding /></el-icon>
<span>{{ $t('app.appOfficeWebsite') }}</span>
</el-link>
</el-descriptions-item>
<el-descriptions-item :label="$t('app.doc')">
<el-link @click="toLink(app.document)">
<el-icon><Document /></el-icon>
<span>{{ $t('app.document') }}</span>
</el-link>
</el-descriptions-item>
<el-descriptions-item label="Github">
<el-link @click="toLink(app.github)">
<el-icon><Link /></el-icon>
<span>{{ $t('app.github') }}</span>
</el-link>
</el-descriptions-item>
</el-descriptions>
</div>
</el-col>
</el-row>
</div>
<el-divider border-style="double" />
<div class="detail" v-loading="loadingDetail">
<div v-loading="loadingDetail">
<v-md-preview :text="appDetail.readme"></v-md-preview>
</div>
</template>
@ -125,11 +143,31 @@ onMounted(() => {
<style lang="scss">
.brief {
height: 30vh;
.icon {
.image {
width: auto;
height: 20vh;
.name {
span {
font-weight: 500;
font-size: 18px;
}
}
.description {
margin-top: 10px;
span {
font-size: 14px;
color: #646a73;
}
}
.version {
margin-top: 10px;
}
.descriptions {
margin-top: 5px;
}
}
.el-avatar {
--el-avatar-bg-color: #ffffff;
}
</style>

View File

@ -1,5 +1,11 @@
<template>
<el-drawer v-model="open" :title="$t('app.install')" size="50%" :before-close="handleClose" :show-close="false">
<el-drawer
:close-on-click-modal="false"
v-model="open"
:title="$t('app.install')"
size="50%"
:before-close="handleClose"
>
<template #header>
<Header :header="$t('app.install')" :back="handleClose" />
</template>

View File

@ -64,7 +64,7 @@
margin-left: 10px;
}
.divider {
.app-divider {
margin-top: 5px;
border: 0;
border-top: 1px solid #f2f2f2;

View File

@ -1,5 +1,11 @@
<template>
<el-drawer v-model="open" size="50%" :destroy-on-close="true" :before-close="handleClose" :show-close="false">
<el-drawer
:close-on-click-modal="false"
v-model="open"
size="50%"
:destroy-on-close="true"
:before-close="handleClose"
>
<template #header>
<Header :header="$t('app.backup')" :resource="installData.appInstallName" :back="handleClose"></Header>
</template>
@ -51,7 +57,6 @@
:close-on-click-modal="false"
:title="$t('commons.msg.operate')"
width="30%"
:show-close="false"
>
<el-alert :title="$t('app.restoreWarn')" type="warning" :closable="false" show-icon />
<template #footer>

View File

@ -1,5 +1,5 @@
<template>
<el-drawer v-model="open" size="40%" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="open" size="40%">
<template #header>
<Header :header="$t('app.param')" :back="handleClose"></Header>
</template>

View File

@ -1,5 +1,5 @@
<template>
<LayoutContent v-loading="loading" :title="activeName">
<LayoutContent v-loading="loading" :title="activeName" :divider="true">
<template #toolbar>
<el-row :gutter="5">
<el-col :span="20">
@ -39,7 +39,6 @@
<el-button @click="sync" type="primary" link v-if="mode === 'installed'">{{ $t('app.sync') }}</el-button>
</template>
<template #main>
<div class="divider"></div>
<el-row :gutter="5">
<el-col v-for="(installed, index) in data" :key="index" :span="12">
<div class="app-card">
@ -107,7 +106,7 @@
<span>{{ $t('app.areadyRun') }} {{ getAge(installed.createdAt) }}</span>
</div>
</div>
<div class="divider"></div>
<div class="app-divider" />
<div class="d-button" v-if="mode === 'installed'">
<el-button
v-for="(button, key) in buttons"

View File

@ -1,5 +1,5 @@
<template>
<el-drawer v-model="open" size="30%" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="open" size="30%">
<template #header>
<Header :header="$t('commons.msg.operate')" :resource="resourceName" :back="handleClose"></Header>
</template>

View File

@ -1,7 +1,7 @@
<template>
<el-dialog
v-model="open"
:title="$t('commons.button.create')"
:title="$t('website.addAccount')"
:destroy-on-close="true"
:close-on-click-modal="false"
width="30%"

View File

@ -1,11 +1,11 @@
<template>
<el-drawer v-model="open" :size="'50%'" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="open" :size="'50%'">
<template #header>
<DrawerHeader :header="$t('website.acmeAccountManage')" :back="handleClose" />
</template>
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()" v-loading="loading">
<template #toolbar>
<el-button type="primary" icon="Plus" @click="openCreate">{{ $t('commons.button.create') }}</el-button>
<el-button type="primary" @click="openCreate">{{ $t('website.addAccount') }}</el-button>
</template>
<el-table-column :label="$t('website.email')" fix show-overflow-tooltip prop="email"></el-table-column>
<el-table-column label="URL" show-overflow-tooltip prop="url"></el-table-column>

View File

@ -1,7 +1,7 @@
<template>
<el-drawer v-model="open" size="50%" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="open" size="50%">
<template #header>
<DrawerHeader :header="$t('commons.button.create')" :back="handleClose" />
<DrawerHeader :header="$t('ssl.create')" :back="handleClose" />
</template>
<el-row>
<el-col :span="22" :offset="1">

View File

@ -1,5 +1,5 @@
<template>
<el-drawer v-model="open" size="50%" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="open" size="50%">
<template #header>
<DrawerHeader :header="$t('ssl.detail')" :back="handleClose" />
</template>

View File

@ -1,7 +1,7 @@
<template>
<el-dialog
v-model="open"
:title="$t('website.createDnsAccount')"
:title="$t('website.addAccount')"
:destroy-on-close="true"
:close-on-click-modal="false"
width="40%"

View File

@ -1,12 +1,12 @@
<template>
<el-drawer v-model="open" :size="'50%'" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="open" :size="'50%'">
<template #header>
<DrawerHeader :header="$t('website.dnsAccountManage')" :back="handleClose" />
</template>
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()">
<template #toolbar>
<el-button type="primary" icon="Plus" @click="openCreate">
{{ $t('commons.button.create') }}
<el-button type="primary" @click="openCreate">
{{ $t('website.addAccount') }}
</el-button>
</template>
<el-table-column :label="$t('commons.table.name')" fix show-overflow-tooltip prop="name"></el-table-column>

View File

@ -9,8 +9,8 @@
</el-alert>
</template>
<template #toolbar>
<el-button type="primary" icon="Plus" @click="openSSL()">
{{ $t('commons.button.create') }}
<el-button type="primary" @click="openSSL()">
{{ $t('ssl.create') }}
</el-button>
<el-button type="primary" plain @click="openAcmeAccount()">
{{ $t('website.acmeAccountManage') }}

View File

@ -1,7 +1,7 @@
<template>
<el-drawer v-model="backupVisiable" size="50%" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="backupVisiable" size="50%">
<template #header>
<Header :header="$t('database.backup')" :resource="websiteName" :back="handleClose"></Header>
<DrawerHeader :header="$t('database.backup')" :resource="websiteName" :back="handleClose"></DrawerHeader>
</template>
<ComplexTable
v-loading="loading"
@ -42,7 +42,6 @@ import { ElMessage } from 'element-plus';
import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords } from '@/api/modules/backup';
import { Backup } from '@/api/interface/backup';
import { BackupWebsite, RecoverWebsite } from '@/api/modules/website';
import Header from '@/components/drawer-header/index.vue';
const selects = ref<any>([]);
const loading = ref(false);

View File

@ -1,5 +1,5 @@
<template>
<el-drawer v-model="open" size="50%" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="open" size="50%">
<template #header>
<DrawerHeader :header="$t('website.create')" :back="handleClose">
<template #buttons>

View File

@ -1,11 +1,8 @@
<template>
<el-dialog
v-model="open"
:title="$t('website.defaulServer')"
width="35%"
@close="handleClose"
:close-on-click-modal="false"
>
<el-drawer :close-on-click-modal="false" v-model="open" size="30%">
<template #header>
<DrawerHeader :header="$t('website.defaulServer')" :back="handleClose"></DrawerHeader>
</template>
<el-row>
<el-col :span="22" :offset="1">
<el-form label-position="top">
@ -37,7 +34,7 @@
</el-button>
</span>
</template>
</el-dialog>
</el-drawer>
</template>
<script lang="ts" setup>
import { Website } from '@/api/interface/Website';

View File

@ -1,12 +1,12 @@
<template>
<el-drawer v-model="open" size="50%" :show-close="false" :before-close="handleClose">
<el-drawer :close-on-click-modal="false" v-model="open" size="50%" :before-close="handleClose">
<template #header>
<Header :header="$t('website.groupSetting')" :back="handleClose"></Header>
<Header :header="$t('website.group')" :back="handleClose"></Header>
</template>
<ComplexTable :data="data" @search="search()">
<template #toolbar>
<el-button type="primary" icon="Plus" @click="openCreate">{{ $t('commons.button.create') }}</el-button>
<el-button type="primary" @click="openCreate">{{ $t('website.createGroup') }}</el-button>
</template>
<el-table-column :label="$t('commons.table.name')" prop="name">
<template #default="{ row }">

View File

@ -1,4 +1,13 @@
<template>
<RouterButton
:buttons="[
{
label: i18n.global.t('website.website'),
path: '/websites',
},
]"
/>
<br />
<LayoutContent :title="$t('website.website')" v-loading="loading">
<template #app>
<AppStatus
@ -11,8 +20,8 @@
<template v-if="nginxIsExist && !openNginxConfig" #toolbar>
<el-row :class="{ mask: nginxStatus != 'Running' }">
<el-col :span="20">
<el-button type="primary" icon="Plus" @click="openCreate">
{{ $t('commons.button.create') }}
<el-button type="primary" @click="openCreate">
{{ $t('website.create') }}
</el-button>
<el-button type="primary" plain @click="openGroup">
{{ $t('website.group') }}

View File

@ -1,5 +1,5 @@
<template>
<el-drawer v-model="upVisiable" size="50%" :show-close="false">
<el-drawer :close-on-click-modal="false" v-model="upVisiable" size="50%">
<template #header>
<Header :header="$t('commons.button.import')" :resource="websiteName" :back="handleClose"></Header>
</template>