Skip to content

Commit

Permalink
Merge pull request #7579 from jutoft/bugfix/update-docker-deps
Browse files Browse the repository at this point in the history
Update Dockerfile to use Python base image and add input args
  • Loading branch information
xoriole authored Feb 13, 2024
2 parents c43a2dc + eae4a3b commit 697422c
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 36 deletions.
53 changes: 34 additions & 19 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,29 +1,44 @@
# The base image already builds the libtorrent dependency so only Python pip packages
# are necessary to be installed to run Tribler core process.
FROM triblercore/libtorrent:1.2.10-x
# libtorrent-1.2.19 does not support python 3.11 yet
FROM python:3.10-slim

# Update the base system and install required libsodium and Python pip
RUN apt update && apt upgrade -y
RUN apt install -y libsodium23 python3-pip git

RUN useradd -ms /bin/bash user
USER user
WORKDIR /home/user
RUN apt-get update \
&& apt-get install -y --no-install-recommends libsodium23=1.0.18-1 \
&& rm -rf /var/lib/apt/lists/*

# Then, install pip dependencies so that it can be cached and does not
# need to be built every time the source code changes.
# This reduces the docker build time.
RUN mkdir requirements
COPY ./requirements-core.txt requirements/core-requirements.txt
RUN pip3 install -r requirements/core-requirements.txt
COPY ./requirements-core.txt /app/tribler/core-requirements.txt
RUN pip3 install -r /app/tribler/core-requirements.txt

RUN useradd -ms /bin/bash user

# Create default state and download directories and set the permissions
RUN chown -R user:user /app
RUN mkdir /state /downloads && chown -R user:user /state /downloads

# Copy the source code and set the working directory
COPY ./ tribler
WORKDIR /home/user/tribler
COPY ./src /app/tribler/src/
WORKDIR /app/tribler/

# Set the REST API port and expose it
# Set to -1 to use the default
ENV CORE_API_PORT=20100
EXPOSE 20100
ENV IPV8_PORT=7759
ENV TORRENT_PORT=-1
ENV DOWNLOAD_DIR=/downloads
ENV TSTATEDIR=/state
ENV HTTP_HOST=127.0.0.1
ENV HTTPS_HOST=127.0.0.1

VOLUME /state
VOLUME /downloads

USER user

# Only run the core process with --core switch
CMD ["./src/tribler.sh", "--core"]
CMD exec python3 /app/tribler/src/run_tribler_headless.py \
--ipv8=${IPV8_PORT} \
--libtorrent=${TORRENT_PORT} \
--restapi_http_host=${HTTP_HOST} \
--restapi_https_host=${HTTPS_HOST} \
"--statedir=${TSTATEDIR}" \
"--download_dir=${DOWNLOAD_DIR}"
7 changes: 7 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ To run the built docker image:
Note that by default, the REST API is bound to localhost inside the container so to
access the APIs, network needs to be set to host (--net="host").

To use the local state directory and downloads directory, the volumes can be mounted:

.. code-block:: bash
docker run -p 20100:20100 --net="host" -v ~/.Tribler:/state -v ~/downloads/TriblerDownloads:/downloads triblercore/triblercore:latest
The REST APIs are now accessible at: http://localhost:20100/docs


Expand Down
13 changes: 9 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ services:
tribler-core:
image: triblercore/triblercore:latest
container_name: triblercore
network_mode: "host"
build: .
volumes:
- ~/.Tribler:/home/user/.Tribler
- "~/.Tribler:/state"
- "~/Downloads/TriblerDownloads:/downloads"
ports:
- "20100:20100"
environment:
CORE_API_PORT: 20100

- CORE_API_PORT=20100
- CORE_API_KEY=TEST
- TORRENT_PORT=7000
- TSTATEDIR=/state
- HTTP_HOST=0.0.0.0
49 changes: 42 additions & 7 deletions src/run_tribler_headless.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from tribler.core.components.session import Session
from tribler.core.config.tribler_config import TriblerConfig
from tribler.core.start_core import components_gen
from tribler.core.upgrade.version_manager import VersionHistory
from tribler.core.utilities.exit_codes.tribler_exit_codes import EXITCODE_ANOTHER_CORE_PROCESS_IS_RUNNING
from tribler.core.utilities.osutils import get_appstate_dir, get_root_state_directory
from tribler.core.utilities.path_util import Path
Expand Down Expand Up @@ -78,11 +79,13 @@ async def signal_handler(sig):
signal.signal(signal.SIGINT, lambda sig, _: ensure_future(signal_handler(sig)))
signal.signal(signal.SIGTERM, lambda sig, _: ensure_future(signal_handler(sig)))

statedir = Path(options.statedir or Path(get_appstate_dir(), '.Tribler'))
config = TriblerConfig.load(state_dir=statedir)
if options.statedir:
os.environ['TSTATEDIR'] = options.statedir

# Check if we are already running a Tribler instance
root_state_dir = get_root_state_directory(create=True)
version_history = VersionHistory(root_state_dir)
statedir = version_history.code_version.directory
config = TriblerConfig.load(state_dir=statedir)

self.process_lock = try_acquire_file_lock(root_state_dir / CORE_LOCK_FILENAME)
current_process_owns_lock = bool(self.process_lock)
Expand All @@ -96,9 +99,30 @@ async def signal_handler(sig):

print("Starting Tribler")

if options.restapi > 0:
http_port = options.restapi_http_port or int(os.environ.get('CORE_API_PORT', "0"))

if 'CORE_API_PORT' in os.environ and (http_port := int(os.environ.get('CORE_API_PORT'))) > 0:
config.api.http_port = http_port
elif options.restapi_http_port > 0:
config.api.http_port = options.restapi_http_port

if options.restapi_http_host:
config.api.http_host = options.restapi_http_host

if options.restapi_https_port > 0:
config.api.https_port = options.restapi_https_port

if options.restapi_https_host:
config.api.https_host = options.restapi_https_host

if config.api.http_port > 0:
config.api.http_enabled = True
config.api.http_port = options.restapi

if config.api.https_port > 0:
config.api.https_enabled = True

if api_key := os.environ.get('CORE_API_KEY'):
config.api.key = api_key

if options.ipv8 > 0:
config.ipv8.port = options.ipv8
Expand All @@ -108,6 +132,9 @@ async def signal_handler(sig):
if options.libtorrent != -1 and options.libtorrent > 0:
config.libtorrent.port = options.libtorrent

if options.download_dir:
config.download_defaults.saveas = options.download_dir

if options.ipv8_bootstrap_override is not None:
config.ipv8.bootstrap_override = options.ipv8_bootstrap_override

Expand Down Expand Up @@ -135,7 +162,15 @@ def main(argv):
parser.add_argument('--help', '-h', action='help', default=argparse.SUPPRESS,
help='Show this help message and exit')
parser.add_argument('--statedir', '-s', default=None, help='Use an alternate statedir')
parser.add_argument('--restapi', '-p', default=-1, type=int, help='Use an alternate port for REST API')
parser.add_argument('--download_dir', default=None, help='Use an alternative download directory')
parser.add_argument('--restapi_http_port', '--restapi', '-p', default=-1, type=int,
help='Use an alternate port for http REST API')
parser.add_argument('--restapi_http_host', default=None, type=str,
help='Use an alternate listen address for http REST API')
parser.add_argument('--restapi_https_port', default=-1, type=int,
help='Use an alternate port for https REST API')
parser.add_argument('--restapi_https_host', default=None, type=str,
help='Use an alternate listen address for https REST API')
parser.add_argument('--ipv8', '-i', default=-1, type=int, help='Use an alternate port for the IPv8')
parser.add_argument('--libtorrent', '-l', default=-1, type=int, help='Use an alternate port for libtorrent')
parser.add_argument('--ipv8_bootstrap_override', '-b', default=None, type=str,
Expand All @@ -152,7 +187,7 @@ def main(argv):
coro = service.start_tribler(args)
ensure_future(coro)

if sys.platform == 'win32':
if sys.platform == 'win32' and sys.version_info < (3, 8):
# Unfortunately, this is needed on Windows for Ctrl+C to work consistently.
# Should no longer be needed in Python 3.8.
async def wakeup():
Expand Down
10 changes: 4 additions & 6 deletions src/tribler/core/components/restapi/rest/rest_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ def __init__(self, config: APISettings, root_endpoint: RootEndpoint, state_dir=N
self.config = config
self.state_dir = state_dir

self.http_host = '127.0.0.1'
self.https_host = '0.0.0.0'
self.shutdown_timeout = shutdown_timeout

def get_endpoint(self, name):
Expand Down Expand Up @@ -146,13 +144,13 @@ async def start(self):
self._logger.info('Https enabled')
await self.start_https_site()

self._logger.info(f'Swagger docs: http://{self.http_host}:{self.config.http_port}/docs')
self._logger.info(f'Swagger JSON: http://{self.http_host}:{self.config.http_port}/docs/swagger.json')
self._logger.info(f'Swagger docs: http://{self.config.http_host}:{self.config.http_port}/docs')
self._logger.info(f'Swagger JSON: http://{self.config.http_host}:{self.config.http_port}/docs/swagger.json')

async def start_http_site(self):
api_port = max(self.config.http_port, 0) # if the value in config is -1 we convert it to 0

self.site = web.TCPSite(self.runner, self.http_host, api_port, shutdown_timeout=self.shutdown_timeout)
self.site = web.TCPSite(self.runner, self.config.http_host, api_port, shutdown_timeout=self.shutdown_timeout)
self._logger.info(f"Starting HTTP REST API server on port {api_port}...")

try:
Expand All @@ -174,7 +172,7 @@ async def start_https_site(self):
ssl_context.load_cert_chain(cert)

port = self.config.https_port
self.site_https = web.TCPSite(self.runner, self.https_host, port, ssl_context=ssl_context)
self.site_https = web.TCPSite(self.runner, self.config.https_host, port, ssl_context=ssl_context)

await self.site_https.start()
self._logger.info("Started HTTPS REST API: %s", self.site_https.name)
Expand Down
2 changes: 2 additions & 0 deletions src/tribler/core/components/restapi/rest/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
class APISettings(TriblerConfigSection):
http_enabled: bool = False
http_port: int = -1
http_host: str = "127.0.0.1"
https_enabled: bool = False
https_host: str = "127.0.0.1"
https_port: int = -1
https_certfile: str = ''
key: Optional[str] = None
Expand Down

0 comments on commit 697422c

Please sign in to comment.